소스 검색

🍊

master
Roderic Day 1 년 전
부모
커밋
4bfa0b3026
3개의 변경된 파일77개의 추가작업 그리고 1개의 파일을 삭제
  1. +1
    -1
      VERSION
  2. +27
    -0
      y2023/p21.py
  3. +49
    -0
      y2023/p22.py

+ 1
- 1
VERSION 파일 보기

@@ -1 +1 @@
🚌
🍊

+ 27
- 0
y2023/p21.py 파일 보기

@@ -0,0 +1,27 @@
text = open(0).read()
graph = {
complex(x, y): val
for y, row in enumerate(text.splitlines())
for x, val in enumerate(row)
}
width = max(int(p.real) for p in graph) + 1
height = max(int(p.imag) for p in graph) + 1

wrap = lambda p: complex(p.real % width, p.imag % height)
start, = (k for k, v in graph.items() if v == 'S')
state = {(False, start)}
seen = state.copy()
for step in range(100):
state = {
(not age, p + s)
for age, p in state
for s in [1, -1, 1j, -1j]
if graph[wrap(p + s)] in {'.', 'S'}
if (not age, p + s) not in seen
}
seen |= state

if step == 64:
ans1 = sum(not age for age, pos in seen if pos in graph)
print(ans1)


+ 49
- 0
y2023/p22.py 파일 보기

@@ -0,0 +1,49 @@
@lambda fn: lambda brick: set(fn(brick))
def dimension(brick):
(x1, x2), (y1, y2), (z1, z2) = map(sorted, zip(*brick))
for z in range(z1, z2 + 1):
for y in range(y1, y2 + 1):
for x in range(x1, x2 + 1):
yield x, y, z


def tetris(bricks):
floor = {(x, y, 0) for x in range(100) for y in range(100)}
seen = floor
for brick in map(dimension, bricks):
while not seen & brick:
brick = {(x, y, z - 1) for x, y, z in brick}
resting_place = {(x, y, z + 1) for x, y, z in brick}
seen |= resting_place
yield resting_place


def topple(i, depends_on, holds_up):
gone = set()
state = {i}
while state:
gone |= state
state = {above
for below in state
for above in depends_on.get(below, [])
if holds_up[above] <= gone
}
return gone - {i}


text = open(0).read()
bricks = [[[int(n) for n in sub.split(',')] for sub in line.split('~')] for line in text.splitlines()]
bricks.sort(key=lambda brick: min(z for x, y, z in brick))
bricks = list(tetris(bricks))

known = {i for i, _ in enumerate(bricks)}
holds_up, depends_on = {}, {}
for j, brick in enumerate(bricks):
j_brick_1_down = {(x, y, z - 1) for x, y, z in brick}
holds_up[j] = {i for i, i_brick in enumerate(bricks) if i != j and j_brick_1_down & i_brick}
for i in holds_up[j]:
depends_on.setdefault(i, set()).add(j)

needed = {v for k, vs in holds_up.items() if len(vs) == 1 for v in vs}
print(len(known - needed))
print(sum(len(topple(i, depends_on, holds_up)) for i in needed))

Loading…
취소
저장