-
Notifications
You must be signed in to change notification settings - Fork 0
/
d8.rs
86 lines (75 loc) · 2.58 KB
/
d8.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#![allow(clippy::must_use_candidate, clippy::missing_panics_doc)]
use std::collections::HashMap;
use std::string::ToString;
use itertools::{FoldWhile, Itertools};
use num::Integer;
fn parse_input(input: &str) -> (String, HashMap<String, Vec<String>>) {
let (instructions, nodes) = input.split_once("\n\n").unwrap();
let map = nodes
.lines()
.map(|line| {
let (node, children) = line.split_once(" = ").unwrap();
let children = children
.trim_start_matches('(')
.trim_end_matches(')')
.split(", ")
.map(ToString::to_string)
.collect::<Vec<_>>();
(node.to_string(), children)
})
.collect::<HashMap<_, _>>();
(instructions.to_string(), map)
}
pub fn part1(input: &str) -> u64 {
let (instructions, map) = parse_input(input);
instructions
.chars()
.cycle()
.fold_while(
(0, "AAA".to_string()),
|(steps, mut current), instruction| {
if current == "ZZZ" {
return FoldWhile::Done((steps, current));
}
let children = map.get(¤t).unwrap();
current = match instruction {
'L' => children[0].clone(),
'R' => children[1].clone(),
_ => unreachable!(),
};
FoldWhile::Continue((steps + 1, current))
},
)
.into_inner()
.0
}
pub fn part2(input: &str) -> u64 {
let (instructions, map) = parse_input(input);
map.keys()
.filter(|key| key.ends_with('A'))
.cloned()
.map(|mut current| {
instructions
.chars()
.cycle()
.fold_while(0, |steps, instruction| {
if current.ends_with('Z') {
return FoldWhile::Done(steps);
}
let children = map.get(¤t).unwrap();
current = match instruction {
'L' => children[0].clone(),
'R' => children[1].clone(),
_ => unreachable!(),
};
FoldWhile::Continue(steps + 1)
})
.into_inner()
})
.fold(1, |acc, current| acc.lcm(¤t))
}
pub fn main() {
let input = std::fs::read_to_string("../../input/8.txt").expect("Input file not found");
println!("Part 1 : {}", part1(&input));
println!("Part 2 : {}", part2(&input));
}