From 1e11d80d453687a8f4a50a5744995282aee97279 Mon Sep 17 00:00:00 2001 From: Tyler Beckman Date: Mon, 23 Dec 2024 23:01:33 -0700 Subject: [PATCH] Day 24 p1 --- Cargo.toml | 8 ++++++ day24/part1.rs | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ day24/part2.rs | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 141 insertions(+) create mode 100644 day24/part1.rs create mode 100644 day24/part2.rs diff --git a/Cargo.toml b/Cargo.toml index d4ad678..ac98c8d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -67,3 +67,11 @@ path = "day23/part1.rs" [[bin]] name = "d23p2" path = "day23/part2.rs" + +[[bin]] +name = "d24p1" +path = "day24/part1.rs" + +[[bin]] +name = "d24p2" +path = "day24/part2.rs" diff --git a/day24/part1.rs b/day24/part1.rs new file mode 100644 index 0000000..aa5ad08 --- /dev/null +++ b/day24/part1.rs @@ -0,0 +1,66 @@ +use std::collections::HashMap; + +use itertools::Itertools; + +const INPUT: &str = include_str!("input.txt"); + +#[derive(Debug)] +struct Gate<'a> { + first: &'a str, + second: &'a str, + op: Operation +} + +#[repr(u8)] +#[derive(Debug)] +enum Operation { + And, + Or, + Xor, +} + +fn solve<'a>(state: &mut HashMap<&'a str, u64>, gates: &'a HashMap<&'a str, Gate>, output: &'a str) -> u64 { + state.get(output).map(|&t| t).unwrap_or_else(|| { + let gate = &gates[output]; + let (first_res, second_res) = (solve(state, gates, gate.first), solve(state, gates, gate.second)); + state.entry(gate.first).or_insert(first_res); + state.entry(gate.second).or_insert(second_res); + match gate.op { + Operation::And => first_res & second_res, + Operation::Or => first_res | second_res, + Operation::Xor => first_res ^ second_res + } + }) +} + +fn main() { + let (state, gates) = INPUT.split("\n\n").collect_tuple().unwrap(); + let mut state = HashMap::<&str, u64>::from_iter( + state + .trim() + .lines() + .map(|l| l.split_once(": ").unwrap()) + .map(|(wire, value)| (wire, if value == "0" { 0 } else { 1 })) + ); + let gates = HashMap::<&str, Gate>::from_iter( + gates + .trim() + .lines() + .map(|l| l.split_once(" -> ").unwrap()) + .map(|(inputs, output)| (inputs.split(' ').collect_tuple().unwrap(), output)) + .map(|((first, op, second), output)| (output, Gate { first, second, op: match op { + "AND" => Operation::And, + "OR" => Operation::Or, + "XOR" => Operation::Xor, + _ => unreachable!() + }})) + ); + + let mut result = 0u64; + + for (&output, z_value) in gates.keys().filter_map(|k| k.split_once('z').map(|(_, num)| (k, num.parse::().unwrap()))) { + result |= solve(&mut state, &gates, output) << z_value; + } + + println!("{result}"); +} diff --git a/day24/part2.rs b/day24/part2.rs new file mode 100644 index 0000000..034a183 --- /dev/null +++ b/day24/part2.rs @@ -0,0 +1,67 @@ +use std::collections::HashMap; + +use itertools::Itertools; + +const INPUT: &str = include_str!("input.txt"); + +#[derive(Debug)] +struct Gate<'a> { + first: &'a str, + second: &'a str, + op: Operation +} + +#[repr(u8)] +#[derive(Debug)] +enum Operation { + And, + Or, + Xor, +} + +fn solve<'a>(state: &mut HashMap<&'a str, u64>, gates: &'a HashMap<&'a str, Gate>, output: &'a str) -> u64 { + state.get(output).map(|&t| t).unwrap_or_else(|| { + let gate = &gates[output]; + let (first_res, second_res) = (solve(state, gates, gate.first), solve(state, gates, gate.second)); + state.entry(gate.first).or_insert(first_res); + state.entry(gate.second).or_insert(second_res); + match gate.op { + Operation::And => first_res & second_res, + Operation::Or => first_res | second_res, + Operation::Xor => first_res ^ second_res + } + }) +} + +fn main() { + let (state, gates) = INPUT.split("\n\n").collect_tuple().unwrap(); + let mut state = HashMap::<&str, u64>::from_iter( + state + .trim() + .lines() + .map(|l| l.split_once(": ").unwrap()) + .filter(|wire) + .map(|(wire, value)| (wire, if value == "0" { 0 } else { 1 })) + ); + let gates = HashMap::<&str, Gate>::from_iter( + gates + .trim() + .lines() + .map(|l| l.split_once(" -> ").unwrap()) + .map(|(inputs, output)| (inputs.split(' ').collect_tuple().unwrap(), output)) + .map(|((first, op, second), output)| (output, Gate { first, second, op: match op { + "AND" => Operation::And, + "OR" => Operation::Or, + "XOR" => Operation::Xor, + _ => unreachable!() + }})) + ); + + let mut result = 0u64; + + for (&output, z_value) in gates.keys().filter_map(|k| k.split_once('z').map(|(_, num)| (k, num.parse::().unwrap()))) { + result |= solve(&mut state, &gates, output) << z_value; + } + + println!("{result}"); +}