Roderic Day 2年前
コミット
08d36b5e5f
3個のファイルの変更97行の追加24行の削除
  1. +25
    -24
      y2022/p11.py
  2. +48
    -0
      y2022/p12.py
  3. +24
    -0
      y2022/p13.py

+ 25
- 24
y2022/p11.py ファイルの表示

@@ -1,41 +1,42 @@
import functools
import operator
import re
from collections import namedtuple
from math import prod


class Monkey:
def make_monkey(description):
relevant = re.findall(r'\d+|old|\*|\+', description)
parsed = [int(n) if n.isdigit() else n for n in relevant]
_, *items, _, op, y, div, aa, bb = parsed

def __init__(self, description):
relevant = re.findall(r'\d+|old|\*|\+', description)
parsed = [int(n) if n.isdigit() else n for n in relevant]
self.idx, *self.items, _, op, op_arg, self.div, aa, bb = parsed
op = {'*': operator.mul, '+': operator.add}[op]
self.fn = lambda x: op(x, x if op_arg == 'old' else op_arg)
self.target = lambda x: aa if x % self.div == 0 else bb
op = {'*': operator.mul, '+': operator.add}[op]
grow_item = lambda x: op(x, x if y == 'old' else y)
find_target = lambda x: aa if x % div == 0 else bb
return Monkey(items, grow_item, find_target)

def __repr__(self):
return f'Monkey_{self.idx}({self.items})'


def play(monkeys, n_rounds, act):
def play(monkeys, n_rounds, shrink):
counts = [0 for _ in monkeys]
for _ in range(n_rounds):
for monkey in monkeys:
for idx, monkey in enumerate(monkeys):
while monkey.items:
counts[monkey.idx] += 1
item = act(monkey, monkey.items.pop())
monkeys[monkey.target(item)].items.append(item)
yy, zz = sorted(counts)[-2:]
return yy * zz
counts[idx] += 1
item = monkey.items.pop()
item = monkey.grow_item(item)
item = shrink(item)
idx = monkey.find_target(item)
monkeys[idx].items.append(item)
return prod(sorted(counts)[-2:])


text = open(0).read()
Monkey = namedtuple('Monkey', ['items', 'grow_item', 'find_target'])

monkeys = [Monkey(descr) for descr in text.strip().split('\n\n')]
ans1 = play(monkeys, 20, lambda m, i: int(m.fn(i) / 3))
monkeys = [make_monkey(descr) for descr in text.strip().split('\n\n')]
ans1 = play(monkeys, 20, lambda x: x // 3)
print(ans1)

monkeys = [Monkey(descr) for descr in text.strip().split('\n\n')]
lim = functools.reduce(operator.mul, [m.div for m in monkeys])
ans2 = play(monkeys, 10_000, lambda m, i: m.fn(i) % lim)
lim = prod(map(int, re.findall(r'divisible by (\d+)', text)))
monkeys = [make_monkey(descr) for descr in text.strip().split('\n\n')]
ans2 = play(monkeys, 10_000, lambda x: x % lim)
print(ans2)

+ 48
- 0
y2022/p12.py ファイルの表示

@@ -0,0 +1,48 @@
def parse_grid(text):
grid = {}
for y, row in enumerate(text):
for x, v in enumerate(row):
grid[complex(x, y)] = v if v in 'SE' else ord(v)
return grid


def print_grid(mapping):
xmin, *_, xmax = {int(p.real) for p in mapping}
ymin, *_, ymax = {int(p.imag) for p in mapping}
for y in range(ymin, ymax + 1):
for x in range(xmin, xmax + 1):
print(mapping.get(complex(x, y), ' '), end=' ')
print()


def shortest_path(starts, ends, evolve):
starts = {k: [k] for k in starts}
known = starts.copy()
while starts:
old = list(starts)[0]
path = starts.pop(old)
starts |= {new: path + [new] for new in evolve(old) if new not in known}
known |= starts
for final in set(starts) & set(ends):
# print_grid({k: '.' for k in known[final]})
return known[final]


def main():
text = open(0).read().splitlines()
grid = parse_grid(text)

rev = {v: k for k, v in grid.items()}
start, end = rev['S'], rev['E']
grid[start], grid[end] = ord('a'), ord('z')

dof = [1, -1, 1j, -1j]
evolve = lambda old: {old + step for step in dof if is_valid(old, step)}
is_valid = lambda old, step: old + step in grid and grid[old + step] - grid[old] <= 1

print(len(shortest_path({start}, {end}, evolve)) - 1)
starts = {k for k, v in grid.items() if v == ord('a')}
print(len(shortest_path(starts, {end}, evolve)) - 1)


main()

+ 24
- 0
y2022/p13.py ファイルの表示

@@ -0,0 +1,24 @@
from functools import cmp_to_key


def cmp(aa, bb):
match aa, bb:
case int(), int():
return (aa > bb) - (aa < bb)
case int(), list():
return cmp([aa], bb)
case list(), int():
return cmp(aa, [bb])
case list(), list():
fallback = cmp(len(aa), len(bb))
return next((res for res in map(cmp, aa, bb) if res), fallback)


text = open(0).read()
pairs = [[eval(ln) for ln in block.splitlines()] for block in text.strip().split('\n\n')]
print(sum(i for i, (aa, bb) in enumerate(pairs, 1) if cmp(aa, bb) == -1))

x, y = [2], [6]
entries = sum(pairs, [x, y])
entries.sort(key=cmp_to_key(cmp))
print(entries.index(x) * entries.index(y))

読み込み中…
キャンセル
保存