day08 done.
This commit is contained in:
parent
c9e4dab862
commit
5b3a1c737f
|
@ -1,2 +1,3 @@
|
||||||
pub mod points;
|
pub mod points;
|
||||||
pub mod range;
|
pub mod range;
|
||||||
|
pub mod misc;
|
||||||
|
|
43
aoc_libs/src/misc.rs
Normal file
43
aoc_libs/src/misc.rs
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
pub fn arr_lcm(input: &[usize]) -> usize {
|
||||||
|
input.iter().copied().reduce(lcm).unwrap_or(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn lcm(first: usize, second: usize) -> usize {
|
||||||
|
first * second / gcd(&first, &second)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn gcd(a: &usize, b: &usize) -> usize {
|
||||||
|
let mut a = *a;
|
||||||
|
let mut b = *b;
|
||||||
|
while b != 0 {
|
||||||
|
let tmp = b;
|
||||||
|
b = a.rem_euclid(b);
|
||||||
|
a = tmp;
|
||||||
|
}
|
||||||
|
a
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_arr_lcm() {
|
||||||
|
assert_eq!(arr_lcm(&[4, 6]), 12);
|
||||||
|
assert_eq!(arr_lcm(&[5, 2]), 10);
|
||||||
|
assert_eq!(arr_lcm(&[5, 2, 6]), 30);
|
||||||
|
assert_eq!(arr_lcm(&[5, 2, 6, 3]), 30);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_lcm() {
|
||||||
|
assert_eq!(lcm(4, 6), 12);
|
||||||
|
assert_eq!(lcm(5, 2), 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_gcd() {
|
||||||
|
assert_eq!(gcd(&8, &12), 4);
|
||||||
|
assert_eq!(gcd(&54, &24), 6);
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,5 +10,5 @@ fn main() {
|
||||||
println!("Result: {}", part1::part1(&structured_input));
|
println!("Result: {}", part1::part1(&structured_input));
|
||||||
|
|
||||||
println!("Part Two");
|
println!("Part Two");
|
||||||
println!("Result: {}", part2::part2());
|
println!("Result: {}", part2::part2(&structured_input));
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ pub struct Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
static NODE_REGEX: Lazy<Regex> = Lazy::new(|| {
|
static NODE_REGEX: Lazy<Regex> = Lazy::new(|| {
|
||||||
Regex::new(r"^([[:alpha:]]{3}) = \(([[:alpha:]]{3}), ([[:alpha:]]{3})\)$").unwrap()
|
Regex::new(r"^([[:alnum:]]{3}) = \(([[:alnum:]]{3}), ([[:alnum:]]{3})\)$").unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
pub fn parse(input: &str) -> (Vec<Direction>, HashMap<String, Node>) {
|
pub fn parse(input: &str) -> (Vec<Direction>, HashMap<String, Node>) {
|
||||||
|
|
|
@ -1,15 +1,113 @@
|
||||||
|
use aoc_libs::misc::arr_lcm;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::parse::*;
|
use crate::parse::*;
|
||||||
|
|
||||||
pub fn part2() -> usize {
|
// note about inputs: each "ends with A" node is the starting point,
|
||||||
unimplemented!()
|
// and is not returned to part of the loop.
|
||||||
|
// eatch 'Z' node is at the 'end' of the loop,
|
||||||
|
// so the time when you first hit z is equal to your cycle time.
|
||||||
|
|
||||||
|
pub fn part2(input: &(Vec<Direction>, HashMap<String, Node>)) -> usize {
|
||||||
|
let (directions, graph) = input;
|
||||||
|
let starting_points = find_starting_points(graph);
|
||||||
|
println!("{:?}", starting_points);
|
||||||
|
let cycle_lengths: Vec<_> = starting_points
|
||||||
|
.iter()
|
||||||
|
.inspect(|p| print!("starting point {}: ", p))
|
||||||
|
.map(|p| cycle_len_and_offset(p, directions, graph))
|
||||||
|
.inspect(|c| println!("cycles: {}", c))
|
||||||
|
.collect();
|
||||||
|
arr_lcm(&cycle_lengths)
|
||||||
|
}
|
||||||
|
|
||||||
|
//returns the length of the loop
|
||||||
|
fn cycle_len_and_offset(
|
||||||
|
start: &str,
|
||||||
|
directions: &[Direction],
|
||||||
|
graph: &HashMap<String, Node>,
|
||||||
|
) -> usize {
|
||||||
|
let mut current_node: String = start.to_string();
|
||||||
|
let mut dir_index: usize = 0;
|
||||||
|
let mut cycles: usize = 0;
|
||||||
|
while !current_node.ends_with('Z') {
|
||||||
|
match directions[dir_index % directions.len()] {
|
||||||
|
Direction::Left => current_node = graph.get(¤t_node).unwrap().left.clone(),
|
||||||
|
Direction::Right => current_node = graph.get(¤t_node).unwrap().right.clone(),
|
||||||
|
};
|
||||||
|
cycles += 1;
|
||||||
|
dir_index += 1;
|
||||||
|
// println!("finding index: {}", current_node);
|
||||||
|
}
|
||||||
|
cycles
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_starting_points(input: &HashMap<String, Node>) -> Vec<String> {
|
||||||
|
let mut ret = Vec::new();
|
||||||
|
for point in input.keys() {
|
||||||
|
if point.ends_with('A') {
|
||||||
|
ret.push(point.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_find_len_of_cycle() {
|
||||||
|
let input = parse(concat!(
|
||||||
|
"LR\n",
|
||||||
|
"\n",
|
||||||
|
"11A = (11B, XXX)\n",
|
||||||
|
"11B = (XXX, 11Z)\n",
|
||||||
|
"11Z = (11B, XXX)\n",
|
||||||
|
"22A = (22B, XXX)\n",
|
||||||
|
"22B = (22C, 22C)\n",
|
||||||
|
"22C = (22Z, 22Z)\n",
|
||||||
|
"22Z = (22B, 22B)\n",
|
||||||
|
"XXX = (XXX, XXX)\n",
|
||||||
|
));
|
||||||
|
assert_eq!(cycle_len_and_offset("11A", &input.0, &input.1), 2);
|
||||||
|
assert_eq!(cycle_len_and_offset("22A", &input.0, &input.1), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_find_starting_points() {
|
||||||
|
let input = parse(concat!(
|
||||||
|
"LR\n",
|
||||||
|
"\n",
|
||||||
|
"11A = (11B, XXX)\n",
|
||||||
|
"11B = (XXX, 11Z)\n",
|
||||||
|
"11Z = (11B, XXX)\n",
|
||||||
|
"22A = (22B, XXX)\n",
|
||||||
|
"22B = (22C, 22C)\n",
|
||||||
|
"22C = (22Z, 22Z)\n",
|
||||||
|
"22Z = (22B, 22B)\n",
|
||||||
|
"XXX = (XXX, XXX)\n",
|
||||||
|
));
|
||||||
|
let starting_points = find_starting_points(&input.1);
|
||||||
|
assert_eq!(starting_points.len(), 2);
|
||||||
|
assert!(starting_points.contains(&"11A".to_string()));
|
||||||
|
assert!(starting_points.contains(&"22A".to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_part2() {
|
fn test_part2() {
|
||||||
assert_eq!(0, 0);
|
let input = parse(concat!(
|
||||||
|
"LR\n",
|
||||||
|
"\n",
|
||||||
|
"11A = (11B, XXX)\n",
|
||||||
|
"11B = (XXX, 11Z)\n",
|
||||||
|
"11Z = (11B, XXX)\n",
|
||||||
|
"22A = (22B, XXX)\n",
|
||||||
|
"22B = (22C, 22C)\n",
|
||||||
|
"22C = (22Z, 22Z)\n",
|
||||||
|
"22Z = (22B, 22B)\n",
|
||||||
|
"XXX = (XXX, XXX)\n",
|
||||||
|
));
|
||||||
|
assert_eq!(part2(&input), 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue