day 14, use rotation, proper cycle detection, merge both parts, enable codon
This commit is contained in:
		
							
								
								
									
										30
									
								
								d14/part1.py
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								d14/part1.py
									
									
									
									
									
								
							@@ -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
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										59
									
								
								d14/part2.py
									
									
									
									
									
								
							
							
						
						
									
										59
									
								
								d14/part2.py
									
									
									
									
									
								
							@@ -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
									
								
							
							
						
						
									
										49
									
								
								d14/run.py
									
									
									
									
									
										Normal 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())
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user