day 14, use rotation, proper cycle detection, merge both parts, enable codon

This commit is contained in:
setop 2023-12-16 01:56:25 +01:00
parent a4e02c42a7
commit 6fe70f851f
3 changed files with 49 additions and 89 deletions

View File

@ -1,30 +0,0 @@
import sys
# load ptf flat
G = [list(l) for l in sys.stdin.read().splitlines()]
W = len(G[0])
H = len(G)
print(W,H)
# move far north each com
for x in range(W):
for y in range(H):
print(f'{x=},{y=} = {G[y][x]}')
if G[y][x] == "O":
for j in range(y-1,0-1,-1):
print(f'{j=}')
if G[j][x] == '.': # can go north
print(f'north, {j=}')
G[j][x] = "O"
G[j+1][x] = "."
else:
break
S = 0
for y,row in enumerate(G):
print(''.join(row))
S += (H-y)*row.count('O')
print(S)
# compute

View File

@ -1,59 +0,0 @@
import sys
I = sys.stdin.read().splitlines()
G = [list(l) for l in I]
W = len(G[0])
H = len(G)
def north():
for x in range(W):
for y in range(H):
if G[y][x] == "O":
for j in range(y-1,0-1,-1):
if G[j][x] == '.':
G[j][x] = "O"
G[j+1][x] = "."
else:
break
def south():
for x in range(W):
for y in range(H-1,0-1,-1):
if G[y][x] == "O":
for j in range(y+1,W,1):
if G[j][x] == '.':
G[j][x] = "O"
G[j-1][x] = "."
else:
break
def east():
for y in range(H):
for x in range(W-1,0-1,-1):
if G[y][x] == "O":
for i in range(x+1,H,1):
if G[y][i] == '.':
G[y][i] = "O"
G[y][i-1] = "."
else:
break
def west():
for y in range(H):
for x in range(W):
if G[y][x] == "O":
for i in range(x-1,0-1,-1):
if G[y][i] == '.':
G[y][i] = "O"
G[y][i+1] = "."
else:
break
for _ in range(1_000):
north()
west()
south()
east()
print(sum((H-y)*row.count('O') for y,row in enumerate(G)))

49
d14/run.py Normal file
View File

@ -0,0 +1,49 @@
import sys
I = sys.stdin.read().splitlines()
G = [list(l) for l in I]
R = len(G)
C = len(G[0])
def rotate(G, F):
for r in range(R):
for c in range(C):
F[c][R-1-r] = G[r][c]
def tilt(G):
for x in range(C):
for y in range(R):
if G[y][x] == "O":
for j in range(y-1,0-1,-1):
if G[j][x] == '.':
G[j][x] = "O"
G[j+1][x] = "."
else:
break
score = lambda: sum((R-y)*row.count('O') for y,row in enumerate(G))
cache = {}
F = [['?' for _ in range(C)] for _ in range(R)] # pre-allocate saves 10% time (no GC)
target = 1_000_000_000
t = 0
while t<target:
print(t, end='\r')
t += 1
for j in range(4):
tilt(G)
if t==1 and j==0: # part 1
print(score())
rotate(G, F); F, G = G, F
#Gh = tuple(tuple(row) for row in G)
Gh = ''.join(''.join(row) for row in G)
if Gh in cache:
cycle_length = t-cache[Gh]
print(f'{t=}, {cycle_length=}')
amt = (target-t)//cycle_length
t += amt * cycle_length
cache[Gh] = t
print(t, score())