Initial commit
This commit is contained in:
commit
97a4330bc0
110 changed files with 7006 additions and 0 deletions
BIN
2024/21/Notes.xopp
Normal file
BIN
2024/21/Notes.xopp
Normal file
Binary file not shown.
BIN
2024/21/Spreadsheet.ods
Normal file
BIN
2024/21/Spreadsheet.ods
Normal file
Binary file not shown.
1
2024/21/demog
Normal file
1
2024/21/demog
Normal file
|
@ -0,0 +1 @@
|
|||
3A
|
98
2024/21/one.py
Normal file
98
2024/21/one.py
Normal file
|
@ -0,0 +1,98 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
|
||||
input_file = sys.argv[1]
|
||||
|
||||
with open(input_file) as fd:
|
||||
lines = [line.rstrip() for line in fd.readlines()]
|
||||
|
||||
numeric_keypad = ["789", "456", "123", " 0A"]
|
||||
directional_keypad = [" ^A", "<v>"]
|
||||
|
||||
vec = tuple[int, int]
|
||||
directions = {
|
||||
"^": (-1, 0), # ^ North
|
||||
">": (0, 1), # > East
|
||||
"v": (1, 0), # v South
|
||||
"<": (0, -1), # < West
|
||||
}
|
||||
directional_keypad_buttons = tuple(directions.keys()) + ("A",)
|
||||
|
||||
complexity = int(sys.argv[2])
|
||||
keypads = [directional_keypad] * complexity + [numeric_keypad]
|
||||
|
||||
|
||||
def but_pos(but: str, keypad: list[str]) -> vec:
|
||||
for i, line in enumerate(keypad):
|
||||
if but in line:
|
||||
return i, line.index(but)
|
||||
raise IndexError("No such button")
|
||||
|
||||
|
||||
def in_bounds(i: int, j: int, keypad: list[str]) -> bool:
|
||||
if j not in range(3) or i not in range(len(keypad)):
|
||||
return False
|
||||
return keypad[i][j] != " "
|
||||
|
||||
last_but = "A"
|
||||
all_a = [but_pos("A", keypad) for keypad in keypads]
|
||||
|
||||
score = 0
|
||||
for code in lines:
|
||||
print("Code", code)
|
||||
topresses = 0
|
||||
for desir_but in code:
|
||||
print("Button", desir_but)
|
||||
all_a[-1] = but_pos(last_but, keypads[-1])
|
||||
start_poss = tuple(all_a)
|
||||
all_a[-1] = but_pos(desir_but, keypads[-1])
|
||||
desir_poss = tuple(all_a)
|
||||
|
||||
stack = {start_poss}
|
||||
seen = set()
|
||||
presses = 0
|
||||
while desir_poss not in stack:
|
||||
# print("Press", presses, stack)
|
||||
presses += 1
|
||||
nstack = set()
|
||||
for poss in stack:
|
||||
for but in directional_keypad_buttons:
|
||||
# Find which keypad this will move
|
||||
k = 0
|
||||
while but == "A" and k < len(keypads) - 1:
|
||||
i, j = poss[k]
|
||||
but = keypads[k][i][j]
|
||||
k += 1
|
||||
|
||||
# Do not press the final keypad
|
||||
if k == len(keypads) - 1 and but == "A":
|
||||
continue
|
||||
|
||||
# Move
|
||||
direction = directions[but]
|
||||
i, j = poss[k]
|
||||
ii, jj = i + direction[0], j + direction[1]
|
||||
if not in_bounds(ii, jj, keypads[k]):
|
||||
continue
|
||||
|
||||
# Ensure we haven't been in this state before
|
||||
state = poss[:k] + ((ii, jj),) + poss[k + 1 :]
|
||||
if state in seen:
|
||||
continue
|
||||
seen.add(state)
|
||||
|
||||
# print(" Kept", state)
|
||||
nstack.add(state)
|
||||
|
||||
stack = nstack
|
||||
topresses += presses + 1
|
||||
last_but = desir_but
|
||||
|
||||
numpart = int("0" + code.replace("A", ""))
|
||||
print(f"{topresses=} * {numpart=}")
|
||||
score += topresses * numpart
|
||||
|
||||
|
||||
|
||||
print(score)
|
97
2024/21/onet.py
Normal file
97
2024/21/onet.py
Normal file
|
@ -0,0 +1,97 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
|
||||
input_file = sys.argv[1]
|
||||
|
||||
with open(input_file) as fd:
|
||||
lines = [line.rstrip() for line in fd.readlines()]
|
||||
|
||||
numeric_keypad = ["789", "456", "123", " 0A"]
|
||||
directional_keypad = [" ^A", "<v>"]
|
||||
|
||||
vec = tuple[int, int]
|
||||
directions = {
|
||||
"^": (-1, 0), # ^ North
|
||||
">": (0, 1), # > East
|
||||
"v": (1, 0), # v South
|
||||
"<": (0, -1), # < West
|
||||
}
|
||||
directional_keypad_buttons = tuple(directions.keys()) + ("A",)
|
||||
|
||||
complexity = int(sys.argv[2])
|
||||
keypads = [directional_keypad] * complexity + [numeric_keypad]
|
||||
|
||||
|
||||
def but_pos(but: str, keypad: list[str]) -> vec:
|
||||
for i, line in enumerate(keypad):
|
||||
if but in line:
|
||||
return i, line.index(but)
|
||||
raise IndexError("No such button")
|
||||
|
||||
|
||||
def in_bounds(i: int, j: int, keypad: list[str]) -> bool:
|
||||
if j not in range(3) or i not in range(len(keypad)):
|
||||
return False
|
||||
return keypad[i][j] != " "
|
||||
|
||||
last_but = "A"
|
||||
all_a = [but_pos("A", keypad) for keypad in keypads]
|
||||
|
||||
score = 0
|
||||
for code in lines:
|
||||
# print("Code", code)
|
||||
topresses = 0
|
||||
for desir_but in code:
|
||||
# print("Button", desir_but)
|
||||
all_a[-1] = but_pos(last_but, keypads[-1])
|
||||
start_poss = tuple(all_a)
|
||||
all_a[-1] = but_pos(desir_but, keypads[-1])
|
||||
if len(keypads) > 1:
|
||||
all_a[-2] = but_pos("^", keypads[-2])
|
||||
desir_poss = tuple(all_a)
|
||||
|
||||
stack = {start_poss}
|
||||
seen = set()
|
||||
presses = 0
|
||||
while desir_poss not in stack:
|
||||
# print("Press", presses, stack)
|
||||
presses += 1
|
||||
nstack = set()
|
||||
for poss in stack:
|
||||
for but in directional_keypad_buttons:
|
||||
# Find which keypad this will move
|
||||
k = 0
|
||||
while but == "A" and k < len(keypads) - 1:
|
||||
i, j = poss[k]
|
||||
but = keypads[k][i][j]
|
||||
k += 1
|
||||
|
||||
# Do not press the final keypad
|
||||
if k == len(keypads) - 1 and but == "A":
|
||||
continue
|
||||
|
||||
# Move
|
||||
direction = directions[but]
|
||||
i, j = poss[k]
|
||||
ii, jj = i + direction[0], j + direction[1]
|
||||
if not in_bounds(ii, jj, keypads[k]):
|
||||
continue
|
||||
|
||||
# Ensure we haven't been in this state before
|
||||
state = poss[:k] + ((ii, jj),) + poss[k + 1 :]
|
||||
if state in seen:
|
||||
continue
|
||||
seen.add(state)
|
||||
|
||||
# print(" Kept", state)
|
||||
nstack.add(state)
|
||||
|
||||
stack = nstack
|
||||
topresses += presses + 0
|
||||
last_but = desir_but
|
||||
|
||||
score += topresses
|
||||
|
||||
print(score)
|
||||
|
281
2024/21/two.py
Normal file
281
2024/21/two.py
Normal file
|
@ -0,0 +1,281 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import typing
|
||||
import functools
|
||||
|
||||
input_file = sys.argv[1]
|
||||
|
||||
with open(input_file) as fd:
|
||||
lines = [line.rstrip() for line in fd.readlines()]
|
||||
|
||||
numeric_keypad = ["789", "456", "123", " 0A"]
|
||||
directional_keypad = [" ^A", "<v>"]
|
||||
|
||||
vec = tuple[int, int]
|
||||
directions = {
|
||||
"^": (-1, 0), # ^ North
|
||||
">": (0, 1), # > East
|
||||
"v": (1, 0), # v South
|
||||
"<": (0, -1), # < West
|
||||
}
|
||||
directional_keypad_buttons = tuple(directions.keys()) + ("A",)
|
||||
|
||||
complexity = int(sys.argv[2])
|
||||
keypads = [numeric_keypad] + ([directional_keypad] * complexity)
|
||||
|
||||
|
||||
def but_pos(but: str, keypad: list[str]) -> vec:
|
||||
for i, line in enumerate(keypad):
|
||||
if but in line:
|
||||
return i, line.index(but)
|
||||
raise IndexError(f"No such button: {but} in {keypad}")
|
||||
|
||||
|
||||
def in_bounds(i: int, j: int, keypad: list[str]) -> bool:
|
||||
if j not in range(3) or i not in range(len(keypad)):
|
||||
return False
|
||||
return keypad[i][j] != " "
|
||||
|
||||
|
||||
# FIFTH TRY
|
||||
# Using 2 as a base
|
||||
|
||||
|
||||
@functools.cache
|
||||
def press(buts: str, depth: int) -> int:
|
||||
if depth == len(keypads):
|
||||
return len(buts)
|
||||
keypad = keypads[depth]
|
||||
i, j = but_pos("A", keypad)
|
||||
nums = 0
|
||||
for but in buts:
|
||||
nnbuts = ""
|
||||
ni, nj = but_pos(but, keypad)
|
||||
bounded = True
|
||||
while nj < j:
|
||||
nnbuts += "<"
|
||||
j -= 1
|
||||
bounded &= in_bounds(i, j, keypad)
|
||||
while ni > i:
|
||||
nnbuts += "v"
|
||||
i += 1
|
||||
bounded &= in_bounds(i, j, keypad)
|
||||
while ni < i:
|
||||
nnbuts += "^"
|
||||
i -= 1
|
||||
bounded &= in_bounds(i, j, keypad)
|
||||
while nj > j:
|
||||
nnbuts += ">"
|
||||
j += 1
|
||||
bounded &= in_bounds(i, j, keypad)
|
||||
if not bounded:
|
||||
nnbuts = nnbuts[::-1]
|
||||
nnbuts += "A"
|
||||
nums += press(nnbuts, depth + 1)
|
||||
return nums
|
||||
|
||||
|
||||
score = 0
|
||||
for code in lines:
|
||||
print("Code", code)
|
||||
topresses = press(code, 0)
|
||||
|
||||
numpart = int("0" + code.replace("A", ""))
|
||||
print(f"{topresses=} * {numpart=}")
|
||||
score += topresses * numpart
|
||||
|
||||
print(score)
|
||||
|
||||
|
||||
# FOURTH TRY
|
||||
|
||||
|
||||
# def press4(buts: str) -> int:
|
||||
# poss = [list(but_pos("A")) for keypad in keypads]
|
||||
# indexes = [0 for _ in keypads]
|
||||
# combis = ["" for _ in keypads]
|
||||
# combis[0] = buts
|
||||
# while indexes[0] != len(buts):
|
||||
# for k in len(keypads):
|
||||
# pass
|
||||
# return 0
|
||||
#
|
||||
#
|
||||
# score = 0
|
||||
# for code in lines:
|
||||
# print("Code", code)
|
||||
#
|
||||
# topresses = press4(code)
|
||||
#
|
||||
# numpart = int("0" + code.replace("A", ""))
|
||||
# print(f"{topresses=} * {numpart=}")
|
||||
# score += topresses * numpart
|
||||
#
|
||||
# print(score)
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
# THIRD TRY
|
||||
|
||||
|
||||
def press3(buts: str, depth: int) -> typing.Generator[str, None, None]:
|
||||
if depth >= len(keypads):
|
||||
yield from buts
|
||||
return
|
||||
|
||||
keypad = keypads[::-1][depth]
|
||||
but_poss: dict[str, vec] = dict()
|
||||
for i, line in enumerate(keypad):
|
||||
for j, but in enumerate(line):
|
||||
but_poss[but] = i, j
|
||||
i, j = but_poss["A"]
|
||||
ai, ij = but_poss[" "]
|
||||
|
||||
for but in press3(buts, depth + 1):
|
||||
nnbuts = ""
|
||||
ni, nj = but_poss[but]
|
||||
bounded = True
|
||||
if nj < j:
|
||||
nnbuts += "<" * (j - nj)
|
||||
j = nj
|
||||
bounded &= (ai, ij) != (i, j)
|
||||
if ni > i:
|
||||
nnbuts += "v" * (ni - i)
|
||||
i = ni
|
||||
bounded &= (ai, ij) != (i, j)
|
||||
if ni < i:
|
||||
nnbuts += "^" * (i - ni)
|
||||
i = ni
|
||||
bounded &= (ai, ij) != (i, j)
|
||||
if nj > j:
|
||||
nnbuts += ">" * (nj - j)
|
||||
j = nj
|
||||
if not bounded:
|
||||
nnbuts = nnbuts[::-1]
|
||||
nnbuts += "A"
|
||||
yield from nnbuts
|
||||
|
||||
|
||||
score = 0
|
||||
for code in lines:
|
||||
print("Code", code)
|
||||
|
||||
topresses = 0
|
||||
for _ in press3(code, 0):
|
||||
topresses += 1
|
||||
|
||||
numpart = int("0" + code.replace("A", ""))
|
||||
print(f"{topresses=} * {numpart=}")
|
||||
score += topresses * numpart
|
||||
|
||||
print(score)
|
||||
|
||||
# SECOND TRY
|
||||
|
||||
# # Shouldn't move over the bounds, repeat movements when possible, also use movements
|
||||
# # that start further to A then closer to A, because we're going to press A after anyways
|
||||
# moves = {
|
||||
# "AA": "",
|
||||
# "A^": "<",
|
||||
# "A>": "v",
|
||||
# "Av": "<v", # sort
|
||||
# "A<": "v<<", # hole avoid
|
||||
# "^A": ">",
|
||||
# "^^": "",
|
||||
# "^>": "v>", # sort
|
||||
# "^v": "v",
|
||||
# "^<": "v<", # hole avoid
|
||||
# ">A": "^",
|
||||
# ">^": "<^", # sort
|
||||
# ">>": "",
|
||||
# ">v": "<",
|
||||
# "><": "<<",
|
||||
# "vA": "^>", # symetric. but lower layer sort!
|
||||
# "v^": "^",
|
||||
# "v>": ">",
|
||||
# "vv": "",
|
||||
# "v<": "<",
|
||||
# "<A": ">>^", # hole avoid
|
||||
# "<^": ">^", # hole avoid
|
||||
# "<>": ">>",
|
||||
# "<v": ">",
|
||||
# "<<": "",
|
||||
# }
|
||||
#
|
||||
#
|
||||
# def press(buts: str, depth: int) -> str:
|
||||
# if depth == len(keypads):
|
||||
# return buts
|
||||
# keypad = keypads[depth]
|
||||
# numerical = keypad == numeric_keypad
|
||||
# prev_but = "A"
|
||||
# i, j = but_pos(prev_but, keypad)
|
||||
# nbuts = ""
|
||||
# for but in buts:
|
||||
# if numerical:
|
||||
# nnbuts = ""
|
||||
# ni, nj = but_pos(but, keypad)
|
||||
# # right before down
|
||||
# # up before left
|
||||
# bounded = True
|
||||
# while nj < j:
|
||||
# nnbuts += "<"
|
||||
# j -= 1
|
||||
# bounded &= in_bounds(i, j, keypad)
|
||||
# while ni > i:
|
||||
# nnbuts += "v"
|
||||
# i += 1
|
||||
# bounded &= in_bounds(i, j, keypad)
|
||||
# while ni < i:
|
||||
# nnbuts += "^"
|
||||
# i -= 1
|
||||
# bounded &= in_bounds(i, j, keypad)
|
||||
# while nj > j:
|
||||
# nnbuts += ">"
|
||||
# j += 1
|
||||
# bounded &= in_bounds(i, j, keypad)
|
||||
# if not bounded:
|
||||
# nnbuts = nnbuts[::-1]
|
||||
# nbuts += nnbuts
|
||||
# else:
|
||||
# move = prev_but + but
|
||||
# nbuts += moves[move]
|
||||
# nbuts += "A"
|
||||
# prev_but = but
|
||||
# return press(nbuts, depth + 1)
|
||||
#
|
||||
#
|
||||
# score = 0
|
||||
# for code in lines:
|
||||
# print("Code", code)
|
||||
# presses = press(code, 0)
|
||||
# print(f"{presses=}")
|
||||
# topresses = len(presses)
|
||||
#
|
||||
# numpart = int("0" + code.replace("A", ""))
|
||||
# print(f"{topresses=} * {numpart=}")
|
||||
# score += topresses * numpart
|
||||
#
|
||||
# print(score)
|
||||
|
||||
# FIRST TRY
|
||||
|
||||
# keys = {
|
||||
# "A": "A",
|
||||
# "^": "<A" + ">",
|
||||
# ">": "VA" + "^",
|
||||
# "V": "V<A" + ">^",
|
||||
# "<": "V<<A" + ">>^",
|
||||
# }
|
||||
#
|
||||
# def press(but: str, depth: int) -> str:
|
||||
# if depth <= 0:
|
||||
# return but
|
||||
# depth -= 1
|
||||
# return "".join(press(b, depth) for b in keys[but])
|
||||
#
|
||||
#
|
||||
# res = press("^", complexity)
|
||||
# # res += press("A", complexity)
|
||||
# print(len(res), res)
|
64
2024/21/two_fast.py
Normal file
64
2024/21/two_fast.py
Normal file
|
@ -0,0 +1,64 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import functools
|
||||
import sys
|
||||
|
||||
input_file = sys.argv[1]
|
||||
|
||||
with open(input_file) as fd:
|
||||
lines = [line.rstrip() for line in fd.readlines()]
|
||||
|
||||
numeric_keypad = ["789", "456", "123", " 0A"]
|
||||
directional_keypad = [" ^A", "<v>"]
|
||||
|
||||
vec = tuple[int, int]
|
||||
|
||||
complexity = int(sys.argv[2])
|
||||
keypads = [numeric_keypad] + ([directional_keypad] * complexity)
|
||||
|
||||
|
||||
@functools.cache
|
||||
def press(buts: str, depth: int) -> int:
|
||||
if depth == len(keypads):
|
||||
return len(buts)
|
||||
|
||||
keypad = keypads[depth]
|
||||
but_poss: dict[str, vec] = dict()
|
||||
for i, line in enumerate(keypad):
|
||||
for j, but in enumerate(line):
|
||||
but_poss[but] = i, j
|
||||
i, j = but_poss["A"]
|
||||
ai, aj = but_poss[" "]
|
||||
|
||||
depth += 1
|
||||
nums = 0
|
||||
for but in buts:
|
||||
nnbuts = ""
|
||||
ni, nj = but_poss[but]
|
||||
crossing_gap = ((i == ai) and (nj == aj)) or ((ni == ai) and (j == aj))
|
||||
if nj < j:
|
||||
nnbuts += "<" * (j - nj)
|
||||
if ni < i:
|
||||
nnbuts += "^" * (i - ni)
|
||||
elif ni > i:
|
||||
nnbuts += "v" * (ni - i)
|
||||
if nj > j:
|
||||
nnbuts += ">" * (nj - j)
|
||||
i, j = ni, nj
|
||||
if crossing_gap:
|
||||
nnbuts = nnbuts[::-1]
|
||||
nnbuts += "A"
|
||||
nums += press(nnbuts, depth)
|
||||
return nums
|
||||
|
||||
|
||||
score = 0
|
||||
for code in lines:
|
||||
print("Code", code)
|
||||
topresses = press(code, 0)
|
||||
|
||||
numpart = int("0" + code.replace("A", ""))
|
||||
print(f"{topresses=} * {numpart=}")
|
||||
score += topresses * numpart
|
||||
|
||||
print(score)
|
Loading…
Add table
Add a link
Reference in a new issue