Просмотр исходного кода

refactor + no precommit

master
Roderic Day 3 лет назад
Родитель
Сommit
e5703e5302
13 измененных файлов: 184 добавлений и 53 удалений
  1. +1
    -0
      .gitignore
  2. +3
    -7
      makefile
  3. +23
    -8
      toolkit.py
  4. +1
    -6
      y2015/p01.py
  5. +1
    -6
      y2015/p02.py
  6. +1
    -6
      y2015/p03.py
  7. +10
    -13
      y2015/p04.py
  8. +1
    -7
      y2015/p05.py
  9. +0
    -0
      y2015/p06.py
  10. +29
    -0
      y2015/p07.py
  11. +49
    -0
      y2016/p24.py
  12. +15
    -0
      y2018/p05.py
  13. +50
    -0
      y2020/p98.py

+ 1
- 0
.gitignore Просмотреть файл

.DS_Store .DS_Store
venv/ venv/
.env .env
*.js

+ 3
- 7
makefile Просмотреть файл

include .env include .env
FILE = $(shell find . -path "./y????/p??.py" -type f | xargs ls -rt | tail -n 1) FILE = $(shell find . -path "./y????/p??.py" -type f | xargs ls -rt | tail -n 1)
DATA = $(shell echo $(FILE) | sed -e s/\.py/\.dat/)
PYTHONPATH = . PYTHONPATH = .
export export


main: venv/ $(DATA) main: venv/ $(DATA)
@cat $(DATA) | venv/bin/python -u $(FILE)
venv/bin/python -u toolkit.py $(FILE)


flake: venv/ flake: venv/
venv/bin/flake8 --exclude=venv/ venv/bin/flake8 --exclude=venv/


$(DATA):
@echo $(DATA) | venv/bin/python -c "import toolkit; toolkit.get_dat()" $(DATA)

venv/: requirements.txt venv/: requirements.txt
rm -rf venv/ rm -rf venv/
~/.pyenv/versions/3.8.0/bin/python -m venv venv ~/.pyenv/versions/3.8.0/bin/python -m venv venv
venv/bin/pip install -r requirements.txt venv/bin/pip install -r requirements.txt
touch requirements.txt venv/ touch requirements.txt venv/
# install flake8 git hook # install flake8 git hook
echo 'venv/bin/flake8 --exclude=venv/' > .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
# echo 'venv/bin/flake8 --exclude=venv/' > .git/hooks/pre-commit
# chmod +x .git/hooks/pre-commit

+ 23
- 8
toolkit.py Просмотреть файл

import builtins
import collections import collections
import hashlib import hashlib
import itertools import itertools
import importlib
import math import math
import os import os
import re import re
import string
import sys import sys
from pathlib import Path from pathlib import Path


return path[::-1] return path[::-1]




def get_dat():
path = sys.argv[1]
year, qn = map(int, re.findall(r'\d+', sys.argv[1]))
url = f'https://adventofcode.com/{year}/day/{qn}/input'
cookies = {'session': os.environ['SESSION']}
response = requests.get(url, cookies=cookies)
response.raise_for_status()
Path(path).write_bytes(response.content)
def ensure_data(path):
if not path.exists():
year, qn = map(int, re.findall(r'\d+', sys.argv[1]))
url = f'https://adventofcode.com/{year}/day/{qn}/input'
cookies = {'session': os.environ['SESSION']}
response = requests.get(url, cookies=cookies)
response.raise_for_status()
path.write_bytes(response.content)




def batch(iterable, size): def batch(iterable, size):
count += 1 count += 1
else: else:
raise RuntimeError('Reached steady state') raise RuntimeError('Reached steady state')


if __name__ == '__main__':
data_file = Path(sys.argv[1]).with_suffix('.dat')
ensure_data(data_file)
builtins.data_file = data_file
builtins.string = string
builtins.re = re
rel = re.sub(r'.+(y\d+)/(p\d+).+', r'\1.\2', os.environ['FILE'])
mod = importlib.import_module(rel)
print(getattr(mod, 'ans1', None))
print(getattr(mod, 'ans2', None))

+ 1
- 6
y2015/p01.py Просмотреть файл

import sys


ans1 = 0 ans1 = 0
ans2 = None ans2 = None
for i, char in enumerate(sys.stdin.read(), 1):
for i, char in enumerate(data_file.read_text(), 1):
ans1 += {'(': 1, ')': -1}[char] ans1 += {'(': 1, ')': -1}[char]
if ans1 == -1 and ans2 is None: if ans1 == -1 and ans2 is None:
ans2 = i ans2 = i
print(ans1)
print(ans2)

+ 1
- 6
y2015/p02.py Просмотреть файл

import sys


ans1 = 0 ans1 = 0
ans2 = 0 ans2 = 0
for line in sys.stdin.readlines():
for line in data_file.read_text().splitlines():
a, b, c = sorted(map(int, line.split('x'))) a, b, c = sorted(map(int, line.split('x')))
ans1 += 2 * (a * b + b * c + a * c) + a * b ans1 += 2 * (a * b + b * c + a * c) + a * b
ans2 += a * b * c + 2 * (a + b) ans2 += a * b * c + 2 * (a + b)
print(ans1)
print(ans2)

+ 1
- 6
y2015/p03.py Просмотреть файл

import sys
from itertools import accumulate as acc from itertools import accumulate as acc




text = sys.stdin.read()
text = data_file.read_text()
dirs = dict(zip('<>^v', [-1, 1, -1j, 1j])) dirs = dict(zip('<>^v', [-1, 1, -1j, 1j]))

ans1 = len({*acc(map(dirs.get, text))}) ans1 = len({*acc(map(dirs.get, text))})
print(ans1)

ans2 = len({*acc(map(dirs.get, text[::2])), *acc(map(dirs.get, text[1::2]))}) ans2 = len({*acc(map(dirs.get, text[::2])), *acc(map(dirs.get, text[1::2]))})
print(ans2)

+ 10
- 13
y2015/p04.py Просмотреть файл

import sys
from hashlib import md5 from hashlib import md5
from multiprocessing import Pool from multiprocessing import Pool


return i, hasher.hexdigest() return i, hasher.hexdigest()




if __name__ == '__main__':
code = sys.stdin.read().strip()
ans1 = None
ans2 = None
with Pool() as pool:
for i, coin in pool.starmap(mine, [(code, i) for i in range(10**7)]):
if ans1 is None and coin.startswith('00000'):
ans1 = i
if ans2 is None and coin.startswith('000000'):
ans2 = i
print(ans1)
print(ans2)
code = data_file.read_text().strip()
ans1 = None
ans2 = None
for i in range(10**7):
i, coin = mine(code, i)
if ans1 is None and coin.startswith('00000'):
ans1 = i
if ans2 is None and coin.startswith('000000'):
ans2 = i
break

+ 1
- 7
y2015/p05.py Просмотреть файл

import re
import sys


def checks1(string): def checks1(string):
yield len(re.findall(r'([aeiou])', string)) >= 3 yield len(re.findall(r'([aeiou])', string)) >= 3
yield len(re.findall(r'(.)\1', string)) yield len(re.findall(r'(.)\1', string))


ans1 = 0 ans1 = 0
ans2 = 0 ans2 = 0
for line in sys.stdin.read().splitlines():
for line in data_file.read_text().splitlines():
ans1 += all(checks1(line)) ans1 += all(checks1(line))
ans2 += all(checks2(line)) ans2 += all(checks2(line))
print(ans1)
print(ans2)

+ 0
- 0
y2015/p06.py Просмотреть файл


+ 29
- 0
y2015/p07.py Просмотреть файл

def pythonize(string):
op, out = (
re.sub(r'([a-z]+)', r'\1_', string)
.replace('AND', '&')
.replace('OR', '|')
.replace('NOT ', '~')
.replace('RSHIFT', '>>')
.replace('LSHIFT', '<<')
).split(' -> ')
return f'{out} = {op}'


def process(instructions, registers={}):
while instructions:
curr, *instructions = instructions
out = curr.split()[0]
if out in registers:
continue
try:
exec(curr, None, registers)
except NameError:
instructions.append(curr)
return registers


inp = [pythonize(string) for string in data_file.read_text().splitlines()]
found = process(inp.copy())
ans1 = found['a_']
ans2 = process(inp.copy(), {'b_': ans1})['a_']

+ 49
- 0
y2016/p24.py Просмотреть файл

import sys
from itertools import permutations


text = sys.stdin.read()


# transform text into data structures
valid = set()
target = {}
for y, line in enumerate(text.splitlines()):
for x, char in enumerate(line):
if char == '#':
continue
valid.add(x + 1j * y)
if char != '.':
target[x + 1j * y] = char


# generate travel map
graph = {}
for A in target:
seen = {A}
boundary = {A}
pending = set(target) - seen
N = 0
while pending:
N += 1
boundary = {pos + step for pos in boundary for step in [1, -1, 1j, -1j]}
boundary &= valid - seen
seen.update(boundary)

for B in boundary & pending:
pending -= {B}
graph[target[A], target[B]] = N


# use map to determine routes
calc = lambda combo: sum(graph[pair] for pair in zip(combo, combo[1:]))

z = '0'
rest = set(target.values()) - {z}
options = [(z,) + combo for combo in permutations(rest)]
ans = min(options, key=calc)
print(calc(ans))

options = [(z,) + combo + (z,) for combo in permutations(rest)]
ans = min(options, key=calc)
print(calc(ans))

+ 15
- 0
y2018/p05.py Просмотреть файл

inp = data_file.read_text().strip()
out = {}
for a in [''] + list(string.ascii_lowercase):
text = inp.replace(a, '').replace(a.swapcase(), '')
stack1 = list(text)
stack2 = []
while stack1:
x = stack1.pop()
if stack2 and x.swapcase() == stack2[-1]:
y = stack2.pop()
else:
stack2.append(x)
out[a] = len(stack2)
ans1 = out['']
ans2 = min(out.values())

+ 50
- 0
y2020/p98.py Просмотреть файл

import collections
import itertools
import re
import sys


txt = '''90342 ;2 correct
70794 ;0 correct
39458 ;2 correct
34109 ;1 correct
51545 ;2 correct
12531 ;1 correct
''' # 39542 is unique
txt = sys.stdin.read()


exclusions = collections.defaultdict(set)
clues = []
for string, n in re.findall(r'(\d+) ;(\d)', txt):
choices = set(enumerate(string))
combos = [frozenset(cs) for cs in itertools.combinations(choices, int(n))]
for combo in combos:
exclusions[combo] |= (choices - combo)
if int(n):
clues.append(combos)


for pos in range(len(string)):
choices = {(pos, char) for char in '0123456789'}
for choice in choices:
exclusions[frozenset({choice})] |= (choices - {choice})


def solve(clues_left, known=frozenset()):
if not clues_left:
avail = {a for gr in exclusions for a in gr}
avail -= {v for k, vs in exclusions.items() if k <= known for v in vs}
yield ''.join(c for _, c in sorted(avail))

else:
choices = min(clues_left, key=len)
for choice in choices:
chosen = known | choice
bads = {v for k, vs in exclusions.items() if k <= chosen for v in vs}
mods = [[c for c in cl if not c & bads] for cl in clues_left if cl != choices]
yield from solve(mods, chosen)


solution = next(solve(clues))
print(solution)

Загрузка…
Отмена
Сохранить