Merge branch 'master' of github.com:Birdulon/AdventOfCode
This commit is contained in:
commit
ab23da9b56
|
@ -1,5 +1,5 @@
|
||||||
import numpy as np
|
import numpy as np
|
||||||
max_it = 813960 # Somewhat cheaty - this value was obtained from an earlier factor-based brute force. Just use an arbitrarily large number if it fails.
|
max_it = 1000000 # Arbitrarily large number, increase if it fails.
|
||||||
input = 33100000
|
input = 33100000
|
||||||
|
|
||||||
houses = np.ones([max_it], dtype=np.int64)
|
houses = np.ones([max_it], dtype=np.int64)
|
||||||
|
@ -8,8 +8,8 @@ for i in range(2, max_it):
|
||||||
houses[i::i] += i
|
houses[i::i] += i
|
||||||
print(np.argmax(houses > pres10)) # Part 1
|
print(np.argmax(houses > pres10)) # Part 1
|
||||||
|
|
||||||
houses_2 = np.ones([max_it], dtype=np.int64)
|
houses_2 = np.zeros([max_it], dtype=np.int64) # Can no longer optimise out first elf
|
||||||
pres11 = input//11
|
pres11 = input//11
|
||||||
for i in range(2, max_it):
|
for i in range(1, max_it):
|
||||||
houses_2[i:i*51:i] += i
|
houses_2[i:i*51:i] += i
|
||||||
print(np.argmax(houses_2 > pres11)) # Part 2
|
print(np.argmax(houses_2 > pres11)) # Part 2
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
249, 60
|
||||||
|
150, 332
|
||||||
|
174, 83
|
||||||
|
287, 329
|
||||||
|
102, 338
|
||||||
|
111, 201
|
||||||
|
259, 96
|
||||||
|
277, 161
|
||||||
|
143, 288
|
||||||
|
202, 311
|
||||||
|
335, 55
|
||||||
|
239, 148
|
||||||
|
137, 224
|
||||||
|
48, 214
|
||||||
|
186, 87
|
||||||
|
282, 334
|
||||||
|
147, 157
|
||||||
|
246, 191
|
||||||
|
241, 181
|
||||||
|
286, 129
|
||||||
|
270, 287
|
||||||
|
79, 119
|
||||||
|
189, 263
|
||||||
|
324, 280
|
||||||
|
316, 279
|
||||||
|
221, 236
|
||||||
|
327, 174
|
||||||
|
141, 82
|
||||||
|
238, 317
|
||||||
|
64, 264
|
||||||
|
226, 151
|
||||||
|
110, 110
|
||||||
|
336, 194
|
||||||
|
235, 333
|
||||||
|
237, 55
|
||||||
|
230, 137
|
||||||
|
267, 44
|
||||||
|
258, 134
|
||||||
|
223, 42
|
||||||
|
202, 76
|
||||||
|
159, 135
|
||||||
|
229, 238
|
||||||
|
197, 83
|
||||||
|
173, 286
|
||||||
|
123, 90
|
||||||
|
314, 165
|
||||||
|
140, 338
|
||||||
|
347, 60
|
||||||
|
108, 76
|
||||||
|
268, 329
|
|
@ -0,0 +1,56 @@
|
||||||
|
import logging
|
||||||
|
# logging.basicConfig(level=logging.DEBUG)
|
||||||
|
with open('day7-input', 'r') as file:
|
||||||
|
data = [l.strip('\n') for l in file]
|
||||||
|
|
||||||
|
steps = set()
|
||||||
|
step_deps = {}
|
||||||
|
for line in data:
|
||||||
|
tokens = line.split()
|
||||||
|
step1, step2 = tokens[1], tokens[-3]
|
||||||
|
steps.update((step1, step2))
|
||||||
|
step_deps[step2] = step_deps.get(step2, []) + [step1]
|
||||||
|
|
||||||
|
|
||||||
|
def assemble_sleigh(all_steps, step_dependencies, workers):
|
||||||
|
unprocessed_steps = all_steps.copy()
|
||||||
|
ready_steps = set()
|
||||||
|
constructing_steps = {}
|
||||||
|
completed_steps = set()
|
||||||
|
output = []
|
||||||
|
|
||||||
|
time = -1
|
||||||
|
while unprocessed_steps:
|
||||||
|
time += 1
|
||||||
|
for k in list(constructing_steps):
|
||||||
|
constructing_steps[k] -= 1
|
||||||
|
if constructing_steps[k] < 1:
|
||||||
|
completed_steps.add(k)
|
||||||
|
output.append(k)
|
||||||
|
logging.debug(f'{time:04}: Step {k} complete!')
|
||||||
|
constructing_steps.pop(k)
|
||||||
|
|
||||||
|
free_workers = workers - len(constructing_steps)
|
||||||
|
if free_workers < 1:
|
||||||
|
continue
|
||||||
|
|
||||||
|
for step in unprocessed_steps - ready_steps:
|
||||||
|
dependencies = [d for d in step_dependencies.pop(step, []) if d not in completed_steps]
|
||||||
|
if dependencies:
|
||||||
|
step_dependencies[step] = dependencies
|
||||||
|
else:
|
||||||
|
ready_steps.add(step)
|
||||||
|
|
||||||
|
for step in list(sorted(ready_steps))[:free_workers]:
|
||||||
|
constructing_steps[step] = 60 + ord(step) - 64 # ord('A') is 65
|
||||||
|
logging.debug(f'{time:04}: Starting step {step}! ({constructing_steps[step]} seconds remain)')
|
||||||
|
unprocessed_steps.remove(step)
|
||||||
|
ready_steps.remove(step)
|
||||||
|
|
||||||
|
output += [step for step, time in sorted(constructing_steps.items(), key=lambda x: x[1])]
|
||||||
|
time += max(constructing_steps.values())
|
||||||
|
return ''.join(output), time
|
||||||
|
|
||||||
|
|
||||||
|
print('Solo - Order {}, completion time {:4d}s'.format(*assemble_sleigh(steps, step_deps.copy(), 1))) # Part 1, answer is order.
|
||||||
|
print('5man - Order {}, completion time {:4d}s'.format(*assemble_sleigh(steps, step_deps.copy(), 5))) # Part 2, answer is time.
|
|
@ -0,0 +1,101 @@
|
||||||
|
Step C must be finished before step P can begin.
|
||||||
|
Step V must be finished before step Q can begin.
|
||||||
|
Step T must be finished before step X can begin.
|
||||||
|
Step B must be finished before step U can begin.
|
||||||
|
Step Z must be finished before step O can begin.
|
||||||
|
Step P must be finished before step I can begin.
|
||||||
|
Step D must be finished before step G can begin.
|
||||||
|
Step A must be finished before step Y can begin.
|
||||||
|
Step R must be finished before step O can begin.
|
||||||
|
Step J must be finished before step E can begin.
|
||||||
|
Step N must be finished before step S can begin.
|
||||||
|
Step X must be finished before step H can begin.
|
||||||
|
Step F must be finished before step L can begin.
|
||||||
|
Step S must be finished before step I can begin.
|
||||||
|
Step W must be finished before step Q can begin.
|
||||||
|
Step H must be finished before step K can begin.
|
||||||
|
Step K must be finished before step Q can begin.
|
||||||
|
Step E must be finished before step L can begin.
|
||||||
|
Step Q must be finished before step O can begin.
|
||||||
|
Step U must be finished before step G can begin.
|
||||||
|
Step L must be finished before step O can begin.
|
||||||
|
Step Y must be finished before step G can begin.
|
||||||
|
Step G must be finished before step I can begin.
|
||||||
|
Step M must be finished before step I can begin.
|
||||||
|
Step I must be finished before step O can begin.
|
||||||
|
Step A must be finished before step N can begin.
|
||||||
|
Step H must be finished before step O can begin.
|
||||||
|
Step T must be finished before step O can begin.
|
||||||
|
Step H must be finished before step U can begin.
|
||||||
|
Step A must be finished before step I can begin.
|
||||||
|
Step B must be finished before step R can begin.
|
||||||
|
Step V must be finished before step T can begin.
|
||||||
|
Step H must be finished before step M can begin.
|
||||||
|
Step C must be finished before step A can begin.
|
||||||
|
Step B must be finished before step G can begin.
|
||||||
|
Step L must be finished before step Y can begin.
|
||||||
|
Step T must be finished before step J can begin.
|
||||||
|
Step A must be finished before step R can begin.
|
||||||
|
Step X must be finished before step L can begin.
|
||||||
|
Step B must be finished before step L can begin.
|
||||||
|
Step A must be finished before step F can begin.
|
||||||
|
Step K must be finished before step O can begin.
|
||||||
|
Step W must be finished before step M can begin.
|
||||||
|
Step Z must be finished before step N can begin.
|
||||||
|
Step Z must be finished before step S can begin.
|
||||||
|
Step R must be finished before step K can begin.
|
||||||
|
Step Q must be finished before step L can begin.
|
||||||
|
Step G must be finished before step O can begin.
|
||||||
|
Step F must be finished before step Y can begin.
|
||||||
|
Step V must be finished before step H can begin.
|
||||||
|
Step E must be finished before step I can begin.
|
||||||
|
Step W must be finished before step Y can begin.
|
||||||
|
Step U must be finished before step I can begin.
|
||||||
|
Step F must be finished before step K can begin.
|
||||||
|
Step M must be finished before step O can begin.
|
||||||
|
Step Z must be finished before step H can begin.
|
||||||
|
Step X must be finished before step S can begin.
|
||||||
|
Step J must be finished before step O can begin.
|
||||||
|
Step B must be finished before step I can begin.
|
||||||
|
Step F must be finished before step H can begin.
|
||||||
|
Step D must be finished before step U can begin.
|
||||||
|
Step E must be finished before step M can begin.
|
||||||
|
Step Z must be finished before step X can begin.
|
||||||
|
Step P must be finished before step L can begin.
|
||||||
|
Step W must be finished before step H can begin.
|
||||||
|
Step C must be finished before step D can begin.
|
||||||
|
Step A must be finished before step X can begin.
|
||||||
|
Step Q must be finished before step I can begin.
|
||||||
|
Step R must be finished before step Y can begin.
|
||||||
|
Step B must be finished before step A can begin.
|
||||||
|
Step N must be finished before step L can begin.
|
||||||
|
Step H must be finished before step G can begin.
|
||||||
|
Step Y must be finished before step M can begin.
|
||||||
|
Step L must be finished before step G can begin.
|
||||||
|
Step G must be finished before step M can begin.
|
||||||
|
Step Z must be finished before step R can begin.
|
||||||
|
Step S must be finished before step Q can begin.
|
||||||
|
Step P must be finished before step J can begin.
|
||||||
|
Step V must be finished before step J can begin.
|
||||||
|
Step J must be finished before step I can begin.
|
||||||
|
Step J must be finished before step X can begin.
|
||||||
|
Step W must be finished before step O can begin.
|
||||||
|
Step B must be finished before step F can begin.
|
||||||
|
Step R must be finished before step M can begin.
|
||||||
|
Step V must be finished before step S can begin.
|
||||||
|
Step H must be finished before step E can begin.
|
||||||
|
Step E must be finished before step U can begin.
|
||||||
|
Step R must be finished before step W can begin.
|
||||||
|
Step X must be finished before step Q can begin.
|
||||||
|
Step N must be finished before step G can begin.
|
||||||
|
Step T must be finished before step I can begin.
|
||||||
|
Step L must be finished before step M can begin.
|
||||||
|
Step H must be finished before step I can begin.
|
||||||
|
Step U must be finished before step M can begin.
|
||||||
|
Step C must be finished before step H can begin.
|
||||||
|
Step P must be finished before step H can begin.
|
||||||
|
Step J must be finished before step F can begin.
|
||||||
|
Step A must be finished before step O can begin.
|
||||||
|
Step X must be finished before step M can begin.
|
||||||
|
Step H must be finished before step L can begin.
|
||||||
|
Step W must be finished before step K can begin.
|
|
@ -0,0 +1,73 @@
|
||||||
|
with open('day7-input', 'r') as file:
|
||||||
|
data = [l.strip('\n') for l in file]
|
||||||
|
|
||||||
|
steps = set()
|
||||||
|
step_deps = {}
|
||||||
|
for line in data:
|
||||||
|
s = line.split()
|
||||||
|
step1 = s[1]
|
||||||
|
step2 = s[-3]
|
||||||
|
steps.add(step1)
|
||||||
|
steps.add(step2)
|
||||||
|
if step2 in step_deps:
|
||||||
|
step_deps[step2] += step1
|
||||||
|
else:
|
||||||
|
step_deps[step2] = [step1]
|
||||||
|
|
||||||
|
queue = [step for step in steps]
|
||||||
|
step_deps_1 = step_deps.copy()
|
||||||
|
completed_steps = set()
|
||||||
|
ready_steps = set()
|
||||||
|
output = []
|
||||||
|
while queue:
|
||||||
|
for step in queue:
|
||||||
|
if step not in step_deps_1:
|
||||||
|
ready_steps.add(step)
|
||||||
|
else:
|
||||||
|
deps = [d for d in step_deps_1[step] if d not in completed_steps]
|
||||||
|
if len(deps) > 0:
|
||||||
|
step_deps_1[step] = deps
|
||||||
|
else:
|
||||||
|
ready_steps.add(step)
|
||||||
|
step_deps_1.pop(step)
|
||||||
|
for step in sorted(ready_steps)[:1]:
|
||||||
|
completed_steps.add(step)
|
||||||
|
output += step
|
||||||
|
queue.remove(step)
|
||||||
|
break
|
||||||
|
ready_steps = set()
|
||||||
|
print(''.join(output)) # Part 1
|
||||||
|
|
||||||
|
unprocessed_steps = steps.copy()
|
||||||
|
step_deps_2 = step_deps.copy()
|
||||||
|
completed_steps_2 = set()
|
||||||
|
ready_steps_2 = set()
|
||||||
|
waiting_steps = {}
|
||||||
|
time = 0
|
||||||
|
while unprocessed_steps:
|
||||||
|
for k in list(waiting_steps.keys()):
|
||||||
|
waiting_steps[k] -= 1
|
||||||
|
if waiting_steps[k] < 1:
|
||||||
|
completed_steps_2.add(k)
|
||||||
|
print(f'{time:04}: Step {k} complete!') # Debug
|
||||||
|
waiting_steps.pop(k)
|
||||||
|
for step in unprocessed_steps-ready_steps_2:
|
||||||
|
if step not in step_deps_2:
|
||||||
|
ready_steps_2.add(step)
|
||||||
|
else:
|
||||||
|
deps = [d for d in step_deps_2[step] if d not in completed_steps_2]
|
||||||
|
if len(deps) > 0:
|
||||||
|
step_deps_2[step] = deps
|
||||||
|
else:
|
||||||
|
ready_steps_2.add(step)
|
||||||
|
step_deps_2.pop(step)
|
||||||
|
for step in list(sorted(ready_steps_2)):
|
||||||
|
if len(waiting_steps) >= 5: # Only 5 workers
|
||||||
|
break
|
||||||
|
waiting_steps[step] = 60 + ord(step)-64
|
||||||
|
print(f'{time:04}: Starting step {step}! ({waiting_steps[step]} seconds remain)') # Debug
|
||||||
|
unprocessed_steps.remove(step)
|
||||||
|
ready_steps_2.remove(step)
|
||||||
|
time += 1
|
||||||
|
time += max(waiting_steps.values()) - 1 # t got moved forward 1 at end of while loop
|
||||||
|
print(time) # Part 2
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,26 @@
|
||||||
|
with open('day8-input', 'r') as file:
|
||||||
|
data = [int(i) for i in [l.strip('\n') for l in file][0].split()]
|
||||||
|
# data = [2, 3, 0, 3, 10, 11, 12, 1, 1, 0, 1, 99, 2, 1, 1, 2] # For example test casing
|
||||||
|
|
||||||
|
def construct_node(i):
|
||||||
|
num_children = data[i]
|
||||||
|
num_meta = data[i+1]
|
||||||
|
children = []
|
||||||
|
ptr = i+2
|
||||||
|
for c in range(num_children):
|
||||||
|
node, ptr = construct_node(ptr)
|
||||||
|
children.append(node)
|
||||||
|
metadata = data[ptr:ptr+num_meta]
|
||||||
|
return (children, metadata), ptr+num_meta
|
||||||
|
|
||||||
|
def sum_tree_meta(tree):
|
||||||
|
return sum(tree[1] + [sum_tree_meta(child) for child in tree[0]])
|
||||||
|
|
||||||
|
def sum_tree_meta_value(tree):
|
||||||
|
if not tree[0]:
|
||||||
|
return sum(tree[1])
|
||||||
|
return sum([sum_tree_meta_value(tree[0][i-1]) for i in tree[1] if i-1 < len(tree[0])])
|
||||||
|
|
||||||
|
tree = construct_node(0)[0]
|
||||||
|
print(sum_tree_meta(tree)) # Part 1
|
||||||
|
print(sum_tree_meta_value(tree)) # Part 2
|
|
@ -0,0 +1,25 @@
|
||||||
|
import numpy as np
|
||||||
|
from itertools import cycle
|
||||||
|
from collections import deque
|
||||||
|
|
||||||
|
with open('day9-input', 'r') as file:
|
||||||
|
data = [l.strip('\n') for l in file][0].split()
|
||||||
|
players = int(data[0])
|
||||||
|
last_marble = int(data[-2])
|
||||||
|
|
||||||
|
|
||||||
|
def find_winning_score(players, last_marble):
|
||||||
|
marbles = deque([0])
|
||||||
|
scores = np.zeros(players, dtype=np.int64)
|
||||||
|
for marble, player in zip(range(1, last_marble+1), cycle(range(players))):
|
||||||
|
if marble % 23 == 0:
|
||||||
|
marbles.rotate(-7)
|
||||||
|
scores[player] += marble + marbles.pop()
|
||||||
|
else:
|
||||||
|
marbles.rotate(2)
|
||||||
|
marbles.append(marble)
|
||||||
|
return max(scores)
|
||||||
|
|
||||||
|
|
||||||
|
print(find_winning_score(players, last_marble)) # Part 1
|
||||||
|
print(find_winning_score(players, last_marble*100)) # Part 2
|
|
@ -0,0 +1 @@
|
||||||
|
428 players; last marble is worth 72061 points
|
|
@ -0,0 +1,26 @@
|
||||||
|
import numpy as np
|
||||||
|
from itertools import cycle
|
||||||
|
from blist import blist # Regular lists are far too slow for Part 2, as are numpy arrays.
|
||||||
|
|
||||||
|
with open('day9-input', 'r') as file:
|
||||||
|
data = [l.strip('\n') for l in file][0].split()
|
||||||
|
players = int(data[0])
|
||||||
|
last_marble = int(data[-2])
|
||||||
|
|
||||||
|
|
||||||
|
def find_winning_score(players, last_marble):
|
||||||
|
marbles = blist([0])
|
||||||
|
scores = np.zeros(players, dtype=np.int64)
|
||||||
|
current_marble = 0
|
||||||
|
for marble, player in zip(range(1, last_marble+1), cycle(range(players))):
|
||||||
|
if marble % 23 == 0:
|
||||||
|
current_marble = (current_marble-7) % len(marbles)
|
||||||
|
scores[player] += marble + marbles.pop(current_marble)
|
||||||
|
else:
|
||||||
|
current_marble = (current_marble+2) % len(marbles)
|
||||||
|
marbles.insert(current_marble, marble)
|
||||||
|
return max(scores)
|
||||||
|
|
||||||
|
|
||||||
|
print(find_winning_score(players, last_marble)) # Part 1
|
||||||
|
print(find_winning_score(players, last_marble*100)) # Part 2
|
Loading…
Reference in New Issue