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.

Add utilities module with Point class

+61 -29
+13 -15
2016/day01.py
··· 1 1 import fileinput 2 + from utils import Point 2 3 3 4 DIRS = [ 4 - (1, 0), # north 5 - (0, 1), # east 6 - (-1, 0), # south 7 - (0, -1) # west 5 + Point(1, 0), # north 6 + Point(0, 1), # east 7 + Point(-1, 0), # south 8 + Point(0, -1) # west 8 9 ] 9 10 10 11 seen = set() 11 - double_visit = False 12 + double_visit = '' 12 13 13 - x = 0 14 - y = 0 14 + pos = Point(0, 0) 15 15 facing = 0 16 16 17 17 for line in fileinput.input(): ··· 27 27 facing = (facing + 1) % 4 28 28 29 29 for _ in range(steps): 30 - x += DIRS[facing][0] 31 - y += DIRS[facing][1] 32 - 33 - if not double_visit and (x, y) in seen: 34 - print "First double-visit at ({}, {}) ({} blocks away)".format(x, y, abs(x) + abs(y)) 35 - double_visit = True 30 + pos += DIRS[facing] 31 + if not double_visit and pos in seen: 32 + double_visit = "First double-visit at ({}, {}) ({} blocks away)".format(pos.x, pos.y, pos.manhattan) 36 33 else: 37 - seen.add((x, y)) 34 + seen.add(pos) 38 35 39 - print "Easter Bunny HQ is at ({}, {}) ({} blocks away)".format(x, y, abs(x) + abs(y)) 36 + print "Easter Bunny HQ is at ({}, {}) ({} blocks away)".format(pos.x, pos.y, pos.manhattan) 37 + print double_visit
+18 -14
2016/day02.py
··· 1 1 import fileinput 2 + from utils import Point 2 3 3 4 KEYPAD_1 = [ 4 5 ['1', '2', '3'], ··· 15 16 ] 16 17 17 18 DIRS = { 18 - 'U': (0, -1), 19 - 'D': (0, 1), 20 - 'L': (-1, 0), 21 - 'R': (1, 0), 19 + 'U': Point(0, -1), 20 + 'D': Point(0, 1), 21 + 'L': Point(-1, 0), 22 + 'R': Point(1, 0), 22 23 } 23 24 24 25 25 26 def move(keypad, pos, d): 26 27 """Returns the (x, y) coordinate after (possibly) moving.""" 27 - new_x = max(0, min(pos[0] + DIRS[d][0], len(keypad[0]) - 1)) 28 - new_y = max(0, min(pos[1] + DIRS[d][1], len(keypad) - 1)) 28 + new = pos + DIRS[d] 29 29 30 - if keypad[new_y][new_x] == '_': 30 + if new.x < 0 or new.y < 0: 31 31 return pos 32 - else: 33 - return (new_x, new_y) 32 + elif new.x >= len(keypad[0]) or new.y >= len(keypad): 33 + return pos 34 + elif keypad[new.y][new.x] == '_': 35 + return pos 34 36 37 + return new 35 38 36 - pos_1 = (1, 1) # start in middle 37 - pos_2 = (0, 2) # start in middle-left 39 + 40 + pos_1 = Point(1, 1) # start in middle 41 + pos_2 = Point(0, 2) # start in middle-left 38 42 39 43 code_1 = '' 40 44 code_2 = '' 41 45 42 - for i, line in enumerate(fileinput.input()): 46 + for line in fileinput.input(): 43 47 for c in line.strip(): 44 48 pos_1 = move(KEYPAD_1, pos_1, c) 45 49 pos_2 = move(KEYPAD_2, pos_2, c) 46 50 47 - code_1 += KEYPAD_1[pos_1[1]][pos_1[0]] 48 - code_2 += KEYPAD_2[pos_2[1]][pos_2[0]] 51 + code_1 += KEYPAD_1[pos_1.y][pos_1.x] 52 + code_2 += KEYPAD_2[pos_2.y][pos_2.x] 49 53 50 54 print "Theoretical bathroom code: {}".format(code_1) 51 55 print "Actual bathroom code: {}".format(code_2)
+30
2016/utils.py
··· 1 + from functools import total_ordering 2 + 3 + @total_ordering 4 + class Point: 5 + """Simple 2-dimensional point.""" 6 + def __init__(self, x, y): 7 + self.x = x 8 + self.y = y 9 + 10 + def __add__(self, other): 11 + return Point(self.x + other.x, self.y + other.y) 12 + 13 + def __eq__(self, other): 14 + return self.x == other.x and self.y == other.y 15 + 16 + def __ne__(self, other): 17 + return not self == other 18 + 19 + def __lt__(self, other): 20 + return self.manhattan < other.manhattan 21 + 22 + def __str__(self): 23 + return "({}, {})".format(self.x, self.y) 24 + 25 + def __hash__(self): 26 + return hash(tuple((self.x, self.y))) 27 + 28 + @property 29 + def manhattan(self): 30 + return abs(self.x) + abs(self.y)