Skip to content

Commit

Permalink
Add 2023 solutions
Browse files Browse the repository at this point in the history
  • Loading branch information
NoahMollerstuen committed Dec 25, 2023
1 parent 1efde4f commit a29bb7c
Show file tree
Hide file tree
Showing 39 changed files with 2,524 additions and 5 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.idea/
web_secrets.py
lib
puzzle_inputs
web_secrets.py
**/part1_attempts.json
**/part2_attempts.json
80 changes: 80 additions & 0 deletions 2023day12.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import functools

from util import *
from util import Grid as g
import itertools as it
import re

h = Helper(day=12, test_mode=True, test_input="""
??? 1
""")

inp = h.get_input_list()


@functools.cache
def check_record_consistency(springs, groups):
springs = list(springs)
group_len = 0
group_index = -1
in_group = False
for c in springs + ["."]:
if c == '?':
return True
if in_group:
if c == "#":
group_len += 1
if group_len > groups[group_index]:
return False
else:
if groups[group_index] != group_len:
return False
in_group = False
else:
if c == "#":
group_index += 1
if group_index >= len(groups):
return False
in_group = True
group_len = 1

return group_index == len(groups) - 1


def count_valid_combinations(springs, groups):
springs = list(springs)
if '?' not in springs:
return 1

question_index = springs.index('?')

total_options = 0

for c in ".#":
springs[question_index] = c
if check_record_consistency(tuple(springs), groups):
total_options += count_valid_combinations(tuple(springs), groups)

return total_options


records = []

for line in inp:
records.append((
list("?".join(it.repeat(line.split(" ")[0], 5))),
list(it.chain.from_iterable(it.repeat(list(int(d) for d in line.split(" ")[1].split(",")), 5)))
))
# print(records[-1])
# print("".join(records[-1][0]))
# print(records[-1][1])


options_sum = 0
for record in records:
print("".join(record[0]), ",".join(str(n) for n in record[1]))
options = count_valid_combinations(tuple(record[0]), tuple(record[1]))
print(options)
options_sum += options

h.submit(options_sum)
166 changes: 166 additions & 0 deletions day20.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import queue
from collections import defaultdict

from util import *
from util import Grid as g
import itertools as it
import re

h = Helper(test_mode=False, test_input="""
broadcaster -> a
%a -> inv, con
&inv -> b
%b -> con
&con -> output
""")


# pulses_queue = queue.Queue()
#
#
# class SolutionFoundException(Exception):
# pass
#
#
# class Module:
# def __init__(self, name: str, link_strs: t.List[str]):
# self.name: str = name
# self.link_strs: t.List[str] = link_strs
# self.link_objects: t.List[Module] = []
#
# def init_link_objects(self, all_modules):
# for li in self.link_strs:
# try:
# self.link_objects.append(all_modules[li])
# except KeyError:
# pass
#
# def send_pulse(self, is_high_pulse: bool):
# global pulses_queue
#
# for li in self.link_objects:
# if li.name == "kj" and is_high_pulse:
# raise SolutionFoundException
# pulses_queue.put((li, is_high_pulse, self.name))
#
# def activate(self, is_high_pulse: bool, activator_name: str):
# raise NotImplemented()
#
#
# class FlipFlop(Module):
# def __init__(self, name: str, link_strs: t.List[str]):
# super().__init__(name, link_strs)
# self.state = False
#
# def activate(self, is_high_pulse: bool, activator_name):
# if is_high_pulse:
# return
#
# self.state = not self.state
# self.send_pulse(self.state)
#
#
# class Conjunction(Module):
# def __init__(self, name: str, link_strs: t.List[str]):
# super().__init__(name, link_strs)
# self.input_states = {}
#
# def init_link_objects(self, all_modules):
# super().init_link_objects(all_modules)
# for mod in all_modules.values():
# if self.name in mod.link_strs:
# self.input_states[mod.name] = False
#
# def activate(self, is_high_pulse: bool, activator_name: str):
# self.input_states[activator_name] = is_high_pulse
# self.send_pulse(not all(self.input_states.values()))
#
#
# class Broadcast(Module):
# def activate(self, is_high_pulse: bool, activator_name: str):
# self.send_pulse(is_high_pulse)
#
#
# class Button(Module):
# def activate(self, is_high_pulse: bool, activator_name: str):
# self.send_pulse(False)
#
#
# TYPE_CODES = {
# '%': FlipFlop,
# '&': Conjunction,
# 'b': Broadcast,
# }
#
# inp = h.get_input_list()
#
# modules: t.Dict[str, Module] = {}
#
# for line in inp:
# type_code = line[0]
# module_type = TYPE_CODES[type_code]
# name = line.split(' -> ')[0].strip('%&')
# links = line.split(' -> ')[1].split(', ')
# modules[name] = module_type(name, links)
#
# modules["button"] = (Button("button", ["broadcaster"]))
#
# for m in modules.values():
# m.init_link_objects(modules)
#
# step = 0
# last_high = 0
#
# while True:
# states = [str(int(m.state)) for m in modules.values() if isinstance(m, FlipFlop)]
# # print("".join(states))
#
# step += 1
# modules["pd"].activate(False, "")
#
# while not pulses_queue.empty():
# pulse = pulses_queue.get(block=False)
# # print(pulse, pulse[0].name)
# try:
# pulse[0].activate(pulse[1], pulse[2])
# except SolutionFoundException:
# print(step, step - last_high)
# last_high = step
# break

high_steps = defaultdict(lambda: 0)

steps = [
4003,
3989,
3863,
3943,
]

periods = [
3910,
3882,
3630,
3790,
]

"""
kt: goes high on step 4003 and 4004, repeats for 2 steps with period 3910 steps
xv: goes high on step 3989 and 3990, repeats for 2 steps with period 3882 steps
rg: goes high on step 3863 and 3864, repeats for 2 steps with period 3630 steps
pd: goes high on step 3943 and 3944, repeats for 2 steps with period 3790 steps
"""


while True:
for i, p in enumerate(periods):
s = steps[i]
high_steps[s] += 1
if high_steps[s] == 4:
h.submit(s)

high_steps[s + 1] += 1
if high_steps[s + 1] == 4:
h.submit(s + 1)

steps[i] += p
31 changes: 31 additions & 0 deletions day20vis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from pyvis.network import Network

from util import Helper

net = Network(directed=True)

h = Helper(test_mode=False)

inp = h.get_input_list()

modules = {}

for line in inp:
type_code = line[0]
name = line.split(' -> ')[0].strip('%&')
links = line.split(' -> ')[1].split(', ')
modules[name] = (type_code, name, links)
if type_code == '&':
net.add_node(name, name, shape="box")
else:
net.add_node(name, name)

net.add_node("rx", "rx")
net.add_node("button", "button")
modules["button"] = ("but", "button", ["broadcaster"])

for m in modules.values():
for n in m[2]:
net.add_edge(m[1], n)

net.show('mygraph.html', notebook=False)
38 changes: 38 additions & 0 deletions solutions/2023_day06/part1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import operator

from util import *
from util import Grid as g
import itertools as it
import re


h = Helper(test_mode=False, test_input="""
Time: 7 15 30
Distance: 9 40 200
""")

inp = h.get_input_list()


def get_race_distance(total_time, hold_time):
return (total_time - hold_time) * hold_time


def count_winning_times(max_time, dist_to_beat):
c = 0
for ht in range(max_time):
if get_race_distance(max_time, ht) > dist_to_beat:
c += 1
return c


times = [int(n) for n in inp[0].split(" ")[1:] if n]
distances = [int(n) for n in inp[1].split(" ")[1:] if n]


races = list(zip(times, distances))


h.submit(list(it.accumulate((count_winning_times(*r) for r in races), operator.mul))[-1])


32 changes: 32 additions & 0 deletions solutions/2023_day06/part2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import operator

from util import *
from util import Grid as g
import itertools as it
import re


h = Helper(test_mode=False, test_input="""
Time: 7 15 30
Distance: 9 40 200
""")

inp = h.get_input_list()

time = int(inp[0].split(":")[1].replace(' ', ''))
dist = int(inp[1].split(":")[1].replace(' ', ''))


def get_race_distance(total_time, hold_time):
return (total_time - hold_time) * hold_time


def count_winning_times(max_time, dist_to_beat):
c = 0
for ht in range(max_time):
if get_race_distance(max_time, ht) > dist_to_beat:
c += 1
return c


h.submit(count_winning_times(time, dist))
Loading

0 comments on commit a29bb7c

Please sign in to comment.