Final refactoring for days 1-10

master
Tibor Bizjak 2023-03-20 23:58:44 +01:00
parent 072bf8409d
commit 38923eb7a7
5 changed files with 31 additions and 62 deletions

View File

@ -1,5 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from functools import cache
up = lambda v: (v[0], v[1] + 1) up = lambda v: (v[0], v[1] + 1)
down = lambda v: (v[0], v[1] - 1) down = lambda v: (v[0], v[1] - 1)
left = lambda v: (v[0] - 1, v[1]) left = lambda v: (v[0] - 1, v[1])
@ -11,20 +13,12 @@ moves = {'U' : up,
'R' : right '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): def iterate(f, x, N):
for i in range(N): for i in range(N):
yield x yield x
x = f(x) x = f(x)
@memoize @cache
def lines(path): def lines(path):
pos = (0, 0) pos = (0, 0)
r = [] r = []

View File

@ -2,14 +2,15 @@
from intcode import preproc from intcode import preproc
from itertools import permutations from itertools import permutations
from lib import memoize, last from lib import last
from functools import cache
stack_size = 5 stack_size = 5
fst_amp_input = 0 fst_amp_input = 0
def partI(amp): def partI(amp):
run_amp = memoize(lambda *args : last(amp(*args))) run_amp = cache(lambda *args : last(amp(*args)))
phase_range = range(stack_size) phase_range = range(stack_size)
best = 0 best = 0

View File

@ -1,14 +1,13 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from lib import Color
ZERO, ONE, TWO = "012" ZERO, ONE, TWO = "012"
BLACK = 0 BLACK = ZERO
WHITE = 1 WHITE = ONE
color = {WHITE : u"\u2B1C",
BLACK : u"\u2B1B"
}
encode = {WHITE : Color.WHITE, BLACK : Color.BLACK}
class Image: class Image:
def __init__(self, data, w, h): 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)) return '\n'.join(image[i:i+w] for i in range(0, len(image), w))
def __str__(self): 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])

View File

@ -1,64 +1,33 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from math import gcd
from fractions import Fraction from fractions import Fraction
from itertools import product from itertools import product
from functools import total_ordering
from collections import defaultdict from collections import defaultdict
from lib import vector
ASTEROID = '#' 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): def angle(v):
if v.x == 0: x, y = v
return (2 * int(v.y > 0), 0) if x == 0:
halve = 1 if v.x > 0 else 3 return (2 * int(y > 0), 0)
return (halve, Fraction(v.y, v.x)) halve = 1 if x > 0 else 3
return (halve, Fraction(y, x))
def rebase(base, vectors): def rebase(base, vectors):
return (v - base for v in vectors if v != base) return (v - base for v in vectors if v != base)
@total_ordering class Map(list):
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]
def __str__(self): def __str__(self):
return '\n'.join(self.map) return '\n'.join(self.map)
def is_asteroid(self, v): def is_asteroid(self, v):
return self[v] == ASTEROID x, y = v
return self[y][x] == ASTEROID
def vectors(self): def vectors(self):
X, Y = len(self.map[0]), len(self.map) X, Y = len(self[0]), len(self)
return (Vector(x, y) for x, y in product(range(X), range(Y))) return (vector(v) for v in product(range(X), range(Y)))
def asteroid_vectors(self): def asteroid_vectors(self):
return filter(lambda v: self.is_asteroid(v), self.vectors()) return filter(lambda v: self.is_asteroid(v), self.vectors())
@ -94,8 +63,8 @@ def partI(packed):
def partII(packed): def partII(packed):
asteroid_map, asteroid, _ = packed asteroid_map, asteroid, _ = packed
v = asteroid_map.vaporize_seq(asteroid)[199] x, y = asteroid_map.vaporize_seq(asteroid)[199]
return 100*v.x + v.y return 100*x + y
from main import Tests from main import Tests

6
lib.py
View File

@ -4,6 +4,11 @@ import itertools
from collections import deque from collections import deque
from enum import Enum from enum import Enum
# Random definitons ---------------------------------------
class Color:
WHITE = u"\u2B1C"
BLACK = u"\u2B1B"
# Iterator recipes ---------------------------------------- # Iterator recipes ----------------------------------------
def last(iterator): def last(iterator):
"""Exhausts an iterator and returns its last element.""" """Exhausts an iterator and returns its last element."""
@ -30,6 +35,7 @@ class defaultlist(list):
return self.val_factory() return self.val_factory()
return super().__getitem__(i) return super().__getitem__(i)
# Basic linear algebra ------------------------------------ # Basic linear algebra ------------------------------------
class vector(tuple): class vector(tuple):
"""Vector class. Convert iterator to vector.""" """Vector class. Convert iterator to vector."""