Finish day 21 part 2 not super hands free but I take it.
This commit is contained in:
parent
40ac031eb4
commit
1ceb67a7fd
192
d21.py
192
d21.py
@ -1,7 +1,7 @@
|
||||
from lib import *
|
||||
import os
|
||||
|
||||
EXAMPLE = """
|
||||
...........
|
||||
EXAMPLE = """...........
|
||||
.....###.#.
|
||||
.###.##..#.
|
||||
..#.#...#..
|
||||
@ -14,13 +14,11 @@ EXAMPLE = """
|
||||
...........
|
||||
"""
|
||||
|
||||
def solve(i: Input, second=False):
|
||||
res = 0
|
||||
g = i.grid2()
|
||||
def solve(input: Input):
|
||||
g = input.grid2()
|
||||
s = g.find('S')[0]
|
||||
g[s] = 'O'
|
||||
# steps = 64
|
||||
steps = 26501365
|
||||
steps = 64
|
||||
seen = set()
|
||||
for i in range(steps):
|
||||
os = tuple(g.find('O'))
|
||||
@ -38,18 +36,178 @@ def solve(i: Input, second=False):
|
||||
g[nb] = 'O'
|
||||
return len(g.find('O'))
|
||||
|
||||
|
||||
def plot(xs, poss):
|
||||
os.system("clear")
|
||||
rcoords = [x[0] for x in xs]
|
||||
ccoords = [x[1] for x in xs]
|
||||
rmin = min(rcoords)
|
||||
rmax = max(rcoords)
|
||||
cmin = min(ccoords)
|
||||
cmax = max(ccoords)
|
||||
for r in range(rmin, rmax + 1):
|
||||
s = ""
|
||||
for c in range(cmin, cmax + 1):
|
||||
if (r, c) in xs:
|
||||
s += "#"
|
||||
elif (r, c) in poss:
|
||||
s += "O"
|
||||
else:
|
||||
s += " "
|
||||
print(s)
|
||||
|
||||
def move(xs, roff, coff):
|
||||
rcoords = [x[0] for x in xs]
|
||||
ccoords = [x[1] for x in xs]
|
||||
rd = max(rcoords) - min(rcoords) + 3
|
||||
cd = max(ccoords) - min(ccoords) + 3
|
||||
newxs = [(x[0] + roff * rd, x[1] + coff * cd) for x in xs]
|
||||
return set(newxs)
|
||||
|
||||
def iter(poss, stones):
|
||||
nposs = set()
|
||||
for r, c in poss:
|
||||
for ro, co in [(-1, 0), (0, 1), (1, 0), (0, -1)]:
|
||||
nr, nc = r + ro, c + co
|
||||
if not (nr, nc) in stones:
|
||||
nposs.add((nr, nc))
|
||||
return nposs
|
||||
|
||||
def get_bounds(size, ro, co):
|
||||
rmin = size * ro
|
||||
rmax = size + size * ro
|
||||
cmin = size * co
|
||||
cmax = size + size * co
|
||||
return rmin, rmax, cmin, cmax
|
||||
|
||||
def count(poss, size, ro, co):
|
||||
rmin, rmax, cmin, cmax = get_bounds(size, ro, co)
|
||||
res = 0
|
||||
for (r, c) in poss:
|
||||
if (rmin <= r < rmax) and (cmin <= c < cmax):
|
||||
res += 1
|
||||
return res
|
||||
|
||||
def solve2(ip: Input):
|
||||
base_stones = set()
|
||||
poss = set()
|
||||
|
||||
size = len(ip.lines())
|
||||
assert size == len(ip.lines()[0])
|
||||
|
||||
for r, row in enumerate(ip.lines()):
|
||||
for c, col in enumerate(row):
|
||||
if col == "#":
|
||||
base_stones.add((r, c))
|
||||
if col == "S":
|
||||
poss.add((r, c))
|
||||
|
||||
stones = base_stones.copy()
|
||||
|
||||
off = 19 // 2
|
||||
for ro in range(-off, off + 1):
|
||||
for co in range(-off, off + 1):
|
||||
stones |= move(base_stones, ro, co)
|
||||
|
||||
|
||||
hists = {}
|
||||
for ro in range(-off, off + 1):
|
||||
for co in range(-off, off + 1):
|
||||
hists[(ro, co)] = []
|
||||
|
||||
#for step in range(590):
|
||||
# if step % 1 == 0:
|
||||
# sanity = 0
|
||||
# os.system("clear")
|
||||
# for ro in range(-off, off + 1):
|
||||
# s = ""
|
||||
# for co in range(-off, off + 1):
|
||||
# v = count(poss, size, ro, co)
|
||||
# sanity += v
|
||||
# if v > 0:
|
||||
# hists[(ro, co)].append(v)
|
||||
# s += f"{v:6}"
|
||||
# else:
|
||||
# s += 6 * " "
|
||||
# print(s)
|
||||
# # input(f"{step=} {step//size=} {len(poss)} ({sanity}) cont...")
|
||||
# print(f"{step=} {step//size=} {len(poss)} ({sanity}) cont...")
|
||||
# poss = iter(poss, stones)
|
||||
|
||||
# 66, 197, 328 459 # cycle starts
|
||||
# 196, 327, 458, 589 # targets
|
||||
def calc(len, xs):
|
||||
if len % 2 == 0:
|
||||
return len // 2 * sum(xs)
|
||||
else:
|
||||
return len // 2 * sum(xs) + xs[0]
|
||||
|
||||
target = 196
|
||||
target = 327
|
||||
target = 458
|
||||
target = 589
|
||||
target = 26501365
|
||||
# for target in [196, 327, 458, 589]:
|
||||
print()
|
||||
print(target)
|
||||
cycle = 131
|
||||
c = target // cycle
|
||||
d = (target // cycle) * 2 + 1 - 2
|
||||
print(f"{c=} {d=}")
|
||||
res = 0
|
||||
res += 5698 + 5703 + 5709 + 5704 # corners
|
||||
res += c * 964 + c * 984 + c * 968 + c * 978 # outer
|
||||
res += (c - 1) * 6637 + (c - 1) * 6624 + (c - 1) * 6643 + (c - 1) * 6619 # inner
|
||||
|
||||
for i in range(d, 0, -2):
|
||||
res += calc(i, [7623, 7558])
|
||||
|
||||
for i in range(d - 2, 0, -2):
|
||||
res += calc(i, [7623, 7558])
|
||||
|
||||
print(res)
|
||||
return res
|
||||
|
||||
# def get_till(xs, ts):
|
||||
# ts = ts[:]
|
||||
# r = []
|
||||
# for x in xs:
|
||||
# r.append(x)
|
||||
# if x in ts:
|
||||
# ts.remove(x)
|
||||
# if ts == []:
|
||||
# break
|
||||
# return r
|
||||
|
||||
osz_values = hists[(0, 4)][-2:]
|
||||
# se = get_till(hists[0, 5], osz_values)
|
||||
# sn = get_till(hists[-5, 0], osz_values)
|
||||
# ss = get_till(hists[5, 0], osz_values)
|
||||
# sw = get_till(hists[0, -5], osz_values)
|
||||
# print(se)
|
||||
# print(sn)
|
||||
# print(sw)
|
||||
# print(ss)
|
||||
|
||||
# sne = get_till(hists[-5, 5], osz_values)
|
||||
# sse = get_till(hists[5, 5], osz_values)
|
||||
# ssw = get_till(hists[5, -5], osz_values)
|
||||
# snw = get_till(hists[-5, -5], osz_values)
|
||||
# print(sne)
|
||||
# print(sse)
|
||||
# print(ssw)
|
||||
# print(snw)
|
||||
|
||||
# for i in range(3, 10):
|
||||
# print(hists[(0, i)][:5])
|
||||
# print(hists[(0, -i)][:5])
|
||||
|
||||
def main():
|
||||
DAY_INPUT = "i21.txt"
|
||||
|
||||
print("Example 1:", solve(Input(EXAMPLE)))
|
||||
print("Solution 1:", solve(Input(DAY_INPUT)))
|
||||
return
|
||||
|
||||
print("Example 2:", solve(Input(EXAMPLE), True))
|
||||
return
|
||||
|
||||
print("Solution 2:", solve(Input(DAY_INPUT), True))
|
||||
return
|
||||
# print("Example 1:", solve(Input(EXAMPLE)))
|
||||
# print("Solution 1:", solve(Input(DAY_INPUT)))
|
||||
# print("Example 2:", solve2(Input(EXAMPLE)))
|
||||
print("Solution 2:", solve2(Input(DAY_INPUT)))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
Reference in New Issue
Block a user