Compare commits
12 Commits
cb4b8295e1
...
9e168db913
Author | SHA1 | Date | |
---|---|---|---|
9e168db913 | |||
98a4dffb3c | |||
540bbb9a9e | |||
91da124cf7 | |||
8c0cd8e300 | |||
a299c90401 | |||
77f02a8217 | |||
6960c73439 | |||
b7cfadf7b1 | |||
cef93e325f | |||
c4d168689f | |||
c46feecce9 |
1
day21/expr.py
Normal file
1
day21/expr.py
Normal file
File diff suppressed because one or more lines are too long
2037
day21/input
Normal file
2037
day21/input
Normal file
File diff suppressed because it is too large
Load Diff
2047
day21/part1.go
Normal file
2047
day21/part1.go
Normal file
File diff suppressed because it is too large
Load Diff
2054
day21/part2.go
Normal file
2054
day21/part2.go
Normal file
File diff suppressed because it is too large
Load Diff
26
day21/sat.py
Normal file
26
day21/sat.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import z3
|
||||||
|
|
||||||
|
x = z3.Int('x')
|
||||||
|
def mul(a,b): return a*b
|
||||||
|
def div(a,b):
|
||||||
|
quo = a / b
|
||||||
|
return z3.If(z3.Or(a % b == 0, a >= 0),
|
||||||
|
quo,
|
||||||
|
z3.If(b >= 0, quo + 1, quo - 1))
|
||||||
|
def add(a,b): return a+b
|
||||||
|
def sub(a,b): return a-b
|
||||||
|
def num(a): return z3.IntVal(a)
|
||||||
|
def eql(a,b): return a==b
|
||||||
|
|
||||||
|
z = eval(open("expr.py").read())
|
||||||
|
|
||||||
|
s = z3.Solver()
|
||||||
|
s.add(z)
|
||||||
|
print(s.check())
|
||||||
|
|
||||||
|
m = s.model()
|
||||||
|
print(m)
|
||||||
|
|
103
day21/sol.py
Normal file
103
day21/sol.py
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
import operator
|
||||||
|
|
||||||
|
lines = []
|
||||||
|
for line in open("input"):
|
||||||
|
lines.append(line.split())
|
||||||
|
|
||||||
|
|
||||||
|
unused = lines
|
||||||
|
scope = {}
|
||||||
|
while unused:
|
||||||
|
lines, unused = unused, []
|
||||||
|
for words in lines:
|
||||||
|
refs = [x for x in words[1:] if x.isalpha()]
|
||||||
|
if any(r not in scope for r in refs):
|
||||||
|
unused.append(words)
|
||||||
|
continue
|
||||||
|
dst = words[0].rstrip(':')
|
||||||
|
if len(words) == 2:
|
||||||
|
_, src = words
|
||||||
|
scope[dst] = int(src)
|
||||||
|
continue
|
||||||
|
_, x, op, y = words
|
||||||
|
scope[dst] = (op, scope[x], scope[y])
|
||||||
|
|
||||||
|
optab = {
|
||||||
|
'*': operator.mul,
|
||||||
|
'/': operator.floordiv,
|
||||||
|
'+': operator.add,
|
||||||
|
'-': operator.sub,
|
||||||
|
}
|
||||||
|
|
||||||
|
def eval(x):
|
||||||
|
if type(x) == int:
|
||||||
|
return x
|
||||||
|
op = x[0]
|
||||||
|
args = [eval(a) for a in x[1:]]
|
||||||
|
return optab[op](*args)
|
||||||
|
|
||||||
|
root = scope['root']
|
||||||
|
print(eval(root))
|
||||||
|
|
||||||
|
def solve(x):
|
||||||
|
_, left, right = x
|
||||||
|
|
||||||
|
humn = scope['humn']
|
||||||
|
path = set()
|
||||||
|
|
||||||
|
def find(x):
|
||||||
|
if x is humn:
|
||||||
|
path.add(x)
|
||||||
|
return True
|
||||||
|
if type(x) is tuple:
|
||||||
|
for a in x:
|
||||||
|
if find(a):
|
||||||
|
path.add(x)
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
return False
|
||||||
|
|
||||||
|
x, y = left, right
|
||||||
|
if not find(x):
|
||||||
|
find(y)
|
||||||
|
x, y = y, x
|
||||||
|
|
||||||
|
#print(x)
|
||||||
|
assert x in path
|
||||||
|
y = eval(y)
|
||||||
|
|
||||||
|
while x is not humn:
|
||||||
|
assert len(x) == 3
|
||||||
|
op, a, b = x
|
||||||
|
if op == '/':
|
||||||
|
if a in path:
|
||||||
|
y = ('*', y, b)
|
||||||
|
else:
|
||||||
|
raise ValueError("ruh-roh")
|
||||||
|
elif op == '*':
|
||||||
|
if a in path:
|
||||||
|
y = ('/', y, b)
|
||||||
|
else:
|
||||||
|
y = ('/', y, a)
|
||||||
|
elif op == '+':
|
||||||
|
if a in path:
|
||||||
|
y = ('-', y, b)
|
||||||
|
else:
|
||||||
|
y = ('-', y, a)
|
||||||
|
elif op == '-':
|
||||||
|
if a in path:
|
||||||
|
# x - b = y => x = y + b
|
||||||
|
y = ('+', y, b)
|
||||||
|
else:
|
||||||
|
# a - x = y => x = a - y
|
||||||
|
y = ('-', a, y)
|
||||||
|
else:
|
||||||
|
raise ValueError("unknown op "+repr(op))
|
||||||
|
if a in path:
|
||||||
|
x = a
|
||||||
|
else:
|
||||||
|
x = b
|
||||||
|
return eval(y)
|
||||||
|
|
||||||
|
print(solve(root))
|
6
day21/sol.sh
Normal file
6
day21/sol.sh
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
go run part1.go
|
||||||
|
|
||||||
|
go run part2.go > expr.py
|
||||||
|
python sat.py
|
202
day22/input
Normal file
202
day22/input
Normal file
File diff suppressed because one or more lines are too long
14
day22/sample1.in
Normal file
14
day22/sample1.in
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
...#
|
||||||
|
.#..
|
||||||
|
#...
|
||||||
|
....
|
||||||
|
...#.......#
|
||||||
|
........#...
|
||||||
|
..#....#....
|
||||||
|
..........#.
|
||||||
|
...#....
|
||||||
|
.....#..
|
||||||
|
.#......
|
||||||
|
......#.
|
||||||
|
|
||||||
|
10R5L5R10L4R5L5
|
12
day22/sample3.in
Normal file
12
day22/sample3.in
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
>>v#
|
||||||
|
.#v.
|
||||||
|
#.v.
|
||||||
|
..v.
|
||||||
|
...#...v..v#
|
||||||
|
>>>v...<em>></em>#.>>
|
||||||
|
..#v...#....
|
||||||
|
...>>>>v..#.
|
||||||
|
...#....
|
||||||
|
.....#..
|
||||||
|
.#......
|
||||||
|
......#.
|
179
day22/sol.py
Normal file
179
day22/sol.py
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
map = []
|
||||||
|
moves = ""
|
||||||
|
with open("input") as f:
|
||||||
|
for line in f:
|
||||||
|
if line == "\n":
|
||||||
|
break
|
||||||
|
map.append(line.rstrip("\n"))
|
||||||
|
moves = f.readline().strip()
|
||||||
|
|
||||||
|
# 0 - E
|
||||||
|
# 1 - S
|
||||||
|
# 2 - W
|
||||||
|
# 3 - N
|
||||||
|
F = {
|
||||||
|
0: (+1, 0),
|
||||||
|
1: (0, +1),
|
||||||
|
2: (-1, 0),
|
||||||
|
3: (0, -1),
|
||||||
|
}
|
||||||
|
|
||||||
|
#assert len(set(len(l) for l in map)) == 1
|
||||||
|
|
||||||
|
class Map:
|
||||||
|
def __init__(self, map, region_size=50):
|
||||||
|
self.map = map
|
||||||
|
self.row = 0
|
||||||
|
self.col = 0
|
||||||
|
self.face = 0
|
||||||
|
self.region_size = region_size
|
||||||
|
|
||||||
|
while self.map[self.row][self.col] == ' ':
|
||||||
|
self.col += 1
|
||||||
|
|
||||||
|
# 9'
|
||||||
|
# 1 2
|
||||||
|
# \ 4 \
|
||||||
|
# 6 7
|
||||||
|
# 9 \
|
||||||
|
self.region_map = {
|
||||||
|
# R D L U
|
||||||
|
1: [(2,0), (4, 0), (6,2), (9, 1)],
|
||||||
|
4: [(2,-1), (7,0), (6,-1), (1, 0)],
|
||||||
|
7: [(2,2), (9,+1), (6,0), (4,0)],
|
||||||
|
6: [(7,0), (9,0), (1,2), (4,+1)],
|
||||||
|
9: [(7,-1), (2,0), (1,-1), (6,0)],
|
||||||
|
2: [(7,2), (4,+1), (1, 0), (9,0)],
|
||||||
|
}
|
||||||
|
|
||||||
|
ok = True
|
||||||
|
for f in range(4):
|
||||||
|
for r in self.region_map:
|
||||||
|
orig = (r,f)
|
||||||
|
s = repr(orig)
|
||||||
|
for _ in range(4):
|
||||||
|
r, h = self.region_map[r][f]
|
||||||
|
f = (f+h)%4
|
||||||
|
s += "-> {} {}".format(r, f)
|
||||||
|
if (r,f) != orig:
|
||||||
|
print("!!", s)
|
||||||
|
ok = False
|
||||||
|
assert ok, "topology failure"
|
||||||
|
|
||||||
|
def set_simple_region_map(self):
|
||||||
|
R = self.region_size
|
||||||
|
def exists(x,y):
|
||||||
|
return 0 <= y < len(self.map) and 0 <= x < len(self.map[y]) and self.map[y][x] != ' '
|
||||||
|
for y in range(0,len(self.map), R):
|
||||||
|
for x in range(0, len(self.map[y]), R):
|
||||||
|
if exists(x,y):
|
||||||
|
warps = []
|
||||||
|
for f in range(4):
|
||||||
|
dx, dy = F[f]
|
||||||
|
dx, dy = dx*R, dy*R
|
||||||
|
x1, y1 = x+dx, y+dy
|
||||||
|
if exists(x1, y1):
|
||||||
|
dest = self.region(x1,y1)
|
||||||
|
else:
|
||||||
|
if dy:
|
||||||
|
y1 %= len(self.map)
|
||||||
|
while not exists(x1, y1):
|
||||||
|
y1 = (y1+dy)%len(self.map)
|
||||||
|
if dx:
|
||||||
|
x1 %= len(self.map[y1])
|
||||||
|
while not exists(x1, y1):
|
||||||
|
x1 = (x1+dx)%len(self.map[y1])
|
||||||
|
dest = self.region(x1, y1)
|
||||||
|
warps.append((dest, 0))
|
||||||
|
r = self.region(x,y)
|
||||||
|
self.region_map[r] = warps
|
||||||
|
print(self.region_map)
|
||||||
|
|
||||||
|
def nextTile(self, x, y, face):
|
||||||
|
R = self.region_size
|
||||||
|
dx, dy = F[face]
|
||||||
|
if 0 <= (x%R + dx) < R and 0 <= (y%R + dy) < R:
|
||||||
|
x, y = x+dx, y+dy
|
||||||
|
else:
|
||||||
|
r = self.region(x,y)
|
||||||
|
u = (x+dx) % R
|
||||||
|
v = (y+dy) % R
|
||||||
|
|
||||||
|
new_r, rotate = self.region_map[r][face]
|
||||||
|
|
||||||
|
if rotate == 0:
|
||||||
|
pass
|
||||||
|
elif rotate == -1:
|
||||||
|
u, v = v, R-u-1
|
||||||
|
elif rotate == 1:
|
||||||
|
u, v = R-v-1, u
|
||||||
|
elif rotate == 2:
|
||||||
|
u, v = R-u-1, R-v-1
|
||||||
|
x, y = self.to_abs(u, v, new_r)
|
||||||
|
face = (face + rotate) % 4
|
||||||
|
c = self.map[y][x]
|
||||||
|
assert c != ' '
|
||||||
|
return x, y, face, c
|
||||||
|
|
||||||
|
def to_abs(self, u, v, r):
|
||||||
|
"""returns the absolute coords of the local point (u,v) in region r"""
|
||||||
|
R = self.region_size
|
||||||
|
u %= R
|
||||||
|
v %= R
|
||||||
|
rx = r % 3
|
||||||
|
ry = r // 3
|
||||||
|
return (rx*R + u), (ry*R + v)
|
||||||
|
|
||||||
|
def region(self, x, y):
|
||||||
|
R = self.region_size
|
||||||
|
return y//R * 3 + x//R
|
||||||
|
|
||||||
|
def turnLeft(self):
|
||||||
|
self.face = (self.face - 1) % 4
|
||||||
|
def turnRight(self):
|
||||||
|
self.face = (self.face + 1) % 4
|
||||||
|
def walk(self, n, noclip=True):
|
||||||
|
x, y, face = self.col, self.row, self.face
|
||||||
|
while n > 0:
|
||||||
|
x,y,face,c = self.nextTile(x, y, face)
|
||||||
|
if c == '#' and noclip:
|
||||||
|
break
|
||||||
|
n -= 1
|
||||||
|
self.row = y
|
||||||
|
self.col = x
|
||||||
|
self.face = face
|
||||||
|
#print(self.pos())
|
||||||
|
|
||||||
|
def pos(self):
|
||||||
|
return self.row+1, self.col+1
|
||||||
|
|
||||||
|
def score(self):
|
||||||
|
r, c = self.pos()
|
||||||
|
return r*1000 + c*4 + self.face
|
||||||
|
|
||||||
|
#print(moves)
|
||||||
|
|
||||||
|
m = Map(map)
|
||||||
|
#m.set_simple_region_map()
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
while i < len(moves):
|
||||||
|
if moves[i].isdigit():
|
||||||
|
j = i+1
|
||||||
|
while j < len(moves) and moves[j].isdigit():
|
||||||
|
j += 1
|
||||||
|
n = int(moves[i:j])
|
||||||
|
m.walk(n)
|
||||||
|
i = j
|
||||||
|
elif moves[i] == 'L':
|
||||||
|
m.turnLeft()
|
||||||
|
i += 1
|
||||||
|
elif moves[i] == 'R':
|
||||||
|
m.turnRight()
|
||||||
|
i += 1
|
||||||
|
else:
|
||||||
|
print("invalid move", moves[i], "at", i)
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
print(m.row, m.col)
|
||||||
|
print(m.score())
|
72
day23/input
Normal file
72
day23/input
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
#.#####..#..##......##.#..####....#.#.####..##.#######..##..##.###...#..
|
||||||
|
..#..##.#.#.#.##.#......######.#...###....#....#.#..#####.....#..#.####.
|
||||||
|
....#..#.###.####.......#.#.###..#.######...##..#.#.#..#.######.####..##
|
||||||
|
...#.#..####...#..##.#.####..#..##.#####..##.#...#..##..#..#.#.#.####...
|
||||||
|
.##..###..###.#.##...#..#.#.##.##.###.##....#.####.#.##.#..##.#####.#..#
|
||||||
|
#.#.###.#######..#...#####.##..##..##.#...#.#...#####.##....###.#...###.
|
||||||
|
...#...##.#..#.###....#.#.##..#.#..##.#.#.#..#...#.....#.####.##.#..##..
|
||||||
|
####.#...##.##.#..#.#####.#.##.###..#...#.#.##.##......##..#.#..##..##..
|
||||||
|
..#.##.##.####....##.....#.#.......##.#..#.###.####.###.#.....#.#.#...##
|
||||||
|
##...###..###.#.####.#..#...###...####..#####.#.#..##....#.#.####...#..#
|
||||||
|
####..#.#.##.##....#..##.###.#..#..###.##.#.....#######..##.##....#.#.##
|
||||||
|
.##...#.#####...#......##.#.##..#.####......#..###.##.##..#.#...##....##
|
||||||
|
.#.##.#.##.#..#..###.#.###....#.#.#.#.#.###....##..####.#######.##.##.#.
|
||||||
|
#######.##.#...###.#..#######.#..##.#..#.#...#.#.#.#..##.##.#.#.#....#..
|
||||||
|
#.#.#.#.##..##..#.##...##.#.###.####...####.##..#.##.##.###.###.#....##.
|
||||||
|
#...######.#....####.#.#.##....#..#...##.........#####.###..##.#.#..#.#.
|
||||||
|
#.#.#.#.#...#.###...#.....#.#....######......#..#..#.###.#..#.#.##.#....
|
||||||
|
#.##.#...#####.#....#.#.#..##...##.##.##.#####.####.#.##.#.###...#.##.##
|
||||||
|
#...#.#.###........##..#...#.###...###.##......##.####..#.##....##.#..##
|
||||||
|
#####.#..#.....#######..........#..####..##.#.#####..###...#...##.#.####
|
||||||
|
...###..##.##.##.##.#..###...###.#.##.#.###.##.#.#........###...#....##.
|
||||||
|
###.##...##.###..#..#.#.#...##.#.#.....##.#.##....####.####..#######..##
|
||||||
|
##.#.#..#..###.#.#######..#..#.#.#..#####...####...#.####....##.###..##.
|
||||||
|
..#.#.#....####.#.......#..#..###.##.#...##.####..###.#.#..####..#.####.
|
||||||
|
.#.#..##.##..#...##...###.##.#.#.#..#####...#...#####..##.#...###..#.##.
|
||||||
|
..###.#...#.#...#.###...###.##.#.#....#.#...##...##.....#.##.#.###.#....
|
||||||
|
##....#..#........###..#.##.#..##...#.#.#..##.####.#...#.########.###...
|
||||||
|
..#####.##.#...#..##...###.#####...#....#.##.######.#..#.##....###..##..
|
||||||
|
.####.##..###...#.##...#.#.##..###.......#.###.#.##...#.#....#.#.##..##.
|
||||||
|
#..#..###....#..#.#.....#.#.#####..##...####....####.#.#.##....#####.##.
|
||||||
|
##########.####.#...##.##...#....##..##...###....#..###.##..##.###...###
|
||||||
|
##.###..##.####.....#.#.....#.##...#...###..#.#...#....###..###.......#.
|
||||||
|
##..###.#....##..#.#....###...#.####.#.###.#.#.#..##.##..##.######.##...
|
||||||
|
#...####...#.##..##.##.#..####.#..#..#.##.##....#..#.##..##.#.###..#.###
|
||||||
|
#.#..##.###.....#....###.##.##.#.###.#####.#.....##.##.##..#.##.###..###
|
||||||
|
#...#..##..#..###....#..#...#..###...#.##.#.#.###...###..#.##..#..##.##.
|
||||||
|
#.#..#.##.#...#..............#.###...##.##.#.....########.###....#.....#
|
||||||
|
#..#.#...##..#.#.###.##.#.#....####.#.##.#.###.###.#..#..##.....#..####.
|
||||||
|
.....###....##.##..##..#....######......##.###..#.#......#.#..#..#...#.#
|
||||||
|
.##...###.#.#.###...##...##.#.####..#.###.#.#.#.###...##.#...#....###..#
|
||||||
|
#..####.#...#.##..#..#.###.###...#.#.#..##....####..#...##........####..
|
||||||
|
....##.##....#.....#..##..###..####..##.#.#.######..#....#..####.###.#..
|
||||||
|
.#.##..#..#.#.....#........#..###.##.###.##.#..#..##.....#.#.###.###..#.
|
||||||
|
#.#.#.#..#.###.#..#.##.##..######.##.######.#...#.###..#...#...##....#.#
|
||||||
|
##..#...##.#.#.#.######.####.###...####..#....####...#.#..###...##.##..#
|
||||||
|
.##.#....#...##...#...##.##.####..#.##..#.##.####..#.##..#..###..######.
|
||||||
|
.##.#.#.##.#.####..#..#..##.#....#...####.###.##.####.....###..#..#.#..#
|
||||||
|
#.##..#....##....##...#.##..####.#..####....###.##...###....##.###.##...
|
||||||
|
..##..##.#...#.#..###...#.#.#.###.#.#######..#..###.#.###..#.###....#..#
|
||||||
|
#..##.##.####..##.#....##..#.#......###....######..#.....###.....#.#.#..
|
||||||
|
.#...###.##...#.##.##...##...##..####...#..########.###..########.#..#.#
|
||||||
|
###.##.###.#.##.#..#.###....##...###.#.###.##..#.#...#..#####.##.##...#.
|
||||||
|
.###.####..###.#.....####.#...###.##.#.##..#..#....##....#.#..#....###..
|
||||||
|
##.#.#..##.#####..########..##...####....#.##.#.#.###.###.####.....####.
|
||||||
|
#....###.....####.###.###.##..#...#.##.##...##.#..#.........#####......#
|
||||||
|
##.####.#.#..#..#.##...#.##......#...#.#.#.####.##..##...####.....#.#.#.
|
||||||
|
...#.###.#..###.....#.#####.#.....####.###...#.###....#...#..#.#...##.#.
|
||||||
|
.#.......#...#......##..#.###....#.######..###.##...###...##.#.#.##..#.#
|
||||||
|
.##.###.#..#.#####..###...#.###...##.#.####.#.#.#..#....#####...#..##.##
|
||||||
|
.###..#...##..#.....##.#...#.#...##..##.#.###..###.#....##.###.###..#...
|
||||||
|
#######.##..#..#.#...#..#.#..#.#..###..#########.#.....#.....####.##.#.#
|
||||||
|
#.##..####...##.#..###.###...#....####...####..#...#####...##.#...#####.
|
||||||
|
#..##.#..#.######.#.#.#.##...##..#...##...#.......#.#####.#...#.##..#.#.
|
||||||
|
.##..#..###..#####.#.##..######.##...#.###.##.##.#..#....#..#.###..####.
|
||||||
|
...#...##.#...##.#.###.#.#..##..####.....#..........#..#.........##..##.
|
||||||
|
#####..##......##.##...#.##.###...####....##.##..#.###.#..##..#.##.#....
|
||||||
|
.###....##.#####.#.###.#.##...##.####....###..#......#.#..#....##.#.#.##
|
||||||
|
..###.#....#######.#.#..#.###.##.##..#..###...##.###.##.####.##.##.####.
|
||||||
|
.#.#...##.#..##.....###.#..#.#...##..#..#.#.#.###.##.##.#.....#.##..#...
|
||||||
|
.#####.#....#..#.####..####..#....#....##.#...#.##...###.#.#...#########
|
||||||
|
###.####....#.####..#..###....#.###.##...#####.###...#.#..#.#........###
|
||||||
|
#.#.######...#.#..#####.#.####.....##...#.###.#.##..##.#.#.##..#.####.#.
|
1
day23/input.ivy
Normal file
1
day23/input.ivy
Normal file
File diff suppressed because one or more lines are too long
7
day23/sample1.in
Normal file
7
day23/sample1.in
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
....#..
|
||||||
|
..###.#
|
||||||
|
#...#.#
|
||||||
|
.#...##
|
||||||
|
#.###..
|
||||||
|
##.#.##
|
||||||
|
.#..#..
|
107
day23/sol.ivy
Normal file
107
day23/sol.ivy
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
)get "input.ivy"
|
||||||
|
sample = 7 7 rho '....#..' '..###.#' '#...#.#' '.#...##' '#.###..' '##.#.##' '.#..#..'
|
||||||
|
|
||||||
|
#board = sample == '#'
|
||||||
|
board = input == '#'
|
||||||
|
#board
|
||||||
|
|
||||||
|
op show a = (text ".#23456789"[1+a]),"\n-"
|
||||||
|
|
||||||
|
op lift a = (1,rho a) rho a
|
||||||
|
op n moveNSWE a = (lift n flip a[1]), (lift (-n) flip a[2]), (lift n rot a[3]), (lift (-n) rot a[4])
|
||||||
|
|
||||||
|
op any a = or/,a
|
||||||
|
op maybePad1 a =
|
||||||
|
c1 = any a[1]
|
||||||
|
c2 = any a[(rho a)[1]]
|
||||||
|
c1 and c2: 0,a,0
|
||||||
|
c1: 0,a
|
||||||
|
c2: a,0
|
||||||
|
a
|
||||||
|
|
||||||
|
op maybePad a =
|
||||||
|
a = maybePad1 a
|
||||||
|
(any a[;1]) or (any a[;(rho a)[2]]): transp maybePad1 transp a
|
||||||
|
a
|
||||||
|
|
||||||
|
op smearWE a = a or (1 rot a) or (-1 rot a)
|
||||||
|
op smearNS a = a or (1 flip a) or (-1 flip a)
|
||||||
|
|
||||||
|
op look a =
|
||||||
|
ns = lift smearNS a
|
||||||
|
we = lift smearWE a
|
||||||
|
-1 moveNSWE (we, we, ns, ns)
|
||||||
|
|
||||||
|
op axis1 a = 3 1 2 transp a
|
||||||
|
op dup4 a = (4,rho a) rho a
|
||||||
|
|
||||||
|
# look in each direction
|
||||||
|
# an elf can move in a direction if there is no elf in said direction and there is an elf somewhere nearby
|
||||||
|
# returns a 4x(rho a) matrix
|
||||||
|
op canMove a =
|
||||||
|
C = look a
|
||||||
|
(not C) and dup4 (a and or/axis1 C)
|
||||||
|
|
||||||
|
|
||||||
|
# prepare moves
|
||||||
|
# assign each move a priority and take the max
|
||||||
|
# remove lower priority moves
|
||||||
|
op p prepare choices =
|
||||||
|
best = max/ p * axis1 choices # select best direction
|
||||||
|
p o.== best # decompose into 4x?x? matrix
|
||||||
|
|
||||||
|
# count how many elves want to move to each square
|
||||||
|
# filter out moves which conflict
|
||||||
|
op unblocked moves =
|
||||||
|
open = 1 == +/axis1 1 moveNSWE moves
|
||||||
|
moves and -1 moveNSWE dup4 open
|
||||||
|
|
||||||
|
priority = 4 3 2 1
|
||||||
|
M = 0
|
||||||
|
changed = 0
|
||||||
|
|
||||||
|
op M round a =
|
||||||
|
a = maybePad a
|
||||||
|
moves = unblocked (M flip priority) prepare canMove a
|
||||||
|
moved = or/axis1 moves
|
||||||
|
changed; changed = +/, moved
|
||||||
|
b = (a and not moved) + +/axis1 1 moveNSWE moves
|
||||||
|
b
|
||||||
|
|
||||||
|
op round a = M round a
|
||||||
|
|
||||||
|
# this is implemented using globals
|
||||||
|
# to store the board instead of recursion
|
||||||
|
# in order to avoid keeping a bunch of large
|
||||||
|
# intermediate values alive on the stack
|
||||||
|
B = 0
|
||||||
|
op i loop n =
|
||||||
|
i > n: i
|
||||||
|
changed; changed = 0
|
||||||
|
B = M round B
|
||||||
|
M = M - 1
|
||||||
|
changed == 0: i
|
||||||
|
(i+1) loop n
|
||||||
|
|
||||||
|
op n rounds a =
|
||||||
|
B; B = a
|
||||||
|
M; M = 0
|
||||||
|
1 loop n
|
||||||
|
B
|
||||||
|
|
||||||
|
op n numrounds a =
|
||||||
|
B; B = a
|
||||||
|
M; M = 0
|
||||||
|
1 loop n
|
||||||
|
|
||||||
|
op score a =
|
||||||
|
a = maybePad a
|
||||||
|
n = */ (rho a) - 2
|
||||||
|
n - +/, a
|
||||||
|
|
||||||
|
show board
|
||||||
|
#show round board
|
||||||
|
show 10 rounds board
|
||||||
|
score 10 rounds board
|
||||||
|
|
||||||
|
1000 numrounds board
|
92
day23/sol.py
Normal file
92
day23/sol.py
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
from collections import Counter
|
||||||
|
pos = {}
|
||||||
|
y = 0
|
||||||
|
for line in open("input"):
|
||||||
|
for x, c in enumerate(line):
|
||||||
|
if c == '#':
|
||||||
|
pos[x,y] = 1
|
||||||
|
y += 1
|
||||||
|
|
||||||
|
|
||||||
|
def choices(pos, dir):
|
||||||
|
x,y = pos
|
||||||
|
dy = (dir == 'S') - (dir == 'N')
|
||||||
|
dx = (dir == 'E') - (dir == 'W')
|
||||||
|
if dx:
|
||||||
|
for dy in -1,0,+1:
|
||||||
|
yield x+dx,y+dy
|
||||||
|
else:
|
||||||
|
assert dy
|
||||||
|
for dx in -1,0,+1:
|
||||||
|
yield x+dx, y+dy
|
||||||
|
|
||||||
|
def go(pos, dir):
|
||||||
|
x,y = pos
|
||||||
|
dy = (dir == 'S') - (dir == 'N')
|
||||||
|
dx = (dir == 'E') - (dir == 'W')
|
||||||
|
return x+dx,y+dy
|
||||||
|
|
||||||
|
def neighbors(pos):
|
||||||
|
x,y = pos
|
||||||
|
for dx in -1,0,+1:
|
||||||
|
for dy in -1,0,+1:
|
||||||
|
if dx or dy:
|
||||||
|
yield x+dx,y+dy
|
||||||
|
|
||||||
|
def migrate(start, rounds):
|
||||||
|
moves = ['N', 'S', 'W', 'E']
|
||||||
|
for i in range(rounds):
|
||||||
|
#show(start)
|
||||||
|
#print("-")
|
||||||
|
propose = {}
|
||||||
|
destCount = Counter()
|
||||||
|
|
||||||
|
for p in start:
|
||||||
|
propose[p] = p
|
||||||
|
if any(n in start for n in neighbors(p)):
|
||||||
|
for m in moves:
|
||||||
|
if not any(c in start for c in choices(p, m)):
|
||||||
|
c = go(p,m)
|
||||||
|
propose[p] = c
|
||||||
|
destCount[c] += 1
|
||||||
|
break
|
||||||
|
|
||||||
|
next = {}
|
||||||
|
moved = 0
|
||||||
|
for p, d in propose.items():
|
||||||
|
if destCount[d] <= 1:
|
||||||
|
next[d] = 1
|
||||||
|
moved += p != d
|
||||||
|
else:
|
||||||
|
next[p] = 1
|
||||||
|
|
||||||
|
if not moved:
|
||||||
|
break
|
||||||
|
|
||||||
|
moves.append(moves.pop(0))
|
||||||
|
start = next
|
||||||
|
return start, i+1
|
||||||
|
|
||||||
|
def show(pos):
|
||||||
|
xmin = min(x for x,y in pos)
|
||||||
|
ymin = min(y for x,y in pos)
|
||||||
|
xmax = max(x for x,y in pos)
|
||||||
|
ymax = max(y for x,y in pos)
|
||||||
|
for y in range(ymin, ymax+1):
|
||||||
|
print("".join(".#"[(x,y) in pos] for x in range(xmin,xmax+1)))
|
||||||
|
|
||||||
|
def count_empty(pos):
|
||||||
|
n = 0
|
||||||
|
xmin = min(x for x,y in pos)
|
||||||
|
ymin = min(y for x,y in pos)
|
||||||
|
xmax = max(x for x,y in pos)
|
||||||
|
ymax = max(y for x,y in pos)
|
||||||
|
return (ymax-ymin+1)*(xmax-xmin+1) - len(pos)
|
||||||
|
|
||||||
|
|
||||||
|
#print(pos)
|
||||||
|
end, _ = migrate(pos, 10)
|
||||||
|
print(count_empty(end))
|
||||||
|
|
||||||
|
_, n = migrate(pos, 100000)
|
||||||
|
print(n)
|
42
day23/toivy.py
Executable file
42
day23/toivy.py
Executable file
@ -0,0 +1,42 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
"""
|
||||||
|
Converts a text file containing a list of integers
|
||||||
|
into a format that can be loaded by ivy.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
if sys.argv[1:]:
|
||||||
|
filename = sys.argv[1]
|
||||||
|
else:
|
||||||
|
filename = "input"
|
||||||
|
|
||||||
|
varname = filename.split(".",1)[0]
|
||||||
|
|
||||||
|
with open(filename) as f:
|
||||||
|
lines = f.read().splitlines()
|
||||||
|
|
||||||
|
data = []
|
||||||
|
for line in lines:
|
||||||
|
line = line.replace("-", ",")
|
||||||
|
data.append(line.split(","))
|
||||||
|
|
||||||
|
def count(row):
|
||||||
|
n = 0
|
||||||
|
for x in row:
|
||||||
|
if x.isdigit():
|
||||||
|
n += 1
|
||||||
|
else:
|
||||||
|
n += len(x)
|
||||||
|
return n
|
||||||
|
|
||||||
|
cols = max(map(count, data))
|
||||||
|
|
||||||
|
print("{} = {} {} rho".format(varname, len(data), cols), end="")
|
||||||
|
for row in data:
|
||||||
|
print("", " ".join(
|
||||||
|
x if x.isdigit() else repr(x)
|
||||||
|
for x in row), end="")
|
||||||
|
n = count(row)
|
||||||
|
if n < cols:
|
||||||
|
print(" 0" * (cols - n), end="")
|
Loading…
x
Reference in New Issue
Block a user