159 lines
4.1 KiB
Rust
159 lines
4.1 KiB
Rust
use std::collections::HashMap;
|
|
|
|
use super::Solution;
|
|
|
|
pub struct Day08 {}
|
|
|
|
impl Solution for Day08 {
|
|
fn part1(
|
|
&self,
|
|
input: &mut Vec<String>,
|
|
) -> Result<Box<dyn std::fmt::Display + Sync>, Box<dyn std::error::Error>> {
|
|
let instructions: String = input[0].clone();
|
|
let mut map: HashMap<String, (String, String)> = HashMap::new();
|
|
|
|
self.populate_map(&input[2..input.len()], &mut map)?;
|
|
|
|
Ok(Box::new(self.traverse_to_end(
|
|
&"AAA".to_owned(),
|
|
&"ZZZ".to_owned(),
|
|
&instructions,
|
|
&map,
|
|
)?))
|
|
}
|
|
|
|
fn part2(
|
|
&self,
|
|
input: &mut Vec<String>,
|
|
) -> Result<Box<dyn std::fmt::Display + Sync>, Box<dyn std::error::Error>> {
|
|
let instructions: String = input[0].clone();
|
|
|
|
let mut map: HashMap<String, (String, String)> = HashMap::new();
|
|
self.populate_map(&input[2..input.len()], &mut map)?;
|
|
|
|
let mut start_points = vec![];
|
|
for route in &input[2..input.len()] {
|
|
if route.as_bytes()[2] as char == 'A' {
|
|
start_points.push(route.split_at(3).0.to_owned());
|
|
}
|
|
}
|
|
|
|
let mut count = 0u32;
|
|
|
|
println!("{:?}", start_points);
|
|
for start in start_points {
|
|
count += self.traverse_to_end(&start, &"Z".to_owned(), &instructions, &map)?
|
|
}
|
|
|
|
Ok(Box::new(count))
|
|
}
|
|
|
|
fn get_day(&self) -> u8 {
|
|
8
|
|
}
|
|
}
|
|
|
|
impl Day08 {
|
|
/// Given a string in the format XXX = (XXX, XXX), will populate a map witht he Xs
|
|
/// To create a way of traversing the route
|
|
fn populate_map<'a>(
|
|
&self,
|
|
input: &[String],
|
|
map: &mut HashMap<String, (String, String)>,
|
|
) -> Result<(), Box<dyn std::error::Error>> {
|
|
for p in input {
|
|
let mut x = p.split('=');
|
|
|
|
let key = x.nth(0).unwrap().trim().to_owned();
|
|
let (l, r) = x.nth(0).unwrap().split_at(6);
|
|
map.insert(
|
|
key,
|
|
(
|
|
l.to_owned()
|
|
.replace(",", "")
|
|
.replace("(", "")
|
|
.trim()
|
|
.to_owned(),
|
|
r.trim().to_owned().replace(")", ""),
|
|
),
|
|
);
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Function to traverse the map going left and right based on given instructions
|
|
fn traverse_to_end(
|
|
&self,
|
|
start: &String,
|
|
end: &String,
|
|
instructions: &String,
|
|
map: &HashMap<String, (String, String)>,
|
|
) -> Result<u32, Box<dyn std::error::Error>> {
|
|
let mut count = 0u32;
|
|
let mut current = map.get(start).unwrap();
|
|
let mut found = false;
|
|
|
|
while !found {
|
|
for i in instructions.chars() {
|
|
count += 1;
|
|
let next: &String;
|
|
match i {
|
|
'L' => next = ¤t.0,
|
|
'R' => next = ¤t.1,
|
|
_ => {
|
|
continue;
|
|
}
|
|
}
|
|
if next.ends_with("ZZZ") {
|
|
found = true;
|
|
break;
|
|
}
|
|
current = map.get(next).unwrap();
|
|
}
|
|
}
|
|
Ok(count)
|
|
}
|
|
}
|
|
|
|
/// Test from puzzle input
|
|
#[cfg(test)]
|
|
mod test {
|
|
use super::*;
|
|
use crate::*;
|
|
|
|
#[test]
|
|
fn part1() {
|
|
let challenge = day08::Day08 {};
|
|
|
|
//Complete the Challenge
|
|
let answer = challenge
|
|
.part1(
|
|
utils::get_input(challenge.get_day(), utils::InputType::Test1)
|
|
.unwrap()
|
|
.as_mut(),
|
|
)
|
|
.unwrap()
|
|
.to_string();
|
|
|
|
assert_eq!(answer, "6");
|
|
}
|
|
|
|
#[test]
|
|
fn part2() {
|
|
let challenge = day08::Day08 {};
|
|
|
|
//Complete the Challenge
|
|
let answer = challenge
|
|
.part2(
|
|
utils::get_input(challenge.get_day(), utils::InputType::Test2)
|
|
.unwrap()
|
|
.as_mut(),
|
|
)
|
|
.unwrap()
|
|
.to_string();
|
|
|
|
assert_eq!(answer, "6");
|
|
}
|
|
}
|