day10-11
This commit is contained in:
		
							parent
							
								
									f96ab9d93b
								
							
						
					
					
						commit
						a576f4712f
					
				
							
								
								
									
										133
									
								
								aoc_2024/src/day10.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								aoc_2024/src/day10.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,133 @@ | ||||
| use std::collections::VecDeque; | ||||
| 
 | ||||
| use aoc_runner_derive::{aoc, aoc_generator}; | ||||
| use hashbrown::HashSet; | ||||
| 
 | ||||
| type Input = (usize, usize, Vec<Vec<u8>>); | ||||
| 
 | ||||
| #[aoc_generator(day10)] | ||||
| fn parse(input: &str) -> Input { | ||||
|     let map = input | ||||
|         .lines() | ||||
|         .map(|line| line.chars().map(|c| c as u8 - 48).collect()) | ||||
|         .collect::<Vec<Vec<u8>>>(); | ||||
|     let w = map[0].len(); | ||||
|     let h = map.len(); | ||||
|     (w, h, map) | ||||
| } | ||||
| 
 | ||||
| #[aoc(day10, part1)] | ||||
| fn part1(input: &Input) -> usize { | ||||
|     let mut queue = VecDeque::new(); | ||||
|     let mut paths = HashSet::new(); | ||||
|     let (w, h, map) = input; | ||||
|     let h = *h; | ||||
|     let w = *w; | ||||
|     (0..h).for_each(|y| { | ||||
|         (0..w).for_each(|x| { | ||||
|             if map[y][x] == 0 { | ||||
|                 queue.push_back(((x, y), (x, y))); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| 
 | ||||
|     while !queue.is_empty() { | ||||
|         let (begin, (x, y)) = queue.pop_front().unwrap(); | ||||
|         let val = map[y][x]; | ||||
|         if val == 9 { | ||||
|             paths.insert((begin, (x, y))); | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         if x > 0 && map[y][x - 1] == val + 1 { | ||||
|             queue.push_back((begin, (x - 1, y))); | ||||
|         } | ||||
|         if x < h - 1 && map[y][x + 1] == val + 1 { | ||||
|             queue.push_back((begin, (x + 1, y))); | ||||
|         } | ||||
|         if y > 0 && map[y - 1][x] == val + 1 { | ||||
|             queue.push_back((begin, (x, y - 1))); | ||||
|         } | ||||
|         if y < h - 1 && map[y + 1][x] == val + 1 { | ||||
|             queue.push_back((begin, (x, y + 1))); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     paths.len() | ||||
| } | ||||
| 
 | ||||
| #[aoc(day10, part2)] | ||||
| fn part2(input: &Input) -> u64 { | ||||
|     let mut queue = VecDeque::new(); | ||||
|     let mut starts = Vec::new(); | ||||
|     let (w, h, map) = input; | ||||
|     let h = *h; | ||||
|     let w = *w; | ||||
|     (0..h).for_each(|y| { | ||||
|         (0..w).for_each(|x| { | ||||
|             if map[y][x] == 0 { | ||||
|                 starts.push((x, y)); | ||||
|             } else if map[y][x] == 9 { | ||||
|                 queue.push_back((x, y)); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| 
 | ||||
|     let mut sum = 0; | ||||
| 
 | ||||
|     while !queue.is_empty() { | ||||
|         let (x, y) = queue.pop_front().unwrap(); | ||||
|         let val = map[y][x]; | ||||
|         if val == 0 { | ||||
|             sum += 1; | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         if x > 0 && map[y][x - 1] == val - 1 { | ||||
|             queue.push_back((x - 1, y)); | ||||
|         } | ||||
|         if x < h - 1 && map[y][x + 1] == val - 1 { | ||||
|             queue.push_back((x + 1, y)); | ||||
|         } | ||||
|         if y > 0 && map[y - 1][x] == val - 1 { | ||||
|             queue.push_back((x, y - 1)); | ||||
|         } | ||||
|         if y < h - 1 && map[y + 1][x] == val - 1 { | ||||
|             queue.push_back((x, y + 1)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     sum | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use super::*; | ||||
| 
 | ||||
|     #[test] | ||||
|     fn part1_example() { | ||||
|         assert_eq!(part1(&parse("0123\n1234\n8765\n9876")), 1); | ||||
|         assert_eq!( | ||||
|             part1(&parse( | ||||
|                 "89010123\n78121874\n87430965\n96549874\n45678903\n32019012\n01329801\n10456732" | ||||
|             )), | ||||
|             36 | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn part2_example() { | ||||
|         assert_eq!( | ||||
|             part2(&parse( | ||||
|                 ";;;;;0;\n;;4321;\n;;5;;2;\n;;6543;\n;;7;;4;\n;;8765;\n;;9;;;;" | ||||
|             )), | ||||
|             3 | ||||
|         ); | ||||
|         assert_eq!( | ||||
|             part2(&parse( | ||||
|                 "89010123\n78121874\n87430965\n96549874\n45678903\n32019012\n01329801\n10456732" | ||||
|             )), | ||||
|             81 | ||||
|         ); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										86
									
								
								aoc_2024/src/day11.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								aoc_2024/src/day11.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,86 @@ | ||||
| use std::collections::VecDeque; | ||||
| 
 | ||||
| use aoc_runner_derive::{aoc, aoc_generator}; | ||||
| use hashbrown::{hash_map::Entry, HashMap}; | ||||
| use nom::{ | ||||
|     character::complete::{space1, u64 as parse_usize}, | ||||
|     error::Error, | ||||
|     multi::separated_list1, | ||||
| }; | ||||
| use rayon::prelude::*; | ||||
| 
 | ||||
| type Input = Vec<usize>; | ||||
| 
 | ||||
| #[aoc_generator(day11)] | ||||
| fn parse(input: &str) -> Input { | ||||
|     separated_list1(space1::<&str, Error<&str>>, parse_usize)(input) | ||||
|         .unwrap() | ||||
|         .1 | ||||
|         .into_iter() | ||||
|         .map(|v| v as usize) | ||||
|         .collect() | ||||
| } | ||||
| 
 | ||||
| #[aoc(day11, part1)] | ||||
| fn part1(input: &Input) -> usize { | ||||
|     blink(25, input.clone()) | ||||
| } | ||||
| 
 | ||||
| #[aoc(day11, part2)] | ||||
| fn part2(input: &Input) -> usize { | ||||
|     blink(75, input.clone()) | ||||
| } | ||||
| 
 | ||||
| fn blink(blinks: usize, input: Vec<usize>) -> usize { | ||||
|     let mut stones = HashMap::new(); | ||||
|     for stone in input { | ||||
|         *stones.entry(stone).or_insert(0) += 1; | ||||
|     } | ||||
|     for _ in 0..blinks { | ||||
|         stones = single_blink(stones); | ||||
|     } | ||||
|     stones.values().sum::<usize>() | ||||
| } | ||||
| 
 | ||||
| fn single_blink(stones: HashMap<usize, usize>) -> HashMap<usize, usize> { | ||||
|     let mut new_stones = HashMap::with_capacity(2 << 12); | ||||
| 
 | ||||
|     for (stone, count) in stones { | ||||
|         if stone == 0 { | ||||
|             *new_stones.entry(1).or_insert(0) += count; | ||||
|         } else { | ||||
|             let digits = stone.ilog10() + 1; | ||||
|             if digits % 2 == 0 { | ||||
|                 let left = stone / 10usize.pow(digits / 2); | ||||
|                 let right = stone % 10usize.pow(digits / 2); | ||||
|                 *new_stones.entry(left).or_insert(0) += count; | ||||
|                 *new_stones.entry(right).or_insert(0) += count; | ||||
|             } else { | ||||
|                 *new_stones.entry(stone * 2024).or_insert(0) += count; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     new_stones | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use super::*; | ||||
| 
 | ||||
|     #[test] | ||||
|     fn part1_example() { | ||||
|         assert_eq!( | ||||
|             part1(&parse(include_str!("../input/2024/day11.txt").trim_end())), | ||||
|             203609 | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn part2_example() { | ||||
|         assert_eq!( | ||||
|             part2(&parse(include_str!("../input/2024/day11.txt").trim_end())), | ||||
|             240954878211138 | ||||
|         ); | ||||
|     } | ||||
| } | ||||
| @ -1,4 +1,6 @@ | ||||
| mod day1; | ||||
| mod day10; | ||||
| mod day11; | ||||
| mod day2; | ||||
| mod day3; | ||||
| mod day4; | ||||
|  | ||||
							
								
								
									
										33
									
								
								aoc_2024/src/template.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								aoc_2024/src/template.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | ||||
| use aoc_runner_derive::{aoc, aoc_generator}; | ||||
| 
 | ||||
| type Input = (); | ||||
| 
 | ||||
| #[aoc_generator(day)] | ||||
| fn parse(input: &str) -> Input { | ||||
|     todo!() | ||||
| } | ||||
| 
 | ||||
| #[aoc(day, part1)] | ||||
| fn part1(input: &Input) -> usize { | ||||
|     todo!() | ||||
| } | ||||
| 
 | ||||
| // #[aoc(day, part2)]
 | ||||
| // fn part2(input: &Input) -> usize {
 | ||||
| //     todo!()
 | ||||
| // }
 | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use super::*; | ||||
| 
 | ||||
|     #[test] | ||||
|     fn part1_example() { | ||||
|         assert_eq!(part1(&parse("<EXAMPLE>")), 0); | ||||
|     } | ||||
| 
 | ||||
|     // #[test]
 | ||||
|     // fn part2_example() {
 | ||||
|     //     assert_eq!(part2(&parse("<EXAMPLE>")), 0);
 | ||||
|     // }
 | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Jan-Bulthuis
						Jan-Bulthuis