mirror of
https://github.com/kristoferssolo/Advent-of-Code.git
synced 2026-02-04 14:12:02 +00:00
finished day 08
This commit is contained in:
9
2023/day-08/src/bin/part1.rs
Normal file
9
2023/day-08/src/bin/part1.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use color_eyre::Result;
|
||||
use day_08::part1::process;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let file = include_str!("../../input1.txt");
|
||||
let result = process(file)?;
|
||||
println!("{}", result);
|
||||
Ok(())
|
||||
}
|
||||
9
2023/day-08/src/bin/part2.rs
Normal file
9
2023/day-08/src/bin/part2.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use color_eyre::Result;
|
||||
use day_08::part2::process;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let file = include_str!("../../input2.txt");
|
||||
let result = process(file)?;
|
||||
println!("{}", result);
|
||||
Ok(())
|
||||
}
|
||||
2
2023/day-08/src/lib.rs
Normal file
2
2023/day-08/src/lib.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
pub mod part1;
|
||||
pub mod part2;
|
||||
74
2023/day-08/src/part1.rs
Normal file
74
2023/day-08/src/part1.rs
Normal file
@@ -0,0 +1,74 @@
|
||||
use std::{collections::HashMap, ops::Deref, rc::Rc};
|
||||
|
||||
use color_eyre::{eyre::anyhow, Result};
|
||||
|
||||
fn parse_input(input: &str) -> Result<(&str, HashMap<Rc<str>, (Rc<str>, Rc<str>)>)> {
|
||||
let mut lines = input.lines();
|
||||
let rule = lines.next().ok_or_else(|| anyhow!("Path"))?.into();
|
||||
lines.next();
|
||||
let mut maps = HashMap::new();
|
||||
for line in lines {
|
||||
let binding: String = line
|
||||
.replace("=", "")
|
||||
.replace("(", "")
|
||||
.replace(")", "")
|
||||
.replace(",", "");
|
||||
let values = binding.split_whitespace().collect::<Vec<_>>();
|
||||
maps.insert(values[0].into(), (values[1].into(), values[2].into()));
|
||||
}
|
||||
|
||||
Ok((rule, maps))
|
||||
}
|
||||
|
||||
pub fn process(input: &str) -> Result<usize> {
|
||||
let (rule, maps) = parse_input(input)?;
|
||||
let (start, end) = ("AAA", "ZZZ");
|
||||
let mut current: Rc<str> = Rc::from(start);
|
||||
let mut step_count = 0;
|
||||
|
||||
while current.deref() != end {
|
||||
for ch in rule.chars() {
|
||||
if let Some(side) = maps.get(¤t) {
|
||||
match ch {
|
||||
'L' => current = side.0.clone(),
|
||||
'R' => current = side.1.clone(),
|
||||
_ => return Err(anyhow!("Should not have happened")),
|
||||
}
|
||||
step_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(step_count)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_process() -> Result<()> {
|
||||
let input = "RL
|
||||
|
||||
AAA = (BBB, CCC)
|
||||
BBB = (DDD, EEE)
|
||||
CCC = (ZZZ, GGG)
|
||||
DDD = (DDD, DDD)
|
||||
EEE = (EEE, EEE)
|
||||
GGG = (GGG, GGG)
|
||||
ZZZ = (ZZZ, ZZZ)";
|
||||
assert_eq!(2, process(input)?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_process2() -> Result<()> {
|
||||
let input = "LLR
|
||||
|
||||
AAA = (BBB, BBB)
|
||||
BBB = (AAA, ZZZ)
|
||||
ZZZ = (ZZZ, ZZZ)";
|
||||
assert_eq!(6, process(input)?);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
77
2023/day-08/src/part2.rs
Normal file
77
2023/day-08/src/part2.rs
Normal file
@@ -0,0 +1,77 @@
|
||||
use std::{collections::HashMap, rc::Rc};
|
||||
|
||||
use color_eyre::{eyre::anyhow, Result};
|
||||
|
||||
fn parse_input(input: &str) -> Result<(&str, HashMap<Rc<str>, (Rc<str>, Rc<str>)>)> {
|
||||
let mut lines = input.lines();
|
||||
let rule = lines.next().ok_or_else(|| anyhow!("Path"))?.into();
|
||||
lines.next();
|
||||
let mut maps = HashMap::new();
|
||||
for line in lines {
|
||||
let binding: String = line
|
||||
.replace("=", "")
|
||||
.replace("(", "")
|
||||
.replace(")", "")
|
||||
.replace(",", "");
|
||||
let values = binding.split_whitespace().collect::<Vec<_>>();
|
||||
maps.insert(values[0].into(), (values[1].into(), values[2].into()));
|
||||
}
|
||||
|
||||
Ok((rule, maps))
|
||||
}
|
||||
|
||||
pub fn process(input: &str) -> Result<usize> {
|
||||
let (rule, maps) = parse_input(input)?;
|
||||
let start: Vec<_> = maps
|
||||
.keys()
|
||||
.filter(|&key| key.ends_with('A'))
|
||||
.cloned()
|
||||
.collect();
|
||||
|
||||
let mut current_values = start;
|
||||
let mut step_count = 0;
|
||||
println!("{:?}", ¤t_values);
|
||||
|
||||
'outer: loop {
|
||||
for ch in rule.chars() {
|
||||
for value in &mut current_values {
|
||||
if let Some(side) = maps.get(value) {
|
||||
match ch {
|
||||
'L' => *value = side.0.clone(),
|
||||
'R' => *value = side.1.clone(),
|
||||
_ => return Err(anyhow!("Unexpected character in rule")),
|
||||
}
|
||||
}
|
||||
}
|
||||
step_count += 1;
|
||||
if current_values.iter().all(|x| x.ends_with('Z')).clone() {
|
||||
break 'outer;
|
||||
}
|
||||
}
|
||||
println!("{}", step_count);
|
||||
}
|
||||
|
||||
Ok(step_count)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_process() -> Result<()> {
|
||||
let input = "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)";
|
||||
assert_eq!(6, process(input)?);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user