Bladeren bron

see ya, space cowgirl

master
Roderic Day 3 jaren geleden
bovenliggende
commit
9c839848db
10 gewijzigde bestanden met toevoegingen van 210 en 3 verwijderingen
  1. +5
    -3
      toolkit.py
  2. +19
    -0
      y2015/p12.py
  3. +20
    -0
      y2015/p13.py
  4. +16
    -0
      y2015/p14.py
  5. +19
    -0
      y2015/p15.py
  6. +24
    -0
      y2015/p16.py
  7. +14
    -0
      y2015/p17.py
  8. +24
    -0
      y2015/p18.py
  9. +19
    -0
      y2015/p19.py
  10. +50
    -0
      y2015/p21.py

+ 5
- 3
toolkit.py Bestand weergeven

@@ -1,9 +1,11 @@
import builtins
import collections
import functools
import hashlib
import itertools
import importlib
import itertools
import math
import operator
import os
import re
import string
@@ -13,8 +15,7 @@ from pathlib import Path
import requests


def integers(line):
return [int(n) for n in re.findall(r'\d+', line)]
product = functools.partial(functools.reduce, operator.mul)


def lcm(a, b):
@@ -106,6 +107,7 @@ if __name__ == '__main__':
data_file = Path(sys.argv[1]).with_suffix('.dat')
ensure_data(data_file)
builtins.df = data_file
builtins.text = data_file.read_text()
builtins.string = string
builtins.re = re
rel = re.sub(r'.+(y\d+)/(p\d+).+', r'\1.\2', os.environ['FILE'])

+ 19
- 0
y2015/p12.py Bestand weergeven

@@ -0,0 +1,19 @@
import json


def recurse(data, avoid=None):
type_ = type(data)
if type_ is int:
return data
elif type_ is str:
return 0
elif type_ is list:
return sum(recurse(el, avoid) for el in data)
elif type_ is dict:
if any(val == avoid for val in data.values()): return 0
return sum(recurse(value, avoid) for key, value in data.items())


data = json.loads(df.read_text())
ans1 = recurse(data)
ans2 = recurse(data, 'red')

+ 20
- 0
y2015/p13.py Bestand weergeven

@@ -0,0 +1,20 @@
import collections
import itertools


happiness = collections.defaultdict(int)
people = set()
for line in df.read_text().splitlines():
A, verb, N, B = re.findall(r'([A-Z][a-z]+|gain|lose|\d+)', line)
happiness[A, B] = int(N) if verb == 'gain' else -int(N)
people.update({A, B})


def calc(seq):
return sum(happiness[b, a] + happiness[b, c]
for a, b, c in zip(seq[-1:] + seq[:-1], seq, seq[1:] + seq[:1])
)


ans1 = max(calc(combo) for combo in itertools.permutations(people))
ans2 = max(calc(combo) for combo in itertools.permutations(people | {'me'}))

+ 16
- 0
y2015/p14.py Bestand weergeven

@@ -0,0 +1,16 @@
import collections
import itertools


reindeers = [
itertools.accumulate(itertools.cycle([speed] * act + [0] * rest))
for line in df.read_text().splitlines()
for speed, act, rest in [map(int, re.findall(r'\d+', line))]
]


traveled = [[next(rr) for _ in range(2503)] for rr in reindeers]
transpose = list(zip(*traveled))
ans1 = max(transpose[-1])
points = [[d == max(dsts) for d in dsts] for dsts in transpose]
ans2 = max(sum(pts) for pts in zip(*points))

+ 19
- 0
y2015/p15.py Bestand weergeven

@@ -0,0 +1,19 @@
from toolkit import product


def combine(qtys):
return [max(0, sum(a * b for a, b in zip(qtys, vs))) for vs in zip(*data)]


data = [
[int(n) for n in re.findall(r'-?\d+', ln)]
for ln in df.read_text().splitlines()
]
qtys = [
combine([A, B, C, 100 - A - B - C])
for A in range(101)
for B in range(101 - A)
for C in range(101 - A - B)
]
ans1 = max(product(combo[:-1]) for combo in qtys)
ans2 = max(product(combo[:-1]) for combo in qtys if combo[-1] == 500)

+ 24
- 0
y2015/p16.py Bestand weergeven

@@ -0,0 +1,24 @@
known = {
'children': 3,
'cats': 7,
'samoyeds': 2,
'pomeranians': 3,
'akitas': 0,
'vizslas': 0,
'goldfish': 5,
'trees': 3,
'cars': 2,
'perfumes': 1,
}
for line in df.read_text().splitlines():
sue, N, *rest = re.findall(r'\w+', line)
stuff = {k: int(v) for k, v in zip(rest[::2], rest[1::2])}
if all(known[k] == stuff[k] for k in stuff):
ans1 = N
if all(
known[k] < stuff[k] if k in {'cats', 'trees'}
else known[k] > stuff[k] if k in {'pomeranians', 'goldfish'}
else known[k] == stuff[k]
for k in stuff):
ans2 = N


+ 14
- 0
y2015/p17.py Bestand weergeven

@@ -0,0 +1,14 @@
def recurse(pending, opts, chain=tuple()):
if pending == 0:
yield chain
else:
for i, opt in enumerate(opts):
yield from recurse(pending - opt, opts[i + 1:], chain + (opt,))


ns = sorted([int(n) for n in df.read_text().splitlines()], reverse=True)
opts = list(recurse(150, ns))
ans1 = len(opts)

min_n = min(map(len, opts))
ans2 = sum(len(opt) == min_n for opt in opts)

+ 24
- 0
y2015/p18.py Bestand weergeven

@@ -0,0 +1,24 @@
def condition(x, y, on):
is_on = (x, y) in on
neighbours_on = sum(
(x + dx, y + dy) in on
for dx in [1, 0, -1] for dy in [1, 0, -1]
if dx or dy
)
return (is_on and neighbours_on in {2, 3}) or neighbours_on == 3


on1 = {
(x, y)
for y, ln in enumerate(df.read_text().splitlines())
for x, ch in enumerate(ln)
if ch == '#'
}
on2 = set(on1)
grid = {(x, y) for x in range(100) for y in range(100)}
corners = {(0, 0), (0, 99), (99, 0), (99, 99)}
for _ in range(100):
on1 = {(x, y) for x, y in grid if condition(x, y, on1)}
on2 = {(x, y) for x, y in grid if condition(x, y, on2)} | corners
ans1 = len(on1)
ans2 = len(on2)

+ 19
- 0
y2015/p19.py Bestand weergeven

@@ -0,0 +1,19 @@
pre, seq = text.strip().split('\n\n')
formulas = re.findall(r'(\w+) => (\w+)', pre)


ans1 = len({
seq[:match.start()] + seq[match.start():].replace(key, val, 1)
for key, val in formulas
for match in re.finditer(key, seq)
})


ops = formulas
ans2 = 0
while seq != 'e':
ans2 += 1
for k, v in ops:
if v in seq:
seq = seq.replace(v, k, 1)
break

+ 50
- 0
y2015/p21.py Bestand weergeven

@@ -0,0 +1,50 @@
import itertools


def is_win(p_hp, p_atk, p_def, b_hp, b_atk, b_def):
while True:
b_hp -= max(1, p_atk - b_def)
if b_hp <= 0:
return True
p_hp -= max(1, b_atk - p_def)
if p_hp <= 0:
return False


weapons = [
(8, 4, 0),
(10, 5, 0),
(25, 6, 0),
(40, 7, 0),
(74, 8, 0),
]
armors = [
(0, 0, 0),
(13, 0, 1),
(31, 0, 2),
(53, 0, 3),
(75, 0, 4),
(102, 0, 5),
]
rings = [
(0, 0, 0),
(0, 0, 0),
(25, 1, 0),
(50, 2, 0),
(100, 3, 0),
(20, 0, 1),
(40, 0, 2),
(80, 0, 3),
]
opts = [
[sum(vs) for vs in zip(*[w, a, r1, r2])]
for w, a in itertools.product(weapons, armors)
for r1, r2 in itertools.combinations(rings, 2)
]
p_hp = 100
b_hp, b_atk, b_def = map(int, re.findall(r'(\d+)', text))
wins = {True: set(), False: set()}
for cost, p_atk, p_def in opts:
wins[is_win(p_hp, p_atk, p_def, b_hp, b_atk, b_def)].add(cost)
ans1 = min(wins[True])
ans2 = max(wins[False])

Laden…
Annuleren
Opslaan