-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.py
115 lines (97 loc) · 3.01 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
from typing import *
from collections import *
from datetime import *
from itertools import *
from functools import *
from contextlib import *
import re
import operator as op
import heapq
from pprint import pprint
import requests
from datetime import datetime
from bs4 import BeautifulSoup
from dataclasses import dataclass, replace as dataclass_replace
import copy
import math
import time
today = datetime.now()
def read(name):
with open(name) as f:
return [l.strip() for l in f.readlines()]
def to_data(txt):
return [l.strip() for l in txt.split('\n')]
def get_todays_input(session, year=0, day=0):
year = year or today.year
day = day or today.day
url = f'https://adventofcode.com/{year}/day/{day}/input'
cache = f'data/{year}.{day}.{session[-3:]}.input'
try:
with open(cache, 'r') as f:
return f.read()
except FileNotFoundError:
response = requests.get(url, cookies={'session': session})
with open(cache, 'w') as f:
f.write(response.text)
return response.text
def get_all_ints(line):
return [int(x) for x in re.findall('-?\d+', line)]
def submit_todays_answer(session, level, answer, year=0, day=0):
year = year or today.year
day = day or today.day
url = f'https://adventofcode.com/{year}/day/{day}/answer'
data = { 'level': level, 'answer': answer }
response = requests.post(url, data, cookies={'session': session})
root = BeautifulSoup(response.text, 'html.parser')
print(root.find('main').text.strip())
@singledispatch
def print_grid(grid: dict, empty='.'):
startx = min(x for x, y in grid)
starty = min(y for x, y in grid)
stopx = 1 + max(x for x, y in grid)
stopy = 1 + max(y for x, y in grid)
print('\n'.join(''.join(grid.get((x, y), empty) for x in range(startx, stopx)) for y in range(starty, stopy)))
@singledispatch
def print_cgrid(grid: dict, empty='.'):
startx = min(int(p.real) for p in grid)
starty = min(int(p.imag) for p in grid)
stopx = 1 + max(int(p.real) for p in grid)
stopy = 1 + max(int(p.imag) for p in grid)
print('\n'.join(''.join(grid.get(x + 1j*y, empty) for x in range(startx, stopx)) for y in range(starty, stopy)))
@print_grid.register
def print_grid_list(grid: list):
print('\n'.join(''.join(cell for cell in row) for row in grid))
def timing(f):
'''Usage:
@timing
def main(...):
...
'''
@wraps(f)
def wrap(*args, **kw):
ts = time.process_time_ns()
yield from f(*args, **kw)
te = time.process_time_ns()
print(f'Elapsed: {(te - ts) * 1e-9:.2f} CPU sec')
return wrap
ops = {
'+': op.add,
'*': op.mul,
'-': op.sub,
'/': op.truediv,
}
from aoc_ocr import aoc_ocr_data, width, height
def aoc_ocr(text, *, fill='#', blank='.'):
text = text.replace(fill, '#').replace(blank, '.')
lines = text.split('\n')
w = len(lines[0])
h = len(lines)
assert h == height and all(len(l) == w for l in lines)
return ''.join(
aoc_ocr_data[
'\n'.join(l[start:start+4] for l in lines)
]
for start in range(0, w, width + 1)
)
# data/sessions.py: sessions = ['...']
from data.sessions import sessions