@@ -1,6 +1,7 @@ | |||
import collections | |||
import os | |||
import re | |||
import subprocess | |||
import sys | |||
from pathlib import Path | |||
@@ -61,3 +62,9 @@ def get_dat(): | |||
response = requests.get(url, cookies=cookies) | |||
response.raise_for_status() | |||
Path(path).write_bytes(response.content) | |||
def md5(strings): | |||
cmd = ['md5'] + [c for s in strings for c in ['-s', s]] | |||
out = subprocess.check_output(cmd).decode() | |||
return re.findall(r'"(.+)"\) = (.+)', out) |
@@ -0,0 +1,18 @@ | |||
import re | |||
import sys | |||
pos = 0 | |||
ori = 1 | |||
seen = set() | |||
ans2 = None | |||
for turn, steps in re.findall(r'(R|L)(\d+)', sys.stdin.read()): | |||
ori *= {'R': 1j, 'L': -1j}[turn] | |||
for _ in range(int(steps)): | |||
pos += ori | |||
if ans2 is None and pos in seen: | |||
ans2 = abs(pos.real) + abs(pos.imag) | |||
seen.add(pos) | |||
ans1 = abs(pos.real) + abs(pos.imag) | |||
print(ans1) | |||
print(ans2) |
@@ -0,0 +1,31 @@ | |||
import sys | |||
import toolkit | |||
def travel(text, start, image): | |||
grid, _, _ = toolkit.read_image(image) | |||
pos = {v: k for k, v in grid.items()}[start] | |||
for line in text.splitlines(): | |||
for step in map(moves.get, line): | |||
if grid[pos + step].strip(): | |||
pos += step | |||
yield grid[pos] | |||
text = sys.stdin.read() | |||
moves = {'U': -1j, 'L': -1, 'R': 1, 'D': 1j} | |||
keypad1 = ''' | |||
123 | |||
456 | |||
789 | |||
''' | |||
keypad2 = ''' | |||
1 | |||
234 | |||
56789 | |||
ABC | |||
D | |||
''' | |||
print(''.join(travel(text, '5', keypad1))) | |||
print(''.join(travel(text, '7', keypad2))) |
@@ -0,0 +1,19 @@ | |||
import sys | |||
grid = [line.split() for line in sys.stdin.readlines()] | |||
ans1 = 0 | |||
for line in grid: | |||
a, b, c = sorted(map(int, line)) | |||
ans1 += a + b > c | |||
print(ans1) | |||
ans2 = 0 | |||
for col in zip(*grid): | |||
for line in zip(*[iter(col)] * 3): | |||
a, b, c = sorted(map(int, line)) | |||
ans2 += a + b > c | |||
print(ans2) |
@@ -0,0 +1,25 @@ | |||
import re | |||
import sys | |||
from collections import Counter | |||
def decode(string, n): | |||
def replacer(match): | |||
char = match.group(0) | |||
return chr((ord(char) + n - ord('a')) % 26 + ord('a')) | |||
return re.sub(r'\w', replacer, string) | |||
text = sys.stdin.read() | |||
ans1 = 0 | |||
for line in text.splitlines(): | |||
name, sid, checksum = re.match(r'^(.+)-(\d+)\[(.+)\]$', line).groups() | |||
by_count = ''.join(dict(Counter(sorted(name)).most_common())) | |||
calc = by_count.replace('-', '')[:5] | |||
if calc == checksum: | |||
ans1 += int(sid) | |||
decoded = decode(name, int(sid)) | |||
if 'north' in decoded: | |||
ans2 = sid | |||
print(ans1) | |||
print(ans2) |
@@ -0,0 +1,21 @@ | |||
import itertools | |||
import sys | |||
import toolkit | |||
text = sys.stdin.read().strip() | |||
password1 = [] | |||
password2 = ['_' for _ in range(8)] | |||
for i in itertools.count(): | |||
strings = [f'{text}{1000 * i + k}' for k in range(1000)] | |||
for string, digest in toolkit.md5(strings): | |||
if digest.startswith('00000'): | |||
print(string, digest) | |||
password1.append(digest[5]) | |||
if digest[5] in '01234567' and password2[int(digest[5])] == '_': | |||
password2[int(digest[5])] = digest[6] | |||
if len(password1) >= 8 and '_' not in password2: | |||
break | |||
print(''.join(password1[:8])) | |||
print(''.join(password2[:8])) |