diff --git a/day03.py b/day03.py index da67229..7a852d8 100644 --- a/day03.py +++ b/day03.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 +from functools import cache + up = lambda v: (v[0], v[1] + 1) down = lambda v: (v[0], v[1] - 1) left = lambda v: (v[0] - 1, v[1]) @@ -11,20 +13,12 @@ moves = {'U' : up, 'R' : right } -def memoize(f): - cache = dict() - def memf(path): - if path not in cache: - cache[path] = f(path) - return cache[path] - return memf - def iterate(f, x, N): for i in range(N): yield x x = f(x) -@memoize +@cache def lines(path): pos = (0, 0) r = [] diff --git a/day07.py b/day07.py index adda838..9927ada 100644 --- a/day07.py +++ b/day07.py @@ -2,14 +2,15 @@ from intcode import preproc from itertools import permutations -from lib import memoize, last +from lib import last +from functools import cache stack_size = 5 fst_amp_input = 0 def partI(amp): - run_amp = memoize(lambda *args : last(amp(*args))) + run_amp = cache(lambda *args : last(amp(*args))) phase_range = range(stack_size) best = 0 diff --git a/day08.py b/day08.py index dfa60d2..7bfb20e 100644 --- a/day08.py +++ b/day08.py @@ -1,14 +1,13 @@ #!/usr/bin/env python3 +from lib import Color + ZERO, ONE, TWO = "012" -BLACK = 0 -WHITE = 1 - -color = {WHITE : u"\u2B1C", - BLACK : u"\u2B1B" - } +BLACK = ZERO +WHITE = ONE +encode = {WHITE : Color.WHITE, BLACK : Color.BLACK} class Image: def __init__(self, data, w, h): @@ -31,7 +30,7 @@ class Image: return '\n'.join(image[i:i+w] for i in range(0, len(image), w)) def __str__(self): - return repr(self).replace(ZERO, color[BLACK]).replace(ONE, color[WHITE]) + return repr(self).replace(BLACK, encode[BLACK]).replace(WHITE, encode[WHITE]) diff --git a/day10.py b/day10.py index 83649c4..3831899 100644 --- a/day10.py +++ b/day10.py @@ -1,64 +1,33 @@ #!/usr/bin/env python3 -from math import gcd from fractions import Fraction from itertools import product -from functools import total_ordering from collections import defaultdict +from lib import vector ASTEROID = '#' -def zrange(x, y, step): - if x == y == step == 0: - def yzero(): - while True: - yield 0 - return yzero() - return range(x, y, step) - def angle(v): - if v.x == 0: - return (2 * int(v.y > 0), 0) - halve = 1 if v.x > 0 else 3 - return (halve, Fraction(v.y, v.x)) + x, y = v + if x == 0: + return (2 * int(y > 0), 0) + halve = 1 if x > 0 else 3 + return (halve, Fraction(y, x)) def rebase(base, vectors): return (v - base for v in vectors if v != base) -@total_ordering -class Vector: - def __init__(self, x, y): - self.x = x - self.y = y - def __add__(self, other): - return Vector(self.x + other.x, self.y + other.y) - def __sub__(self, other): - return self + Vector(-other.x, -other.y) - def __eq__(self, other): - return self.x == other.x and self.y == other.y - def __lt__(self, other): - return (self.x**2 + self.y**2) < (other.x**2 + other.y**2) - def __str__(self): - return str((self.x, self.y)) - def __repr__(self): - return str(self) - -class Map: - def __init__(self, map): - self.map = map - - def __getitem__(self, v): - return self.map[v.y][v.x] - +class Map(list): def __str__(self): return '\n'.join(self.map) def is_asteroid(self, v): - return self[v] == ASTEROID + x, y = v + return self[y][x] == ASTEROID def vectors(self): - X, Y = len(self.map[0]), len(self.map) - return (Vector(x, y) for x, y in product(range(X), range(Y))) + X, Y = len(self[0]), len(self) + return (vector(v) for v in product(range(X), range(Y))) def asteroid_vectors(self): return filter(lambda v: self.is_asteroid(v), self.vectors()) @@ -94,8 +63,8 @@ def partI(packed): def partII(packed): asteroid_map, asteroid, _ = packed - v = asteroid_map.vaporize_seq(asteroid)[199] - return 100*v.x + v.y + x, y = asteroid_map.vaporize_seq(asteroid)[199] + return 100*x + y from main import Tests diff --git a/lib.py b/lib.py index 102846a..bf78665 100644 --- a/lib.py +++ b/lib.py @@ -4,6 +4,11 @@ import itertools from collections import deque from enum import Enum +# Random definitons --------------------------------------- +class Color: + WHITE = u"\u2B1C" + BLACK = u"\u2B1B" + # Iterator recipes ---------------------------------------- def last(iterator): """Exhausts an iterator and returns its last element.""" @@ -30,6 +35,7 @@ class defaultlist(list): return self.val_factory() return super().__getitem__(i) + # Basic linear algebra ------------------------------------ class vector(tuple): """Vector class. Convert iterator to vector."""