summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGustav Sörnäs <gustav@sornas.net>2020-12-17 06:26:17 +0100
committerGustav Sörnäs <gustav@sornas.net>2020-12-17 06:26:17 +0100
commit2aecb39c0e6cf051f27b9a50be210cc07e86f30a (patch)
tree947ddd2141e00bef8b6b2404971f36186935c2f3
parentf4ef5ba6875cc3a888c39ed5c495cfffc1be13c8 (diff)
downloadaoc-2aecb39c0e6cf051f27b9a50be210cc07e86f30a.tar.gz
day 17
-rw-r--r--20/README2
-rw-r--r--20/py/d17.py90
2 files changed, 92 insertions, 0 deletions
diff --git a/20/README b/20/README
index 4d7a179..9539541 100644
--- a/20/README
+++ b/20/README
@@ -18,6 +18,7 @@ Day Time Ans Time Ans
14 4.357 15018100062885 55.561 5724245857696
15 0.363 232 10516.154 18929178
16 156.622 18227 33.297 2355350878831
+ 17 8.053 295 209.633 1972
------- -------
tot TBD ms TBD ms
@@ -26,6 +27,7 @@ Stats:
-------Part 1-------- -------Part 2--------
Day Time Rank Score Time Rank Score
+ 17 00:17:45 416 0 00:21:34 386 0
16 00:13:11 830 0 00:50:54 1318 0
15 00:59:43 5655 0 01:17:06 4904 0
14 00:43:31 4037 0 01:00:44 2402 0
diff --git a/20/py/d17.py b/20/py/d17.py
new file mode 100644
index 0000000..5ec1419
--- /dev/null
+++ b/20/py/d17.py
@@ -0,0 +1,90 @@
+#!/usr/bin/env python3
+import aoc20
+import sys
+import functools
+from collections import defaultdict
+
+
+@functools.cache
+def neighbours3(p):
+ res = set()
+ for dx in range(-1, 1+1):
+ for dy in range(-1, 1+1):
+ for dz in range(-1, 1+1):
+ if dx == dy == dz == 0:
+ continue
+ res.add((p[0] + dx, p[1] + dy, p[2] + dz))
+ return res
+
+
+def pt1(_in):
+ active = set()
+ board = defaultdict(lambda: 0)
+ for y in range(len(_in)):
+ for x in range(len(_in[y])):
+ if _in[y][x] == "#":
+ active.add((x, y, 0))
+ for n in neighbours3((x, y, 0)):
+ board[n] += 1
+
+ for _ in range(6):
+ new_board = defaultdict(lambda: 0)
+ new_active = set()
+ for p, deg in board.items():
+ if p in active and 2 <= deg <= 3:
+ new_active.add(p)
+ for n in neighbours3(p):
+ new_board[n] += 1
+ elif p not in active and deg == 3:
+ new_active.add(p)
+ for n in neighbours3(p):
+ new_board[n] += 1
+ board = new_board
+ active = new_active
+ return(len(active))
+
+
+@functools.cache
+def neighbours4(p):
+ res = set()
+ for dx in range(-1, 1+1):
+ for dy in range(-1, 1+1):
+ for dz in range(-1, 1+1):
+ for dw in range(-1, 1+1):
+ if dx == dy == dz == dw == 0:
+ continue
+ res.add((p[0] + dx, p[1] + dy, p[2] + dz, p[3] + dw))
+ return res
+
+
+def pt2(_in):
+ active = set()
+ board = defaultdict(lambda: 0)
+ for y in range(len(_in)):
+ for x in range(len(_in[y])):
+ if _in[y][x] == "#":
+ active.add((x, y, 0, 0))
+ for n in neighbours4((x, y, 0, 0)):
+ board[n] += 1
+
+ for _ in range(6):
+ new_board = defaultdict(lambda: 0)
+ new_active = set()
+ for p, deg in board.items():
+ if p in active and 2 <= deg <= 3:
+ new_active.add(p)
+ for n in neighbours4(p):
+ new_board[n] += 1
+ elif p not in active and deg == 3:
+ new_active.add(p)
+ for n in neighbours4(p):
+ new_board[n] += 1
+ board = new_board
+ active = new_active
+ return(len(active))
+
+
+if __name__ == "__main__":
+ input = aoc20.read_input(sys.argv[1:], 17)
+ print(pt1(input))
+ print(pt2(input))