diff --git a/aoc-py/solutions/day20.py b/aoc-py/solutions/day20.py index fb0cabd..4a6d4bd 100644 --- a/aoc-py/solutions/day20.py +++ b/aoc-py/solutions/day20.py @@ -103,10 +103,10 @@ def _parse_input(self, inp: str) -> tuple[dict[str, Module], list[str]]: # defaulting to false to begin module.memory[name] = False return modules, broadcast_targets - + def _run_modules(self, destinations: list[Destination], module: Module, source: str, pulse: bool) -> None: """Runs a single iteration of all the modules' pulse sending process""" - + if isinstance(module, Flipper) and not pulse: module.status = not module.status pulse_to_send = module.status @@ -176,8 +176,8 @@ def part_two(self, inp: str) -> int: seen[name := source.name] = True if name not in press_amounts: - press_amounts[name] = n_presses - + press_amounts[name] = n_presses + if all(seen.values()): # we have checked all the modules that feed into the module # we can then return the result diff --git a/src/bin/day19.rs b/src/bin/day19.rs index 1da23e5..160a6fe 100644 --- a/src/bin/day19.rs +++ b/src/bin/day19.rs @@ -8,15 +8,13 @@ use std::{ }; use aoc_2023::Solution; -pub struct Day19; - #[derive(Debug, Clone)] struct Rule<'a> { - pub key: &'a str, - pub target: &'a str, - pub rhs: usize, - pub is_gt: bool, - pub condition: fn(&usize, &usize) -> bool, + key: &'a str, + target: &'a str, + rhs: usize, + is_gt: bool, + condition: fn(&usize, &usize) -> bool, } impl<'a> Rule<'a> { @@ -29,8 +27,8 @@ impl<'a> Rule<'a> { #[derive(Debug, Clone)] struct Workflow<'a> { - pub default: &'a str, - pub rules: Vec>, + default: &'a str, + rules: Vec>, } impl<'a> Workflow<'a> { @@ -54,7 +52,7 @@ impl<'a> Workflow<'a> { if is_gt { '>' } else { '<' } ) .unwrap(); - + self.rules.push(Rule { key, target, is_gt, rhs: rhs.parse::() @@ -66,6 +64,8 @@ impl<'a> Workflow<'a> { } } +pub struct Day19; + impl Day19 { fn parse_workflows(raw: &T) -> HashMap> where @@ -200,7 +200,7 @@ impl Day19 { } /// # Panics - /// + /// /// If failed to parse input (malformed) pub fn part_one(&self, inp: T) -> usize { let inp = inp @@ -219,9 +219,9 @@ impl Day19 { ) .sum() } - + /// # Panics - /// + /// /// If failed to parse input (malformed) pub fn part_two(&self, inp: T) -> usize { let inp = inp diff --git a/src/bin/day20.rs b/src/bin/day20.rs new file mode 100644 index 0000000..57756cb --- /dev/null +++ b/src/bin/day20.rs @@ -0,0 +1,147 @@ +//! Day 20: Pulse Propagation +//! +//! +use std::{ + collections::{VecDeque, HashMap}, + fmt::Display, os::windows::io::BorrowedHandle, +}; +use aoc_2023::Solution; + +#[derive(Debug, Clone)] +struct Destination { + name: String, + target: String, + pulse: bool, +} + +#[derive(Debug, Clone)] +enum Module<'a> { + Flipper { + name: &'a str, + outputs: Vec, + status: bool, + }, + Conjunction { + name: &'a str, + outputs: Vec, + memory: HashMap, + } +} + +impl<'a> Module<'a> { + fn new(raw: &'a str, outputs: Vec) -> Self { + match raw + .split_at(1) + { + ("%", name) => Self::Flipper { + name, outputs, + status: false, + }, + ("&", name) => Self::Conjunction { + name, outputs, + memory: HashMap::new(), + }, + _ => panic!("Invalid module prefix"), + } + } + + fn name(&self) -> &'a str { + match self { + Self::Flipper { name, .. } => name, + Self::Conjunction { name, .. } => name, + } + } + + fn outputs(&self) -> &Vec { + match self { + Self::Flipper { outputs, .. } => outputs, + Self::Conjunction { outputs, .. } => outputs, + } + } +} + +pub struct Day20; + +impl Day20 { + fn parse_input(inp: &T) -> (HashMap>, Vec) + where + T: AsRef, + { + let mut modules = HashMap::new(); + let mut broadcast_targets = Vec::new(); + + for line in inp + .as_ref() + .lines() + { + let (name, targets) = line + .split_once("->") + .unwrap(); + let targets = targets + .split(',') + .map(|s| s.trim().to_string()) + .collect::>(); + match name.trim() { + "broadcaster" => broadcast_targets = targets, + name => { + modules.insert( + name.to_string(), + Module::new(name, targets), + ); + } + } + } + + for (name, module) in &modules { + for output in module + .outputs() + .iter() + .filter_map(|output| modules + .get_mut(output) + ) + { + if let Module::Conjunction { memory, .. } = output { + memory.insert( + name.clone(), + false + ); + } + } + } + (modules, broadcast_targets) + } + pub fn part_one(&self, inp: T) -> usize { + todo!() + } + + pub fn part_two(&self, inp: T) -> usize { + todo!() + } +} + +impl Solution for Day20 { + const NAME: &'static str = "Pulse Propagation"; + + fn run(&self, inp: String) { + let p1 = self.part_one(&inp); + let p2 = self.part_two(&inp); + + println!("Part 1: {p1}"); + println!("Part 2: {p2}"); + + assert_eq!(p1, 680_278_040); + assert_eq!(p2, 243_548_140_870_057); + } +} + +fn main() { + aoc_2023::run_day(20, &Day20); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test() { main(); } +} \ No newline at end of file