Kaynağa Gözat

🐷

master
Roderic Day 1 yıl önce
ebeveyn
işleme
795a9e67b0
3 değiştirilmiş dosya ile 107 ekleme ve 44 silme
  1. +1
    -1
      VERSION
  2. +65
    -43
      y2023/p18.py
  3. +41
    -0
      y2023/p19.py

+ 1
- 1
VERSION Dosyayı Görüntüle

@@ -1 +1 @@
🐷

+ 65
- 43
y2023/p18.py Dosyayı Görüntüle

@@ -1,6 +1,6 @@
def render(graph, default='.'):
xmin, *_, xmax = sorted(int(p.real) for p in walls)
ymin, *_, ymax = sorted(int(p.imag) for p in walls)
xmin, *_, xmax = sorted(int(p.real) for p in graph)
ymin, *_, ymax = sorted(int(p.imag) for p in graph)
out = ''
for y in range(ymin, ymax + 1):
for x in range(xmin, xmax + 1):
@@ -16,57 +16,79 @@ def connected_components(graph):
edge = {graph.pop()}
while edge:
seen |= edge
edge = {pp + ss for pp in edge for ss in [1, -1, 1j, -1j]} & graph - seen
edge = {pp + ss for pp in edge for ss in [1, -1, 1j, -1j] if pp + ss in graph if pp + ss not in seen}
groups.append(seen)
graph -= seen
return groups


text = open(0).read()
p2 = True
def get_solid(walls):
xmin, *_, xmax = sorted(int(p.real) for p in walls)
ymin, *_, ymax = sorted(int(p.imag) for p in walls)

mesh = {complex(x, y) for x in range(xmin, xmax + 1) for y in range(ymin, ymax + 1)}
void = mesh - walls
groups = connected_components(void)
border = lambda p: p.real in {xmin, xmax} or p.imag in {ymin, ymax}
inside = {p for g in groups if not any(border(p) for p in g) for p in g}
solid = inside | walls
return solid

walls = {0}
pos = 0
for line in text.splitlines():
d, n, rest = line.split()
if p2:

def solve1():
pos = 0
walls = {pos}
for line in text.splitlines():
d, n, _ = line.split()
dirx = 1j ** 'RDLU'.index(d)
goal = pos + dirx * int(n)
while pos != goal:
pos += dirx
walls.add(pos)
solid = get_solid(walls)
print(len(solid))


def solve2():
points = {0}
pos = 0
for line in text.splitlines():
_, _, rest = line.split()
n, d = int(rest[1:-1][1:][:5], 16), 'RDLU'[int(rest[-2])]
pos += {'R': 1, 'D': 1j, 'L': -1, 'U': -1j}[d] * int(n)
walls.add(pos)
dirx = 1j ** 'RDLU'.index(d)
pos += dirx * int(n)
points.add(pos)

b2s = {
complex(bx, by) + dx + dy: 3 * complex(sx, sy) + dx + dy
for sx, bx in enumerate(sorted({p.real for p in walls}))
for sy, by in enumerate(sorted({p.imag for p in walls}))
for dx in [-1, 0, 1] for dy in [-1j, 0, 1j]
}
b2s = {
complex(bx, by) + dx + dy: 3 * complex(sx, sy) + dx + dy
for sx, bx in enumerate(sorted({p.real for p in points}))
for sy, by in enumerate(sorted({p.imag for p in points}))
for dx in [-1, 0, 1] for dy in [-1j, 0, 1j]
}
s2b = {v: k for k, v in b2s.items()}

pos, smallpos = next(iter(b2s.items()))
walls = {smallpos}
for line in text.splitlines():
d, n, rest = line.split()
if p2:
pos, smallpos = 0, b2s[0]
walls = {smallpos}
for line in text.splitlines():
d, n, rest = line.split()
n, d = int(rest[1:-1][1:][:5], 16), 'RDLU'[int(rest[-2])]
dirx = {'R': 1, 'D': 1j, 'L': -1, 'U': -1j}[d]
pos += dirx * int(n)
goal = b2s[pos]
while smallpos != goal:
smallpos += dirx
walls.add(smallpos)
dirx = 1j ** 'RDLU'.index(d)
pos += dirx * int(n)
goal = b2s[pos]
while smallpos != goal:
smallpos += dirx
walls.add(smallpos)

xmin, *_, xmax = sorted(int(p.real) for p in b2s.values())
ymin, *_, ymax = sorted(int(p.imag) for p in b2s.values())
void = {complex(x, y) for x in range(xmin, xmax + 1) for y in range(ymin, ymax + 1)} - walls
groups = connected_components(void)
inside = {p for g in groups if not any(p.real in {xmin, xmax} or p.imag in {ymin, ymax} for p in g) for p in g}
solid = inside | walls
solid = get_solid(walls)

# print(render({k: '#' for k in solid}))
out = 0
for smallpos in solid:
c1, c2 = s2b[smallpos], s2b[smallpos + 1 + 1j]
w, h = (c2 - c1).real, (c2 - c1).imag
out += int(w * h)
print(out)

s2b = {v: k for k, v in b2s.items()}
out = 0
for smallpos in solid:
c1, c2 = s2b[smallpos], s2b[smallpos + 1 + 1j]
w, h = (c2 - c1).real, (c2 - c1).imag
out += int(w * h)
print(out)

text = open(0).read()
solve1()
solve2()

+ 41
- 0
y2023/p19.py Dosyayı Görüntüle

@@ -0,0 +1,41 @@
import math


def consume(cc, label, step):
if label in 'AR':
return label
else:
op, new = workflows[label][step]
if eval(op, None, cc):
return consume(cc, new, 0)
else:
return consume(cc, label, step + 1)


text = open(0).read()
aa, bb = text.split('\n\n')
workflows = {}
for line in aa.splitlines():
key, rest = line.split('{')
workflows[key] = [('True:' + ln).split(':')[-2:] for ln in rest[:-1].split(',')]

candidates = [{k[0]: int(k[2:]) for k in ln[1:-1].split(',')} for ln in bb.splitlines()]
print(sum(sum(cc.values()) for cc in candidates if consume(cc, 'in', 0) == 'A'))


def consume2(cc, label, step):
if label in 'AR':
yield math.prod(len(vs) for vs in cc.values()), label
else:
op, new = workflows[label][step]
if op == 'True':
yield from consume2(cc, new, 0)
else:
k = op[0]
vs = {v for v in cc[k] if eval(op, None, {k: v})}
yield from consume2(cc | {k: vs}, new, 0)
yield from consume2(cc | {k: cc[k] - vs}, label, step + 1)


bop = {k: set(range(1, 4000 + 1)) for k in 'xmas'}
print(sum(m for m, label in consume2(bop, 'in', 0) if label == 'A'))

Yükleniyor…
İptal
Kaydet