use std::collections::VecDeque;
-const END_STEP: u32 = 64;
+const END_STEP_PART1: u32 = 64;
+const END_STEP_PART2: u32 = 26501365;
pub fn run(input_file: &str) -> Result<(), Box<dyn Error>> {
let mut f = File::open(input_file)?;
let mut input = String::new();
f.read_to_string(&mut input)?;
- let res = run_part1(&input, END_STEP)?;
+ let res = run_part1(&input, END_STEP_PART1)?;
println!("{res}");
- let res = run_part2(&input)?;
+ let res = run_part2(&input, END_STEP_PART2)?;
println!("{res}");
Ok(())
.filter(|l| !l.is_empty())
.enumerate()
.for_each(|(i, l)| {
- let mut c: Vec<char> = Vec::new();
-
- c.push(' ');
- c.append(&mut l.chars().collect::<Vec<char>>());
- c.push(' ');
-
+ let c: Vec<char> = l.chars().collect();
match c.iter().position(|&a| a == 'S') {
- Some(p) => start = (i + 1, p),
+ Some(p) => start = (i, p),
None => {},
}
-
-
- if i == 0 {
- map.push(vec![' '; c.len()]);
- }
map.push(c);
-
});
- map.push(vec![' '; map[0].len()]);
-
let seen_at_step: Vec<Vec<u32>> = vec![
vec![0 ; map[0].len()]
;
// une fois visitées les cases clignotes
// '.' -> 'O' -> '.' -> 'O'
- pub fn travel(&mut self, end_step: u32) -> u32 {
+ pub fn travel(&mut self, end_step: u32) {
let mut queue: VecDeque<(usize, usize)> = VecDeque::new();
queue.push_back(self.start);
step += 1;
queue = queue_next.clone();
}
+ }
+ fn can_travel_to(&self, n: (usize, usize)) -> bool {
+ self.seen_at_step[n.0][n.1] == 0 && ['.', 'S'].contains(&self.map[n.0][n.1])
+ }
+
+ pub fn reachable(&self, end_step: u32) -> u32 {
self.seen_at_step.iter()
.map(|r| {
r.iter().filter(|&&s| {
})
.sum::<usize>() as u32
}
-
- fn can_travel_to(&self, n: (usize, usize)) -> bool {
- self.seen_at_step[n.0][n.1] == 0 && ['.', 'S'].contains(&self.map[n.0][n.1])
- }
}
fn run_part1(input: &str, end_step: u32) -> Result<u32, Box<dyn Error>> {
let mut puzzle = Puzzle::new(input);
//println!("{:?}", puzzle);
- let res = puzzle.travel(end_step);
+ puzzle.travel(end_step);
+ let res = puzzle.reachable(end_step);
Ok(res)
}
-fn run_part2(input: &str) -> Result<u32, Box<dyn Error>> {
+fn run_part2(input: &str, end_step: u32) -> Result<u32, Box<dyn Error>> {
println!("Running day21 - part 2");
- let res = 0;
+
+ let mut puzzle = Puzzle::new(input);
+ puzzle.travel(end_step);
+ let res = puzzle.reachable(end_step);
Ok(res)
}
}
#[test]
- fn day21_part2() {
- let res = run_part2(TEXT_INPUT);
- assert_eq!(0, res.unwrap());
+ fn day21_part2_example1() {
+ let res = run_part2(TEXT_INPUT, 10);
+ assert_eq!(50, res.unwrap());
+ }
+ #[test]
+ fn day21_part2_example2() {
+ let res = run_part2(TEXT_INPUT, 50);
+ assert_eq!(1594, res.unwrap());
+ }
+ #[test]
+ fn day21_part2_example3() {
+ let res = run_part2(TEXT_INPUT, 100);
+ assert_eq!(6536, res.unwrap());
+ }
+ #[test]
+ fn day21_part2_example4() {
+ let res = run_part2(TEXT_INPUT, 500);
+ assert_eq!(167004, res.unwrap());
+ }
+ #[test]
+ fn day21_part2_example5() {
+ let res = run_part2(TEXT_INPUT, 1000);
+ assert_eq!(668697, res.unwrap());
+ }
+ #[test]
+ fn day21_part2_example6() {
+ let res = run_part2(TEXT_INPUT, 5000);
+ assert_eq!(16733044, res.unwrap());
}
}