You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
2.6 KiB
108 lines
2.6 KiB
#!/usr/bin/env python3
|
|
|
|
import sys, math
|
|
from itertools import permutations, product
|
|
|
|
# +---+---+
|
|
# | ^ | A |
|
|
# +---+---+---+
|
|
# | < | v | > |
|
|
# +---+---+---+
|
|
DIR = {
|
|
'A': (0,2),
|
|
'^': (0,1),
|
|
'<': (-1,0),
|
|
'v': (-1,1),
|
|
'>': (-1,2),
|
|
}
|
|
|
|
# +---+---+---+
|
|
# | 7 | 8 | 9 |
|
|
# +---+---+---+
|
|
# | 4 | 5 | 6 |
|
|
# +---+---+---+
|
|
# | 1 | 2 | 3 |
|
|
# +---+---+---+
|
|
# | 0 | A |
|
|
# +---+---+
|
|
NUM = {
|
|
# ('A', '0'): ['<'],
|
|
# ('A', '1'): ['<^<', '^<<'],
|
|
# ('A', '2'): ['<^', '^<'],
|
|
# ('A', '3'): ['^'],
|
|
# ('A', '4'): ['<^<^', '^<<^', '^^<<', '<^^<'],
|
|
# ('A', '5'): ['<^^', '^<^', '^^<'],
|
|
# ('A', '6'): ['^^'],
|
|
# ('A', '7'): ['^^^<<', '^^<<^', '^<<^^', '^<^<^', '^<^^<'],
|
|
# ('A', '8'): ['<^^', '^<^', '^^<'],
|
|
# ('A', '9'): ['^^^',],
|
|
'A': (0,2),
|
|
'0': (0,1),
|
|
'1': (1,0),
|
|
'2': (1,1),
|
|
'3': (1,2),
|
|
'4': (2,0),
|
|
'5': (2,1),
|
|
'6': (2,2),
|
|
'7': (3,0),
|
|
'8': (3,1),
|
|
'9': (3,2),
|
|
}
|
|
|
|
|
|
def options(start,end, pad):
|
|
s, e = pad[start], pad[end]
|
|
d = {'^': (1,0), 'v': (-1,0), '>': (0,1), '<': (0,-1)}
|
|
dy = e[0]-s[0]
|
|
dx = e[1]-s[1]
|
|
opt = ['^'] * dy + ['v'] * -dy + ['<'] * -dx + ['>'] * dx
|
|
for o in set(permutations(opt)):
|
|
s, e = pad[start], pad[end]
|
|
gap = False
|
|
for step in list(o):
|
|
s = s[0] + d[step][0], s[1] + d[step][1]
|
|
if s == (0,0): gap = True
|
|
if not gap: yield ''.join(o+('A',))
|
|
|
|
|
|
def directional(code):
|
|
strings = ['']
|
|
prev = 'A'
|
|
for key in list(code):
|
|
strings = [s1+s2 for (s1,s2) in product(strings,[opt for opt in options(prev, key, DIR)])]
|
|
prev = key
|
|
return strings
|
|
|
|
|
|
def numeric(code):
|
|
strings = ['']
|
|
prev = 'A'
|
|
for key in list(code):
|
|
strings = [s1+s2 for (s1,s2) in product(strings,[opt for opt in options(prev, key, NUM)])]
|
|
prev = key
|
|
return strings
|
|
|
|
|
|
if __name__ == '__main__':
|
|
codes = [line.strip('\n') for line in open(sys.argv[1])]
|
|
res1 = 0
|
|
for code in codes:
|
|
length = math.inf
|
|
opts = []
|
|
for dirs in sorted(numeric(code),key=len):
|
|
for dirs1 in set(directional(dirs)):
|
|
for dirs2 in set(directional(dirs1)):
|
|
if len(dirs2) <= length:
|
|
opts.append(dirs2)
|
|
length = len(dirs2)
|
|
else: break
|
|
|
|
res1 += length * int(code[:-1])
|
|
|
|
# challenge 1
|
|
print(f"challenge 1:\n{res1}\n")
|
|
|
|
# challenge 2
|
|
res2 = ""
|
|
print(f"challenge 2:\n{res2}")
|
|
|
|
|