Browse Source

see ya, space cowgirl

master
Roderic Day 3 years ago
parent
commit
9c839848db
10 changed files with 210 additions and 3 deletions
  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 View File

import builtins import builtins
import collections import collections
import functools
import hashlib import hashlib
import itertools
import importlib import importlib
import itertools
import math import math
import operator
import os import os
import re import re
import string import string
import requests 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): def lcm(a, b):
data_file = Path(sys.argv[1]).with_suffix('.dat') data_file = Path(sys.argv[1]).with_suffix('.dat')
ensure_data(data_file) ensure_data(data_file)
builtins.df = data_file builtins.df = data_file
builtins.text = data_file.read_text()
builtins.string = string builtins.string = string
builtins.re = re builtins.re = re
rel = re.sub(r'.+(y\d+)/(p\d+).+', r'\1.\2', os.environ['FILE']) rel = re.sub(r'.+(y\d+)/(p\d+).+', r'\1.\2', os.environ['FILE'])

+ 19
- 0
y2015/p12.py View File

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 View File

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 View File

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 View File

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 View File

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 View File

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 View File

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 View File

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 View File

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])

Loading…
Cancel
Save