Compare commits
No commits in common. "9e168db913054a26c1227f0d09fa5220b123101a" and "cb4b8295e11c7a87e79197fa03829bf3a1859667" have entirely different histories.
9e168db913
...
cb4b8295e1
File diff suppressed because one or more lines are too long
2037
day21/input
2037
day21/input
File diff suppressed because it is too large
Load Diff
2047
day21/part1.go
2047
day21/part1.go
File diff suppressed because it is too large
Load Diff
2054
day21/part2.go
2054
day21/part2.go
File diff suppressed because it is too large
Load Diff
26
day21/sat.py
26
day21/sat.py
@ -1,26 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
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
103
day21/sol.py
@ -1,103 +0,0 @@
|
|||||||
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))
|
|
@ -1,6 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
go run part1.go
|
|
||||||
|
|
||||||
go run part2.go > expr.py
|
|
||||||
python sat.py
|
|
202
day22/input
202
day22/input
File diff suppressed because one or more lines are too long
@ -1,14 +0,0 @@
|
|||||||
...#
|
|
||||||
.#..
|
|
||||||
#...
|
|
||||||
....
|
|
||||||
...#.......#
|
|
||||||
........#...
|
|
||||||
..#....#....
|
|
||||||
..........#.
|
|
||||||
...#....
|
|
||||||
.....#..
|
|
||||||
.#......
|
|
||||||
......#.
|
|
||||||
|
|
||||||
10R5L5R10L4R5L5
|
|
@ -1,12 +0,0 @@
|
|||||||
>>v#
|
|
||||||
.#v.
|
|
||||||
#.v.
|
|
||||||
..v.
|
|
||||||
...#...v..v#
|
|
||||||
>>>v...<em>></em>#.>>
|
|
||||||
..#v...#....
|
|
||||||
...>>>>v..#.
|
|
||||||
...#....
|
|
||||||
.....#..
|
|
||||||
.#......
|
|
||||||
......#.
|
|
179
day22/sol.py
179
day22/sol.py
@ -1,179 +0,0 @@
|
|||||||
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
72
day23/input
@ -1,72 +0,0 @@
|
|||||||
#.#####..#..##......##.#..####....#.#.####..##.#######..##..##.###...#..
|
|
||||||
..#..##.#.#.#.##.#......######.#...###....#....#.#..#####.....#..#.####.
|
|
||||||
....#..#.###.####.......#.#.###..#.######...##..#.#.#..#.######.####..##
|
|
||||||
...#.#..####...#..##.#.####..#..##.#####..##.#...#..##..#..#.#.#.####...
|
|
||||||
.##..###..###.#.##...#..#.#.##.##.###.##....#.####.#.##.#..##.#####.#..#
|
|
||||||
#.#.###.#######..#...#####.##..##..##.#...#.#...#####.##....###.#...###.
|
|
||||||
...#...##.#..#.###....#.#.##..#.#..##.#.#.#..#...#.....#.####.##.#..##..
|
|
||||||
####.#...##.##.#..#.#####.#.##.###..#...#.#.##.##......##..#.#..##..##..
|
|
||||||
..#.##.##.####....##.....#.#.......##.#..#.###.####.###.#.....#.#.#...##
|
|
||||||
##...###..###.#.####.#..#...###...####..#####.#.#..##....#.#.####...#..#
|
|
||||||
####..#.#.##.##....#..##.###.#..#..###.##.#.....#######..##.##....#.#.##
|
|
||||||
.##...#.#####...#......##.#.##..#.####......#..###.##.##..#.#...##....##
|
|
||||||
.#.##.#.##.#..#..###.#.###....#.#.#.#.#.###....##..####.#######.##.##.#.
|
|
||||||
#######.##.#...###.#..#######.#..##.#..#.#...#.#.#.#..##.##.#.#.#....#..
|
|
||||||
#.#.#.#.##..##..#.##...##.#.###.####...####.##..#.##.##.###.###.#....##.
|
|
||||||
#...######.#....####.#.#.##....#..#...##.........#####.###..##.#.#..#.#.
|
|
||||||
#.#.#.#.#...#.###...#.....#.#....######......#..#..#.###.#..#.#.##.#....
|
|
||||||
#.##.#...#####.#....#.#.#..##...##.##.##.#####.####.#.##.#.###...#.##.##
|
|
||||||
#...#.#.###........##..#...#.###...###.##......##.####..#.##....##.#..##
|
|
||||||
#####.#..#.....#######..........#..####..##.#.#####..###...#...##.#.####
|
|
||||||
...###..##.##.##.##.#..###...###.#.##.#.###.##.#.#........###...#....##.
|
|
||||||
###.##...##.###..#..#.#.#...##.#.#.....##.#.##....####.####..#######..##
|
|
||||||
##.#.#..#..###.#.#######..#..#.#.#..#####...####...#.####....##.###..##.
|
|
||||||
..#.#.#....####.#.......#..#..###.##.#...##.####..###.#.#..####..#.####.
|
|
||||||
.#.#..##.##..#...##...###.##.#.#.#..#####...#...#####..##.#...###..#.##.
|
|
||||||
..###.#...#.#...#.###...###.##.#.#....#.#...##...##.....#.##.#.###.#....
|
|
||||||
##....#..#........###..#.##.#..##...#.#.#..##.####.#...#.########.###...
|
|
||||||
..#####.##.#...#..##...###.#####...#....#.##.######.#..#.##....###..##..
|
|
||||||
.####.##..###...#.##...#.#.##..###.......#.###.#.##...#.#....#.#.##..##.
|
|
||||||
#..#..###....#..#.#.....#.#.#####..##...####....####.#.#.##....#####.##.
|
|
||||||
##########.####.#...##.##...#....##..##...###....#..###.##..##.###...###
|
|
||||||
##.###..##.####.....#.#.....#.##...#...###..#.#...#....###..###.......#.
|
|
||||||
##..###.#....##..#.#....###...#.####.#.###.#.#.#..##.##..##.######.##...
|
|
||||||
#...####...#.##..##.##.#..####.#..#..#.##.##....#..#.##..##.#.###..#.###
|
|
||||||
#.#..##.###.....#....###.##.##.#.###.#####.#.....##.##.##..#.##.###..###
|
|
||||||
#...#..##..#..###....#..#...#..###...#.##.#.#.###...###..#.##..#..##.##.
|
|
||||||
#.#..#.##.#...#..............#.###...##.##.#.....########.###....#.....#
|
|
||||||
#..#.#...##..#.#.###.##.#.#....####.#.##.#.###.###.#..#..##.....#..####.
|
|
||||||
.....###....##.##..##..#....######......##.###..#.#......#.#..#..#...#.#
|
|
||||||
.##...###.#.#.###...##...##.#.####..#.###.#.#.#.###...##.#...#....###..#
|
|
||||||
#..####.#...#.##..#..#.###.###...#.#.#..##....####..#...##........####..
|
|
||||||
....##.##....#.....#..##..###..####..##.#.#.######..#....#..####.###.#..
|
|
||||||
.#.##..#..#.#.....#........#..###.##.###.##.#..#..##.....#.#.###.###..#.
|
|
||||||
#.#.#.#..#.###.#..#.##.##..######.##.######.#...#.###..#...#...##....#.#
|
|
||||||
##..#...##.#.#.#.######.####.###...####..#....####...#.#..###...##.##..#
|
|
||||||
.##.#....#...##...#...##.##.####..#.##..#.##.####..#.##..#..###..######.
|
|
||||||
.##.#.#.##.#.####..#..#..##.#....#...####.###.##.####.....###..#..#.#..#
|
|
||||||
#.##..#....##....##...#.##..####.#..####....###.##...###....##.###.##...
|
|
||||||
..##..##.#...#.#..###...#.#.#.###.#.#######..#..###.#.###..#.###....#..#
|
|
||||||
#..##.##.####..##.#....##..#.#......###....######..#.....###.....#.#.#..
|
|
||||||
.#...###.##...#.##.##...##...##..####...#..########.###..########.#..#.#
|
|
||||||
###.##.###.#.##.#..#.###....##...###.#.###.##..#.#...#..#####.##.##...#.
|
|
||||||
.###.####..###.#.....####.#...###.##.#.##..#..#....##....#.#..#....###..
|
|
||||||
##.#.#..##.#####..########..##...####....#.##.#.#.###.###.####.....####.
|
|
||||||
#....###.....####.###.###.##..#...#.##.##...##.#..#.........#####......#
|
|
||||||
##.####.#.#..#..#.##...#.##......#...#.#.#.####.##..##...####.....#.#.#.
|
|
||||||
...#.###.#..###.....#.#####.#.....####.###...#.###....#...#..#.#...##.#.
|
|
||||||
.#.......#...#......##..#.###....#.######..###.##...###...##.#.#.##..#.#
|
|
||||||
.##.###.#..#.#####..###...#.###...##.#.####.#.#.#..#....#####...#..##.##
|
|
||||||
.###..#...##..#.....##.#...#.#...##..##.#.###..###.#....##.###.###..#...
|
|
||||||
#######.##..#..#.#...#..#.#..#.#..###..#########.#.....#.....####.##.#.#
|
|
||||||
#.##..####...##.#..###.###...#....####...####..#...#####...##.#...#####.
|
|
||||||
#..##.#..#.######.#.#.#.##...##..#...##...#.......#.#####.#...#.##..#.#.
|
|
||||||
.##..#..###..#####.#.##..######.##...#.###.##.##.#..#....#..#.###..####.
|
|
||||||
...#...##.#...##.#.###.#.#..##..####.....#..........#..#.........##..##.
|
|
||||||
#####..##......##.##...#.##.###...####....##.##..#.###.#..##..#.##.#....
|
|
||||||
.###....##.#####.#.###.#.##...##.####....###..#......#.#..#....##.#.#.##
|
|
||||||
..###.#....#######.#.#..#.###.##.##..#..###...##.###.##.####.##.##.####.
|
|
||||||
.#.#...##.#..##.....###.#..#.#...##..#..#.#.#.###.##.##.#.....#.##..#...
|
|
||||||
.#####.#....#..#.####..####..#....#....##.#...#.##...###.#.#...#########
|
|
||||||
###.####....#.####..#..###....#.###.##...#####.###...#.#..#.#........###
|
|
||||||
#.#.######...#.#..#####.#.####.....##...#.###.#.##..##.#.#.##..#.####.#.
|
|
File diff suppressed because one or more lines are too long
@ -1,7 +0,0 @@
|
|||||||
....#..
|
|
||||||
..###.#
|
|
||||||
#...#.#
|
|
||||||
.#...##
|
|
||||||
#.###..
|
|
||||||
##.#.##
|
|
||||||
.#..#..
|
|
107
day23/sol.ivy
107
day23/sol.ivy
@ -1,107 +0,0 @@
|
|||||||
)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
92
day23/sol.py
@ -1,92 +0,0 @@
|
|||||||
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)
|
|
@ -1,42 +0,0 @@
|
|||||||
#!/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