4 Commits
day19 ... day20

Author SHA1 Message Date
Mikael CAPELLE
1bf2de62c7 Day 20, slow. 2022-12-20 13:39:36 +01:00
Mikael CAPELLE
df808bc98a Start day 20. 2022-12-20 12:35:01 +01:00
Mikaël Capelle
f46e190e98 Add all tests from previous days. 2022-12-19 22:32:15 +01:00
Mikaël Capelle
7f4a34b2d7 Day 19. 2022-12-19 22:09:20 +01:00
32 changed files with 5518 additions and 408 deletions

View File

@@ -1,17 +1,14 @@
# -*- encoding: utf-8 -*- # -*- encoding: utf-8 -*-
import heapq
import math
import sys import sys
import time from typing import Literal
from collections import defaultdict
from typing import Literal, TypedDict
import numpy as np import numpy as np
import parse
from tqdm import tqdm from tqdm import tqdm
Reagent = Literal["ore", "clay", "obsidian", "geode"] Reagent = Literal["ore", "clay", "obsidian", "geode"]
REAGENTS: tuple[Reagent] = ( REAGENTS: tuple[Reagent, ...] = (
"ore", "ore",
"clay", "clay",
"obsidian", "obsidian",
@@ -20,23 +17,6 @@ REAGENTS: tuple[Reagent] = (
IntOfReagent = dict[Reagent, int] IntOfReagent = dict[Reagent, int]
lines = sys.stdin.read().splitlines()
blueprints: list[dict[Reagent, IntOfReagent]] = [
{
"ore": {"ore": 4},
"clay": {"ore": 2},
"obsidian": {"ore": 3, "clay": 14},
"geode": {"ore": 2, "obsidian": 7},
},
{
"ore": {"ore": 2},
"clay": {"ore": 3},
"obsidian": {"ore": 3, "clay": 8},
"geode": {"ore": 3, "obsidian": 12},
},
]
class State: class State:
robots: IntOfReagent robots: IntOfReagent
@@ -64,11 +44,6 @@ class State:
and self.reagents == other.reagents and self.reagents == other.reagents
) )
def __lt__(self, other) -> bool:
return isinstance(other, State) and tuple(
(self.robots[r], self.reagents[r]) for r in REAGENTS
) > tuple((other.robots[r], other.reagents[r]) for r in REAGENTS)
def __hash__(self) -> int: def __hash__(self) -> int:
return hash(tuple((self.robots[r], self.reagents[r]) for r in REAGENTS)) return hash(tuple((self.robots[r], self.reagents[r]) for r in REAGENTS))
@@ -89,399 +64,123 @@ def dominates(lhs: State, rhs: State):
) )
MAX_TIME = 24 lines = sys.stdin.read().splitlines()
blueprint = blueprints[1]
# parents: dict[State, tuple[State | None, int]] = {State(): (None, 0)} blueprints: list[dict[Reagent, IntOfReagent]] = []
# queue = [(0, State())] for line in lines:
# visited: set[State] = set() r = parse.parse(
# at_time: dict[int, list[State]] = defaultdict(lambda: []) "Blueprint {}: "
"Each ore robot costs {:d} ore. "
"Each clay robot costs {:d} ore. "
"Each obsidian robot costs {:d} ore and {:d} clay. "
"Each geode robot costs {:d} ore and {:d} obsidian.",
line,
)
# while queue: blueprints.append(
# time, state = heapq.heappop(queue) {
# if state in visited: "ore": {"ore": r[1]},
# continue "clay": {"ore": r[2]},
"obsidian": {"ore": r[3], "clay": r[4]},
# print(time, state) "geode": {"ore": r[5], "obsidian": r[6]},
}
# visited.add(state) )
# at_time[time].append(state)
# if time > MAX_TIME:
# continue
# if len(queue) % 200 == 0:
# print(len(queue), len(visited), time)
# can_build_any: bool = False
# for reagent in REAGENTS:
# needed = blueprint[reagent]
# if any(state.robots[r] == 0 for r in needed):
# continue
# time_to_complete = max(
# max(
# math.ceil((needed[r] - state.reagents[r]) / state.robots[r])
# for r in needed
# ),
# 0,
# )
# # if time_to_complete != 0:
# # continue
# if time + time_to_complete + 1 > MAX_TIME:
# continue
# wait = time_to_complete + 1
# reagents = {
# r: state.reagents[r] + wait * state.robots[r] - needed.get(r, 0)
# for r in REAGENTS
# }
# robots = state.robots.copy()
# robots[reagent] += 1
# state_2 = State(reagents=reagents, robots=robots)
# if state_2 in visited:
# continue
# if any(dominates(state_v, state_2) for state_v in at_time[time + wait]):
# continue
# # print(time + wait)
# # if any(dominates(state_3, state_2) for state_3 in at_time[time + wait]):
# # print("?")
# # continue
# if state_2 not in parents or parents[state_2][1] > time + wait:
# parents[state_2] = (state, time + wait)
# heapq.heappush(queue, (time + wait, state_2))
# can_build_any = True
# at_time[time + wait].append(state_2)
# if not can_build_any:
# state_2 = State(
# reagents={
# r: state.reagents[r] + state.robots[r] * (MAX_TIME - time)
# for r in REAGENTS
# },
# robots=state.robots,
# )
# if state_2 in visited:
# continue
# if state_2 not in parents or parents[state_2][1] > time + wait:
# parents[state_2] = (state, MAX_TIME)
# heapq.heappush(queue, (MAX_TIME, state_2))
# print(len(visited))
# print(max(state.reagents["geode"] for state in visited))
# exit()
# while states:
# state = states.pop()
# processed.append(state)
# if state.time > MAX_TIME:
# continue
# if len(states) % 100 == 0:
# print(len(states), len(processed), min((s.time for s in states), default=1))
# can_build_any: bool = False
# for reagent in REAGENTS:
# needed = blueprint[reagent]
# if any(state.robots[r] == 0 for r in needed):
# continue
# time_to_complete = max(
# max(
# math.ceil((needed[r] - state.reagents[r]) / state.robots[r])
# for r in needed
# ),
# 0,
# )
# if state.time + time_to_complete + 1 > MAX_TIME:
# continue
# wait = time_to_complete + 1
# reagents = {
# r: state.reagents[r] + wait * state.robots[r] - needed.get(r, 0)
# for r in REAGENTS
# }
# robots = state.robots.copy()
# robots[reagent] += 1
# can_build_any = True
# state_2 = State(time=state.time + wait, reagents=reagents, robots=robots)
# # print(f"{state} -> {state_2}")
# states.add(state_2)
# if not any(dominates(s2, state_2) for s2 in states):
# states.add(state)
# # print(f"can build {reagent} in {time_to_complete}")
# if not can_build_any:
# states.add(
# State(
# time=MAX_TIME + 1,
# reagents={
# r: state.reagents[r] + state.robots[r] * (MAX_TIME - state.time)
# for r in REAGENTS
# },
# robots=state.robots,
# )
# )
# if len(states) % 1000 == 0:
# print("filtering")
# states = {
# s1
# for s1 in states
# if not any(dominates(s2, s1) for s2 in states if s2 is not s1)
# }
# # if len(states) > 4:
# # break
# # break
# print(len(processed))
# print(max(state.reagents["geode"] for state in processed))
# exit()
# for t in range(1, 25):
# states = set()
# for state in state_after_t[t - 1]:
# robots_that_can_be_built = [
# robot
# for robot in REAGENTS
# if all(
# state.reagents[reagent] >= blueprint[robot].get(reagent, 0)
# for reagent in REAGENTS
# )
# ]
# new_states = set()
# # new reagents
# reagents = {
# reagent: state.reagents[reagent] + state.robots[reagent]
# for reagent in REAGENTS
# }
# # if we can build anything, there is no point in waiting
# if len(robots_that_can_be_built) != len(REAGENTS):
# new_states.add(State(robots=state.robots, reagents=reagents))
# for robot in robots_that_can_be_built:
# robots = state.robots.copy()
# robots[robot] += 1
# reagents = {
# reagent: state.reagents[reagent]
# + state.robots[reagent]
# - blueprint[robot].get(reagent, 0)
# for reagent in REAGENTS
# }
# new_states.add(State(robots=robots, reagents=reagents))
# new_states = [
# s1
# for s1 in new_states
# if not any(s1 is not s2 and dominates(s2, s1) for s2 in new_states)
# ]
# states = {
# s1 for s1 in states if not any(dominates(s2, s1) for s2 in new_states)
# }
# states.update(new_states)
# state_after_t[t] = states
# exit()
MAX_TIME = 24 def run(blueprint: dict[Reagent, dict[Reagent, int]], max_time: int) -> int:
blueprint = blueprints[0]
state_after_t: dict[int, list[State]] = {0: [State()]} # since we can only build one robot per time, we do not need more than X robots
# of type K where X is the maximum number of K required among all robots, e.g.,
# in the first toy blueprint, we need at most 4 ore robots, 14 clay ones and 7
# obsidian ones
maximums = {
name: max(blueprint[r].get(name, 0) for r in REAGENTS) for name in REAGENTS
}
for t in range(1, 25): state_after_t: dict[int, set[State]] = {0: [State()]}
print(t, len(state_after_t[t - 1]))
bests_for_robots: dict[tuple[int, ...], list[State]] = {} for t in range(1, max_time + 1):
bests_for_reagents: dict[tuple[int, ...], list[State]] = {}
state_after_t[t] = [] # list of new states at the end of step t that we are going to prune later
states_for_t: set[State] = set()
t1 = time.time() for state in state_after_t[t - 1]:
robots_that_can_be_built = [
robot
for robot in REAGENTS
if all(
state.reagents[reagent] >= blueprint[robot].get(reagent, 0)
for reagent in REAGENTS
)
]
for state in state_after_t[t - 1]: states_for_t.add(
robots_that_can_be_built = [ State(
robot robots=state.robots,
for robot in REAGENTS reagents={
if all( reagent: state.reagents[reagent] + state.robots[reagent]
state.reagents[reagent] >= blueprint[robot].get(reagent, 0) for reagent in REAGENTS
for reagent in REAGENTS },
)
) )
]
# print(t, robots_that_can_be_built) if "geode" in robots_that_can_be_built:
new_states: set[State] = set() robots_that_can_be_built = ["geode"]
else:
robots_that_can_be_built = [
robot
for robot in robots_that_can_be_built
if state.robots[robot] < maximums[robot]
]
# new reagents for robot in robots_that_can_be_built:
reagents = { robots = state.robots.copy()
reagent: state.reagents[reagent] + state.robots[reagent] robots[robot] += 1
for reagent in REAGENTS reagents = {
reagent: state.reagents[reagent]
+ state.robots[reagent]
- blueprint[robot].get(reagent, 0)
for reagent in REAGENTS
}
states_for_t.add(State(robots=robots, reagents=reagents))
# use numpy to switch computation of dominated states -> store each state
# as a 8 array and use numpy broadcasting to find dominated states
states_after = np.asarray(list(states_for_t))
np_states = np.array(
[
[state.robots[r] for r in REAGENTS]
+ [state.reagents[r] for r in REAGENTS]
for state in states_after
]
)
to_keep = []
while len(np_states) > 0:
first_dom = (np_states[1:] >= np_states[0]).all(axis=1).any()
if first_dom:
np_states = np_states[1:]
else:
to_keep.append(np_states[0])
np_states = np_states[1:][~(np_states[1:] <= np_states[0]).all(axis=1)]
state_after_t[t] = {
State(
robots=dict(zip(REAGENTS, row[:4])),
reagents=dict(zip(REAGENTS, row[4:])),
)
for row in to_keep
} }
# if we can build anything, there is no point in waiting return max(state.reagents["geode"] for state in state_after_t[max_time])
new_states.add(State(robots=state.robots, reagents=reagents))
for robot in robots_that_can_be_built:
robots = state.robots.copy()
robots[robot] += 1
reagents = {
reagent: state.reagents[reagent]
+ state.robots[reagent]
- blueprint[robot].get(reagent, 0)
for reagent in REAGENTS
}
new_states.add(State(robots=robots, reagents=reagents))
for s1 in new_states: answer_1 = sum(
r1 = tuple(s1.robots[r] for r in REAGENTS) (i_blueprint + 1) * run(blueprint, 24)
if r1 not in bests_for_robots: for i_blueprint, blueprint in enumerate(tqdm(blueprints))
bests_for_robots[r1] = [s1] )
else: print(f"answer 1 is {answer_1}")
is_dominated = False
for s2 in bests_for_robots[r1]:
if all(s2.reagents[r] >= s1.reagents[r] for r in REAGENTS):
is_dominated = True
break
if not is_dominated:
bests_for_robots[r1].append(s1)
r2 = tuple(s1.reagents[r] for r in REAGENTS) answer_2 = run(blueprints[0], 32) * run(blueprints[1], 32) * run(blueprints[2], 32)
if r2 not in bests_for_reagents: print(f"answer 2 is {answer_2}")
bests_for_reagents[r2] = [s1]
else:
is_dominated = False
for s2 in bests_for_reagents[r2]:
if all(s2.robots[r] >= s1.robots[r] for r in REAGENTS):
is_dominated = True
break
if not is_dominated:
bests_for_reagents[r2].append(s1)
# state_after_t[t].extend(new_states)
t2 = time.time()
for bests in bests_for_robots.values():
dominated = [False for _ in range(len(bests))]
for i_s1, s1 in enumerate(bests):
if dominated[i_s1]:
continue
for i_s2, s2 in enumerate(bests[i_s1 + 1 :], start=i_s1 + 1):
if dominated[i_s2]:
continue
if all(s1.reagents[r] >= s2.reagents[r] for r in REAGENTS):
dominated[i_s2] = True
state_after_t[t].extend(
s1 for i_s1, s1 in enumerate(bests) if not dominated[i_s1]
)
for bests in bests_for_reagents.values():
dominated = [False for _ in range(len(bests))]
for i_s1, s1 in enumerate(bests):
if dominated[i_s1]:
continue
for i_s2, s2 in enumerate(bests[i_s1 + 1 :], start=i_s1 + 1):
if dominated[i_s2]:
continue
if all(s1.robots[r] >= s2.robots[r] for r in REAGENTS):
dominated[i_s2] = True
state_after_t[t].extend(
s1 for i_s1, s1 in enumerate(bests) if not dominated[i_s1]
)
t3 = time.time()
np_states = np.array(
[
[state.robots[r] for r in REAGENTS] + [state.reagents[r] for r in REAGENTS]
for state in state_after_t[t]
]
)
dominated = np.zeros(len(np_states), dtype=bool)
t4 = time.time()
# c = (np_states[None, :, :] <= np_states[:, None, :]).all(axis=-1)
# c[np.arange(len(np_states)), np.arange(len(np_states))] = False
# dominated = c.any(axis=0)
for i in range(len(np_states)):
if dominated[i]:
continue
dominated[i] = not (np_states[i + 1 :] <= np_states[i]).any(axis=1)
dominated[i + 1 :] = (np_states[i + 1 :] <= np_states[i]).all(axis=1)
t5 = time.time()
state_after_t[t] = list(np.array(state_after_t[t])[~dominated])
t6 = time.time()
print(
"->",
t,
len(state_after_t[t]),
dominated.sum(),
t2 - t1,
t3 - t2,
t4 - t3,
t5 - t4,
t6 - t5,
)
# print("->", len(state_after_t[t]))
# dominated = [False for _ in range(len(state_after_t[t]))]
# keep = set()
# for i_s1, s1 in enumerate(tqdm(state_after_t[t])):
# if dominated[i_s1]:
# continue
# for i_s2, s2 in enumerate(state_after_t[t][i_s1 + 1 :], start=i_s1 + 1):
# if dominated[i_s2]:
# continue
# if dominates(s1, s2):
# dominated[i_s2] = True
# elif dominates(s2, s1):
# dominated[i_s1] = True
# break
# if not dominated[i_s1]:
# keep.add(s1)
# state_after_t[t] = list(keep)
# print(len(state_after_t[t]))
# print(sum(dominated))
# break
print(max(state.reagents["geode"] for state in state_after_t[24]))

70
2022/day20.py Normal file
View File

@@ -0,0 +1,70 @@
# -*- encoding: utf-8 -*-
import sys
class Number:
index: int
value: int
def __init__(self, index: int, value: int):
self.index = index
self.value = value
def __eq__(self, other):
if isinstance(other, Number):
return self.index == other.index
elif isinstance(other, int):
return self.value == other
return False
def __hash__(self):
return hash(self.index)
def __str__(self):
return str(self.value)
def __repr__(self):
return str(self)
def decrypt(numbers: list[Number], key: int, rounds: int) -> int:
numbers = numbers.copy()
original = numbers.copy()
numbers2index = {number: number.index for number in numbers}
def swap(lhs: Number, rhs: Number):
i1, i2 = numbers2index[lhs], numbers2index[rhs]
numbers[i1], numbers[i2] = numbers[i2], numbers[i1]
numbers2index[lhs], numbers2index[rhs] = i2, i1
def move(index: int, value: int):
assert value >= 0
while value > 0:
if index == len(numbers) - 1:
swap(numbers[0], numbers[-1])
index, value = 0, value - 1
else:
swap(numbers[index + 1], numbers[index])
index, value = index + 1, value - 1
for _ in range(rounds):
for number in original:
index = numbers2index[number]
move(index, (number.value * key) % (len(numbers) - 1))
index_of_0 = numbers.index(0)
return sum(
numbers[(index_of_0 + offset) % len(numbers)].value * key
for offset in (1000, 2000, 3000)
)
numbers = [Number(i, int(x)) for i, x in enumerate(sys.stdin.readlines())]
answer_1 = decrypt(numbers, 1, 1)
print(f"answer 1 is {answer_1}")
answer_2 = decrypt(numbers, 811589153, 10)
print(f"answer 2 is {answer_2}")

30
2022/inputs/day19.txt Normal file
View File

@@ -0,0 +1,30 @@
Blueprint 1: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 12 clay. Each geode robot costs 4 ore and 19 obsidian.
Blueprint 2: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 11 clay. Each geode robot costs 2 ore and 7 obsidian.
Blueprint 3: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 13 clay. Each geode robot costs 3 ore and 12 obsidian.
Blueprint 4: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 18 clay. Each geode robot costs 2 ore and 19 obsidian.
Blueprint 5: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 19 clay. Each geode robot costs 4 ore and 13 obsidian.
Blueprint 6: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 7 clay. Each geode robot costs 4 ore and 11 obsidian.
Blueprint 7: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 15 clay. Each geode robot costs 4 ore and 17 obsidian.
Blueprint 8: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 13 clay. Each geode robot costs 3 ore and 7 obsidian.
Blueprint 9: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 12 clay. Each geode robot costs 3 ore and 15 obsidian.
Blueprint 10: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 18 clay. Each geode robot costs 4 ore and 11 obsidian.
Blueprint 11: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 8 clay. Each geode robot costs 2 ore and 15 obsidian.
Blueprint 12: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 8 clay. Each geode robot costs 3 ore and 7 obsidian.
Blueprint 13: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 10 clay. Each geode robot costs 2 ore and 10 obsidian.
Blueprint 14: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 13 clay. Each geode robot costs 2 ore and 20 obsidian.
Blueprint 15: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 19 clay. Each geode robot costs 3 ore and 8 obsidian.
Blueprint 16: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 16 clay. Each geode robot costs 2 ore and 18 obsidian.
Blueprint 17: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 9 clay. Each geode robot costs 3 ore and 19 obsidian.
Blueprint 18: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 11 clay. Each geode robot costs 4 ore and 8 obsidian.
Blueprint 19: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 12 clay. Each geode robot costs 3 ore and 17 obsidian.
Blueprint 20: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 14 clay. Each geode robot costs 3 ore and 17 obsidian.
Blueprint 21: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 15 clay. Each geode robot costs 3 ore and 16 obsidian.
Blueprint 22: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 16 clay. Each geode robot costs 4 ore and 16 obsidian.
Blueprint 23: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 19 clay. Each geode robot costs 4 ore and 11 obsidian.
Blueprint 24: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 18 clay. Each geode robot costs 4 ore and 9 obsidian.
Blueprint 25: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 17 clay. Each geode robot costs 3 ore and 16 obsidian.
Blueprint 26: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 20 clay. Each geode robot costs 4 ore and 7 obsidian.
Blueprint 27: Each ore robot costs 2 ore. Each clay robot costs 2 ore. Each obsidian robot costs 2 ore and 8 clay. Each geode robot costs 2 ore and 14 obsidian.
Blueprint 28: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 20 clay. Each geode robot costs 3 ore and 14 obsidian.
Blueprint 29: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 20 clay. Each geode robot costs 4 ore and 8 obsidian.
Blueprint 30: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 18 clay. Each geode robot costs 3 ore and 13 obsidian.

5000
2022/inputs/day20.txt Normal file

File diff suppressed because it is too large Load Diff

0
2022/inputs/day21.txt Normal file
View File

0
2022/inputs/day22.txt Normal file
View File

0
2022/inputs/day23.txt Normal file
View File

0
2022/inputs/day24.txt Normal file
View File

0
2022/inputs/day25.txt Normal file
View File

14
2022/tests/day1.txt Normal file
View File

@@ -0,0 +1,14 @@
1000
2000
3000
4000
5000
6000
7000
8000
9000
10000

146
2022/tests/day10.txt Normal file
View File

@@ -0,0 +1,146 @@
addx 15
addx -11
addx 6
addx -3
addx 5
addx -1
addx -8
addx 13
addx 4
noop
addx -1
addx 5
addx -1
addx 5
addx -1
addx 5
addx -1
addx 5
addx -1
addx -35
addx 1
addx 24
addx -19
addx 1
addx 16
addx -11
noop
noop
addx 21
addx -15
noop
noop
addx -3
addx 9
addx 1
addx -3
addx 8
addx 1
addx 5
noop
noop
noop
noop
noop
addx -36
noop
addx 1
addx 7
noop
noop
noop
addx 2
addx 6
noop
noop
noop
noop
noop
addx 1
noop
noop
addx 7
addx 1
noop
addx -13
addx 13
addx 7
noop
addx 1
addx -33
noop
noop
noop
addx 2
noop
noop
noop
addx 8
noop
addx -1
addx 2
addx 1
noop
addx 17
addx -9
addx 1
addx 1
addx -3
addx 11
noop
noop
addx 1
noop
addx 1
noop
noop
addx -13
addx -19
addx 1
addx 3
addx 26
addx -30
addx 12
addx -1
addx 3
addx 1
noop
noop
noop
addx -9
addx 18
addx 1
addx 2
noop
noop
addx 9
noop
noop
noop
addx -1
addx 2
addx -37
addx 1
addx 3
noop
addx 15
addx -21
addx 22
addx -6
addx 1
noop
addx 2
addx 1
noop
addx -10
noop
noop
addx 20
addx 1
addx 2
addx 2
addx -6
addx -11
noop
noop
noop

27
2022/tests/day11.txt Normal file
View File

@@ -0,0 +1,27 @@
Monkey 0:
Starting items: 79, 98
Operation: new = old * 19
Test: divisible by 23
If true: throw to monkey 2
If false: throw to monkey 3
Monkey 1:
Starting items: 54, 65, 75, 74
Operation: new = old + 6
Test: divisible by 19
If true: throw to monkey 2
If false: throw to monkey 0
Monkey 2:
Starting items: 79, 60, 97
Operation: new = old * old
Test: divisible by 13
If true: throw to monkey 1
If false: throw to monkey 3
Monkey 3:
Starting items: 74
Operation: new = old + 3
Test: divisible by 17
If true: throw to monkey 0
If false: throw to monkey 1

5
2022/tests/day12.txt Normal file
View File

@@ -0,0 +1,5 @@
Sabqponm
abcryxxl
accszExk
acctuvwj
abdefghi

23
2022/tests/day13.txt Normal file
View File

@@ -0,0 +1,23 @@
[1,1,3,1,1]
[1,1,5,1,1]
[[1],[2,3,4]]
[[1],4]
[9]
[[8,7,6]]
[[4,4],4,4]
[[4,4],4,4,4]
[7,7,7,7]
[7,7,7]
[]
[3]
[[[]]]
[[]]
[1,[2,[3,[4,[5,6,7]]]],8,9]
[1,[2,[3,[4,[5,6,0]]]],8,9]

2
2022/tests/day14.txt Normal file
View File

@@ -0,0 +1,2 @@
498,4 -> 498,6 -> 496,6
503,4 -> 502,4 -> 502,9 -> 494,9

14
2022/tests/day15.txt Normal file
View File

@@ -0,0 +1,14 @@
Sensor at x=2, y=18: closest beacon is at x=-2, y=15
Sensor at x=9, y=16: closest beacon is at x=10, y=16
Sensor at x=13, y=2: closest beacon is at x=15, y=3
Sensor at x=12, y=14: closest beacon is at x=10, y=16
Sensor at x=10, y=20: closest beacon is at x=10, y=16
Sensor at x=14, y=17: closest beacon is at x=10, y=16
Sensor at x=8, y=7: closest beacon is at x=2, y=10
Sensor at x=2, y=0: closest beacon is at x=2, y=10
Sensor at x=0, y=11: closest beacon is at x=2, y=10
Sensor at x=20, y=14: closest beacon is at x=25, y=17
Sensor at x=17, y=20: closest beacon is at x=21, y=22
Sensor at x=16, y=7: closest beacon is at x=15, y=3
Sensor at x=14, y=3: closest beacon is at x=15, y=3
Sensor at x=20, y=1: closest beacon is at x=15, y=3

10
2022/tests/day16.txt Normal file
View File

@@ -0,0 +1,10 @@
Valve AA has flow rate=0; tunnels lead to valves DD, II, BB
Valve BB has flow rate=13; tunnels lead to valves CC, AA
Valve CC has flow rate=2; tunnels lead to valves DD, BB
Valve DD has flow rate=20; tunnels lead to valves CC, AA, EE
Valve EE has flow rate=3; tunnels lead to valves FF, DD
Valve FF has flow rate=0; tunnels lead to valves EE, GG
Valve GG has flow rate=0; tunnels lead to valves FF, HH
Valve HH has flow rate=22; tunnel leads to valve GG
Valve II has flow rate=0; tunnels lead to valves AA, JJ
Valve JJ has flow rate=21; tunnel leads to valve II

3
2022/tests/day2.txt Normal file
View File

@@ -0,0 +1,3 @@
A Y
B X
C Z

7
2022/tests/day20.txt Normal file
View File

@@ -0,0 +1,7 @@
1
2
-3
3
-2
0
4

0
2022/tests/day21.txt Normal file
View File

0
2022/tests/day22.txt Normal file
View File

0
2022/tests/day23.txt Normal file
View File

0
2022/tests/day24.txt Normal file
View File

0
2022/tests/day25.txt Normal file
View File

6
2022/tests/day3.txt Normal file
View File

@@ -0,0 +1,6 @@
vJrwpWtwJgWrhcsFMMfFFhFp
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
PmmdzqPrVvPwwTWBwg
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
ttgJtRGJQctTZtZT
CrZsJsPPZsGzwwsLwLmpwMDw

6
2022/tests/day4.txt Normal file
View File

@@ -0,0 +1,6 @@
2-4,6-8
2-3,4-5
5-7,7-9
2-8,3-7
6-6,4-6
2-6,4-8

9
2022/tests/day5.txt Normal file
View File

@@ -0,0 +1,9 @@
[D]
[N] [C]
[Z] [M] [P]
1 2 3
move 1 from 2 to 1
move 3 from 1 to 3
move 2 from 2 to 1
move 1 from 1 to 2

1
2022/tests/day6.txt Normal file
View File

@@ -0,0 +1 @@
mjqjpqmgbljsphdztnvjfqwrcgsmlb

23
2022/tests/day7.txt Normal file
View File

@@ -0,0 +1,23 @@
$ cd /
$ ls
dir a
14848514 b.txt
8504156 c.dat
dir d
$ cd a
$ ls
dir e
29116 f
2557 g
62596 h.lst
$ cd e
$ ls
584 i
$ cd ..
$ cd ..
$ cd d
$ ls
4060174 j
8033020 d.log
5626152 d.ext
7214296 k

5
2022/tests/day8.txt Normal file
View File

@@ -0,0 +1,5 @@
30373
25512
65332
33549
35390

8
2022/tests/day9.txt Normal file
View File

@@ -0,0 +1,8 @@
R 4
U 4
L 3
D 1
R 4
D 1
L 5
R 2

View File

@@ -1,3 +1,5 @@
param ($day) param([switch]$Test, $day)
Get-Content ".\2022\inputs\day$day.txt" | python ".\2022\day$day.py" $folder = $Test ? "tests" : "inputs"
Get-Content ".\2022\$folder\day$day.txt" | python ".\2022\day$day.py"