From ce170f04ff12e1d4ff52873945948cccb3f0793b Mon Sep 17 00:00:00 2001 From: LordMathis Date: Tue, 19 Dec 2023 23:41:55 +0100 Subject: [PATCH] 2023-08: Attempt part two --- input/2023/day_08/input_test_part_2.txt | 10 +++ .../day_08_haunted_wasteland/common.rs | 23 ++++++ src/year_2023/day_08_haunted_wasteland/mod.rs | 5 +- .../day_08_haunted_wasteland/part_one.rs | 24 +------ .../day_08_haunted_wasteland/part_two.rs | 72 +++++++++++++++++++ 5 files changed, 109 insertions(+), 25 deletions(-) create mode 100644 input/2023/day_08/input_test_part_2.txt create mode 100644 src/year_2023/day_08_haunted_wasteland/common.rs create mode 100644 src/year_2023/day_08_haunted_wasteland/part_two.rs diff --git a/input/2023/day_08/input_test_part_2.txt b/input/2023/day_08/input_test_part_2.txt new file mode 100644 index 0000000..a8e2c98 --- /dev/null +++ b/input/2023/day_08/input_test_part_2.txt @@ -0,0 +1,10 @@ +LR + +11A = (11B, XXX) +11B = (XXX, 11Z) +11Z = (11B, XXX) +22A = (22B, XXX) +22B = (22C, 22C) +22C = (22Z, 22Z) +22Z = (22B, 22B) +XXX = (XXX, XXX) \ No newline at end of file diff --git a/src/year_2023/day_08_haunted_wasteland/common.rs b/src/year_2023/day_08_haunted_wasteland/common.rs new file mode 100644 index 0000000..a726c17 --- /dev/null +++ b/src/year_2023/day_08_haunted_wasteland/common.rs @@ -0,0 +1,23 @@ +#[derive(Clone)] +pub struct Node { + pub value: String, + pub left: String, + pub right: String, +} + +pub fn parse_line(s: &str) -> Node { + // AAA = (BBB, CCC) + let s1: Vec<&str> = s.split('=').collect(); + let node_val = s1[0].trim(); + + let s2 = s1[1].replace(&['(', ')'], ""); + let s3: Vec<&str> = s2.trim().split(',').collect(); + let node_left = s3[0].trim(); + let node_right = s3[1].trim(); + + Node { + value: node_val.to_string(), + left: node_left.to_string(), + right: node_right.to_string(), + } +} diff --git a/src/year_2023/day_08_haunted_wasteland/mod.rs b/src/year_2023/day_08_haunted_wasteland/mod.rs index d879334..fbd7cb6 100644 --- a/src/year_2023/day_08_haunted_wasteland/mod.rs +++ b/src/year_2023/day_08_haunted_wasteland/mod.rs @@ -1,5 +1,6 @@ +pub mod common; pub mod part_one; -// pub mod part_two; +pub mod part_two; use crate::utils::solution::Solution; @@ -15,6 +16,6 @@ impl Solution for Day8Solution { fn part_two(&self) -> String { // Implementation for part two of day 1 // ... - String::from("Not implemented") + part_two::part_two() } } diff --git a/src/year_2023/day_08_haunted_wasteland/part_one.rs b/src/year_2023/day_08_haunted_wasteland/part_one.rs index 619280f..96c1373 100644 --- a/src/year_2023/day_08_haunted_wasteland/part_one.rs +++ b/src/year_2023/day_08_haunted_wasteland/part_one.rs @@ -1,12 +1,7 @@ use std::collections::HashMap; use crate::utils::input_reader; - -pub struct Node { - pub value: String, - pub left: String, - pub right: String, -} +use crate::year_2023::day_08_haunted_wasteland::common::{parse_line, Node}; pub fn part_one() -> String { if let Ok(lines) = input_reader::read_lines("./input/2023/day_08/input.txt") { @@ -50,20 +45,3 @@ pub fn part_one() -> String { panic!("Failed to read lines from input file"); } } - -pub fn parse_line(s: &str) -> Node { - // AAA = (BBB, CCC) - let s1: Vec<&str> = s.split('=').collect(); - let node_val = s1[0].trim(); - - let s2 = s1[1].replace(&['(', ')'], ""); - let s3: Vec<&str> = s2.trim().split(',').collect(); - let node_left = s3[0].trim(); - let node_right = s3[1].trim(); - - Node { - value: node_val.to_string(), - left: node_left.to_string(), - right: node_right.to_string(), - } -} diff --git a/src/year_2023/day_08_haunted_wasteland/part_two.rs b/src/year_2023/day_08_haunted_wasteland/part_two.rs new file mode 100644 index 0000000..0e57d9e --- /dev/null +++ b/src/year_2023/day_08_haunted_wasteland/part_two.rs @@ -0,0 +1,72 @@ +use std::collections::HashMap; + +use crate::utils::input_reader; +use crate::year_2023::day_08_haunted_wasteland::common::{parse_line, Node}; + +pub fn part_two() -> String { + if let Ok(lines) = input_reader::read_lines("./input/2023/day_08/input_test_part_2.txt") { + let mut node_map: HashMap = HashMap::new(); + let mut start_nodes: Vec<&Node> = Vec::new(); + let mut instructions: Vec = Vec::new(); + let mut s: String; + + for (i, line) in lines.enumerate() { + s = line.unwrap(); + + if i == 0 { + instructions = s.chars().collect(); + continue; + } + + if s.is_empty() { + continue; + } + + let node = parse_line(&s); + let value = node.value.clone(); + + node_map.insert(value.clone(), &node.clone()); + + if value.ends_with('A') { + let cloned_node = node.clone(); + start_nodes.push(&cloned_node); + } + } + + let mut curr_nodes: Vec<&Node> = start_nodes; + let mut count = 0; + let mut cond = true; + + while cond { + let i = count % instructions.len(); + let c = instructions[i]; + + let mut new_curr: Vec<&Node> = Vec::new(); + cond = false; + + for n in curr_nodes { + let nn: &Node; + if instructions[i] == 'L' { + nn = &node_map[&n.left]; + } else if instructions[i] == 'R' { + nn = &node_map[&n.right]; + } else { + panic!("Unknown instruction!") + } + + if !nn.value.clone().ends_with('Z') { + cond = true; + } + + new_curr.push(nn); + } + + curr_nodes = new_curr; + count += 1; + } + + return count.to_string(); + } else { + panic!("Failed to read lines from input file"); + } +}