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 2021/{08,09}

+101 -19
+42 -19
2021/day08.py
··· 1 1 import fileinput 2 - from string import maketrans 3 - from itertools import permutations 2 + from collections import Counter 4 3 5 4 6 5 UNIQUES = { ··· 23 22 9: 'abcdfg', 24 23 } 25 24 26 - SEGMENTS_MAP = {v: str(k) for k, v in DIGIT_MAP.items()} 25 + REVERSE_MAP = {v: k for k, v in DIGIT_MAP.items()} 27 26 28 - VALID_SEGMENTS = set(v for v in DIGIT_MAP.values()) 27 + # a/c and d/g can both be diambiguated by 4, 28 + # who has a unique segument count, and also 29 + # contains c & d but not a & g. 30 + SEGMENT_FREQ = { 31 + # 'a': 8, 32 + 'b': 6, 33 + # 'c': 8, 34 + # 'd': 7, 35 + 'e': 4, 36 + 'f': 9, 37 + # 'g': 7, 38 + } 29 39 30 - ALL_SEGMENTS = 'abcdefg' 40 + REVERSE_FREQ = {v: k for k, v in SEGMENT_FREQ.items()} 31 41 32 42 part_1 = 0 33 43 part_2 = 0 ··· 41 51 part_1 += 1 42 52 43 53 # Solve part 2 44 - for perm in permutations('abcdefg', 7): 45 - table = maketrans(ALL_SEGMENTS, perm) 54 + for word in input.split(): 55 + if len(word) == 4: 56 + four_segments = word 57 + 58 + frequencies = Counter(input.replace(' ', '')) 59 + 60 + print frequencies.most_common() 61 + # break 46 62 47 - for word in input.split(): 48 - new_word = word.translate(table) 49 - new_word = ''.join(sorted(new_word)) 63 + mapping = {} 64 + for segment, count in frequencies.most_common(): 65 + if count in REVERSE_FREQ: 66 + mapping[segment] = REVERSE_FREQ[count] 67 + elif count == 7: 68 + if segment in four_segments: 69 + mapping[segment] = 'd' 70 + else: 71 + mapping[segment] = 'g' 72 + elif count == 8: 73 + if segment in four_segments: 74 + mapping[segment] = 'c' 75 + else: 76 + mapping[segment] = 'a' 50 77 51 - if new_word not in VALID_SEGMENTS: 52 - break 53 - else: 54 - ans = '' 55 - for word in output.split(): 56 - new_word = word.translate(table) 57 - new_word = ''.join(sorted(new_word)) 58 - ans += SEGMENTS_MAP[new_word] 78 + code = '' 79 + for word in output.split(): 80 + new_word = ''.join(sorted(mapping[l] for l in word)) 81 + code += str(REVERSE_MAP[new_word]) 59 82 60 - part_2 += int(ans) 83 + part_2 += int(code) 61 84 62 85 63 86 print "Part 1:", part_1
+59
2021/day09.py
··· 1 + import fileinput 2 + from collections import Counter, defaultdict, deque, namedtuple # NOQA 3 + from utils import Point, mul 4 + 5 + # Read in problem input. 6 + WIDTH = HEIGHT = 0 7 + BOARD = {} 8 + 9 + for y, line in enumerate(fileinput.input()): 10 + line = line.strip() 11 + for x, c in enumerate(line): 12 + BOARD[Point(x, y)] = int(c) 13 + WIDTH = x + 1 14 + 15 + HEIGHT = y + 1 16 + 17 + 18 + LOW_POINTS = set() 19 + part_1 = 0 20 + 21 + # Solve part 1. 22 + for y in range(HEIGHT): 23 + for x in range(WIDTH): 24 + p = Point(x, y) 25 + val = BOARD[p] 26 + 27 + for n in p.neighbours_4(): 28 + if n in BOARD: 29 + if BOARD[n] <= val: 30 + break 31 + else: 32 + LOW_POINTS.add(p) 33 + part_1 += (val + 1) 34 + 35 + print "Part 1:", part_1 36 + 37 + 38 + # Solve part 2. 39 + def compute_basin_size(board, start): 40 + """Return the set of all explored points from a given point.""" 41 + seen = set() 42 + 43 + def _dfs(node): 44 + val = board[node] 45 + seen.add(node) 46 + for n in node.neighbours_4(): 47 + if n in board and n not in seen: 48 + if val <= board[n] and board[n] != 9: 49 + _dfs(n) 50 + 51 + _dfs(start) 52 + return len(seen) 53 + 54 + BASIN_SIZES = {} 55 + for p in LOW_POINTS: 56 + BASIN_SIZES[p] = compute_basin_size(BOARD, p) 57 + 58 + print "Part 2:", mul(sorted(BASIN_SIZES.values(), reverse=True)[:3]) 59 +