Merge branch 'master' of github.com:Birdulon/AdventOfCode

This commit is contained in:
Luke Hubmayer-Werner 2018-12-10 12:40:07 +10:30
commit ab23da9b56
10 changed files with 362 additions and 3 deletions

View File

@ -1,5 +1,5 @@
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
houses = np.ones([max_it], dtype=np.int64)
@ -8,8 +8,8 @@ for i in range(2, max_it):
houses[i::i] += i
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
for i in range(2, max_it):
for i in range(1, max_it):
houses_2[i:i*51:i] += i
print(np.argmax(houses_2 > pres11)) # Part 2

50
2018/day6-input Normal file
View File

@ -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

56
2018/day7-cleaned.py Normal file
View File

@ -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.

101
2018/day7-input Normal file
View File

@ -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.

73
2018/day7.py Normal file
View File

@ -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

1
2018/day8-input Normal file

File diff suppressed because one or more lines are too long

26
2018/day8.py Normal file
View File

@ -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

25
2018/day9-deque.py Normal file
View File

@ -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

1
2018/day9-input Normal file
View File

@ -0,0 +1 @@
428 players; last marble is worth 72061 points

26
2018/day9.py Normal file
View File

@ -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