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.

Represent Intcode tape as defaultdict

Use defaultdict as the underlying representation for the Intcode VM tape
instead of a list, allowing for "unlimited" tape usage and not requiring
the caller to manually pad the tape with zeroes.

Benchmarking solutions after this change seems to affect some problems
positively and others negatively by a few percent, so it seems worth the
tradeoff to have cleaner code in general.

+12 -16
-1
2019/day09.py
··· 4 4 5 5 # Read input 6 6 TAPE = [int(x) for x in fileinput.input()[0].split(',')] 7 - TAPE += [0] * 100000 # Pad memory 8 7 9 8 print "BOOST keycode:", next(emulate(TAPE, [1])) 10 9 print "Coordinates of distress signal:", next(emulate(TAPE, [2]))
-1
2019/day11.py
··· 39 39 40 40 # Read input 41 41 TAPE = [int(x) for x in fileinput.input()[0].split(',')] 42 - TAPE += [0] * 100000 43 42 44 43 # Part 1 45 44 grid = simulate_robot(TAPE, 0)
+1 -1
2019/day12.py
··· 11 11 return a 12 12 13 13 14 - def lcm(a, b): 14 + def lcm(a, b, *args): 15 15 """Compute the lowest common multiple of a and b""" 16 16 return a * b / gcd(a, b) 17 17
-1
2019/day13.py
··· 6 6 7 7 # Read input 8 8 TAPE = [int(x) for x in fileinput.input()[0].split(',')] 9 - TAPE += [0] * 100000 10 9 TAPE[0] = 2 11 10 12 11 inputs = [0]
-1
2019/day15.py
··· 72 72 73 73 # Read input 74 74 TAPE = [int(x) for x in fileinput.input()[0].split(',')] 75 - TAPE += [0] * 100000 76 75 77 76 BOARD = {} 78 77 OXYGEN = None
-1
2019/day17.py
··· 6 6 7 7 # Read problem input 8 8 TAPE = [int(x) for x in fileinput.input()[0].split(',')] 9 - TAPE += [0] * 100000 10 9 11 10 12 11 # Part 1
-1
2019/day19.py
··· 16 16 17 17 # Read problem input 18 18 TAPE = [int(x) for x in fileinput.input()[0].split(',')] 19 - TAPE += [0] * 100000 20 19 21 20 22 21 part_1 = sum(affected(x, y) for y in range(50) for x in range(50))
-1
2019/day21.py
··· 2 2 from intcode import emulate 3 3 4 4 TAPE = [int(x) for x in fileinput.input()[0].split(',')] 5 - TAPE += [0] * 10000 6 5 7 6 walking = """\ 8 7 OR D J
-1
2019/day23.py
··· 9 9 10 10 11 11 TAPE = [int(x) for x in fileinput.input()[0].split(',')] 12 - TAPE += [0] * 1000 13 12 14 13 VMS = 50 15 14 PACKET_QUEUES = [deque([i]) for i in range(VMS)]
-1
2019/day25.py
··· 50 50 51 51 52 52 TAPE = [int(x) for x in fileinput.input()[0].split(',')] 53 - TAPE += [0] * 10000 54 53 55 54 vm = emulate(TAPE, [ord(c) for c in TAS][::-1]) 56 55 try:
+11 -6
2019/intcode.py
··· 28 28 return '%({}{}{})'.format(relative_base, '+' if param >= 0 else '', param) 29 29 30 30 31 - def parse_mode(tape, mode_op, a, b, c): 31 + def parse_mode(mode_op, a, b, c): 32 32 op = mode_op % 100 33 33 mode_a = (mode_op // 100) % 10 34 34 mode_b = (mode_op // 1000) % 10 ··· 37 37 return op, mode_a, mode_b, mode_c 38 38 39 39 40 - def emulate(tape, inputs, pc=0, relative_base=0, debug=False): 41 - tape = tape[:] 40 + def emulate(base_tape, inputs, pc=0, relative_base=0, debug=False): 41 + tape = defaultdict(int) 42 + for i, v in enumerate(base_tape): 43 + tape[i] = v 42 44 43 45 def resolve_modes(op, params, modes): 44 46 res = [a, b, c] ··· 62 64 63 65 return res 64 66 65 - while pc < len(tape): 66 - mode_op, a, b, c = tape[pc:pc+4] 67 - op, mode_a, mode_b, mode_c = parse_mode(tape, mode_op, a, b, c) 67 + while True: 68 + mode_op = tape[pc] 69 + a = tape[pc+1] 70 + b = tape[pc+2] 71 + c = tape[pc+3] 72 + op, mode_a, mode_b, mode_c = parse_mode(mode_op, a, b, c) 68 73 modes = [mode_a, mode_b, mode_c] 69 74 last_pc = pc 70 75