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