My Advent of Code solutions in Python. kevinyap.ca/2019/12/going-fast-in-advent-of-code/
advent-of-code python
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 125 lines 2.8 kB view raw
1import re 2import math 3import operator 4from functools import total_ordering 5 6 7LETTERS = [x for x in 'abcdefghijklmnopqrstuvwxyz'] 8VOWELS = {'a', 'e', 'i', 'o', 'u'} 9CONSONANTS = set(x for x in LETTERS if x not in VOWELS) 10 11 12def parse_line(regex, line): 13 ret = [] 14 for match in re.match(regex, line).groups(): 15 try: 16 ret.append(int(match)) 17 except ValueError: 18 ret.append(match) 19 20 return ret 21 22 23def new_table(val, width, height): 24 return [[val for _ in range(width)] for _ in range(height)] 25 26 27def mul(lst): 28 """Like sum(), but for multiplication.""" 29 return reduce(operator.mul, lst, 1) # NOQA 30 31 32def chunks(l, n): 33 """Yield successive n-sized chunks from l.""" 34 for i in range(0, len(l), n): 35 yield l[i:i + n] 36 37 38def factors(n): 39 """Returns the factors of n.""" 40 return sorted( 41 x for tup in ( 42 [i, n // i] for i in range(1, int(n ** 0.5) + 1) 43 if n % i == 0) 44 for x in tup) 45 46 47def memoize(f): 48 """Simple dictionary-based memoization decorator""" 49 cache = {} 50 51 def _mem_fn(*args): 52 if args not in cache: 53 cache[args] = f(*args) 54 return cache[args] 55 56 _mem_fn.cache = cache 57 return _mem_fn 58 59 60def _eratosthenes(n): 61 """http://stackoverflow.com/a/3941967/239076""" 62 # Initialize list of primes 63 _primes = [True] * n 64 65 # Set 0 and 1 to non-prime 66 _primes[0] = _primes[1] = False 67 68 for i, is_prime in enumerate(_primes): 69 if is_prime: 70 yield i 71 72 # Mark factors as non-prime 73 for n in xrange(i * i, n, i): # NOQA 74 _primes[n] = False 75 76 77def primes(n): 78 """Return a list of primes from [2, n)""" 79 return list(_eratosthenes(n)) 80 81 82@total_ordering 83class Point: 84 """Simple 2-dimensional point.""" 85 def __init__(self, x, y): 86 self.x = x 87 self.y = y 88 89 def __add__(self, other): 90 return Point(self.x + other.x, self.y + other.y) 91 92 def __sub__(self, other): 93 return Point(self.x - other.x, self.y - other.y) 94 95 def __mul__(self, n): 96 return Point(self.x * n, self.y * n) 97 98 def __div__(self, n): 99 return Point(self.x / n, self.y / n) 100 101 def __neg__(self): 102 return Point(-self.x, -self.y) 103 104 def __eq__(self, other): 105 return self.x == other.x and self.y == other.y 106 107 def __ne__(self, other): 108 return not self == other 109 110 def __lt__(self, other): 111 return self.manhattan < other.manhattan 112 113 def __str__(self): 114 return "({}, {})".format(self.x, self.y) 115 116 def __hash__(self): 117 return hash(tuple((self.x, self.y))) 118 119 @property 120 def manhattan(self): 121 return abs(self.x) + abs(self.y) 122 123 @property 124 def distance(self): 125 return math.sqrt(self.x ** 2 + self.y ** 2)