This commit is contained in:
Sijmen 2024-01-04 04:43:34 +01:00
parent d57166fdd7
commit fe181838e8
Signed by: vijfhoek
GPG key ID: DAF7821E067D9C48
2 changed files with 74 additions and 52 deletions

View file

@ -2,57 +2,72 @@ import sys
from pprint import pprint from pprint import pprint
from copy import deepcopy from copy import deepcopy
def shift(map, dx, dy): def shift(map, dx, dy):
swapped = True
while swapped:
swapped = False
for y in range(max(0, -dy), len(map) - max(0, dy)): for y in range(max(0, -dy), len(map) - max(0, dy)):
for x in range(max(0, -dx), len(map) - max(0, dx)): for x in range(max(0, -dx), len(map) - max(0, dx)):
if map[y + dy][x + dx] == "." and map[y][x] == "O": (x1, y1) = (x, y)
map[y + dy][x + dx] = "O" while True:
(x2, y2) = (x1 + dx, y1 + dy)
if 0 <= y2 < len(map) and 0 <= x2 < len(map[y2]) and map[y2][x2] == ".":
(x1, y1) = (x2, y2)
else:
break
if (x1, y1) != (x, y):
map[y1][x1] = "O"
map[y][x] = "." map[y][x] = "."
swapped = True
def weigh(map): def weigh(map):
return sum((len(map) - y) * row.count("O") for (y, row) in enumerate(map)) return sum((len(map) - y) * row.count("O") for (y, row) in enumerate(map))
CYCLES = 1_000_000_000
# @profile
def main(): def main():
CYCLES = 1_000_000_000
with open(sys.argv[1]) as f: with open(sys.argv[1]) as f:
map = [list(l) for l in f.read().strip().splitlines()] map = [[c for c in l] for l in f.read().strip().splitlines()]
part1 = 0 part1 = 0
pprint(map)
shift(map, 0, -1) shift(map, 0, -1)
pprint(map)
part1 = weigh(map) part1 = weigh(map)
shift(map, -1, 0)
pprint(map)
shift(map, 0, 1)
pprint(map)
shift(map, 1, 0)
pprint(map)
for i in range(1, 100):
shift(map, 0, -1)
shift(map, -1, 0)
shift(map, 0, 1)
shift(map, 1, 0)
seen = {} seen = {}
history = [] history = []
for i in range(CYCLES): (i, j) = (0, 0)
for i in range(100, CYCLES):
shift(map, 0, -1) shift(map, 0, -1)
if i == 0: pprint(map)
shift(map, -1, 0) shift(map, -1, 0)
if i == 0: pprint(map)
shift(map, 0, 1) shift(map, 0, 1)
if i == 0: pprint(map)
shift(map, 1, 0) shift(map, 1, 0)
if i == 0: pprint(map)
s = str(map) s = str(map)
history.append(weigh(map))
if s in seen: if s in seen:
j = seen[s]
break break
seen[s] = i seen[s] = i
history.append(weigh(map))
j = seen[s] offset = (CYCLES - j) % (i - j) - 1
offset = (CYCLES - j) % (i + 1 - j) + j
part2 = history[offset] part2 = history[offset]
print(part1, part2) print(part1, part2)
main() main()
# 98887 too low
# 98898 too high
# 103761 too high

View file

@ -2,7 +2,8 @@ import os
import sys import sys
from collections import defaultdict from collections import defaultdict
def hash(s):
def hash(s: str) -> int:
v = 0 v = 0
for c in s: for c in s:
if c == ",": if c == ",":
@ -12,13 +13,15 @@ def hash(s):
v %= 256 v %= 256
return v return v
with open(sys.argv[1]) as f:
def main() -> None:
with open(sys.argv[1]) as f:
s = f.read().strip() s = f.read().strip()
boxes = defaultdict(list) boxes: defaultdict[int, list[tuple[str, int]]] = defaultdict(list)
part1 = 0 part1 = 0
for s_ in s.split(","): for s_ in s.split(","):
part1 += hash(s_) part1 += hash(s_)
if s_[-1] == "-": if s_[-1] == "-":
@ -39,9 +42,13 @@ for s_ in s.split(","):
else: else:
boxes[h].append((label, focal)) boxes[h].append((label, focal))
part2 = 0 part2 = 0
for (box_i, box) in boxes.items(): for (box_i, box) in boxes.items():
for (slot, (_, focal)) in enumerate(box): for (slot, (_, focal)) in enumerate(box):
part2 += (box_i + 1) * (slot + 1) * focal part2 += (box_i + 1) * (slot + 1) * focal
print(part1, part2) print(part1, part2)
if __name__ == "__main__":
main()