Day 11
This commit is contained in:
		
							parent
							
								
									cc1cb04b33
								
							
						
					
					
						commit
						fd583e70e4
					
				
					 3 changed files with 192 additions and 5 deletions
				
			
		
							
								
								
									
										10
									
								
								src/day10.rs
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								src/day10.rs
									
										
									
									
									
								
							|  | @ -14,23 +14,23 @@ fn solve_part_2_rec( | |||
|     node: u16, | ||||
|     goal: u16, | ||||
|     map: &HashMap<u16, HashSet<u16>>, | ||||
|     used: &HashSet<u16>, | ||||
|     used: &mut HashSet<u16>, | ||||
|     cache: &mut HashMap<(u16, u16), usize>, | ||||
| ) -> usize { | ||||
|     if node == goal { | ||||
|         return 1; | ||||
|     } | ||||
|     let mut ret = 0; | ||||
|     let mut used = used.clone(); | ||||
|     // println!("+{}", node);
 | ||||
|     for next in map.get(&node).iter().map(|v| v.iter()).flatten() { | ||||
|         if !used.insert(*next) { | ||||
|         if used.contains(next) { | ||||
|             continue; | ||||
|         }; | ||||
|         used.insert(*next); | ||||
|         let value = match cache.get(&(node, *next)) { | ||||
|             Some(value) => *value, | ||||
|             None => { | ||||
|                 let value = solve_part_2_rec(*next, goal, map, &used, cache); | ||||
|                 let value = solve_part_2_rec(*next, goal, map, used, cache); | ||||
|                 cache.insert((node, *next), value); | ||||
|                 value | ||||
|             } | ||||
|  | @ -59,7 +59,7 @@ impl Data { | |||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return solve_part_2_rec(0, goal, &map, &HashSet::new(), &mut HashMap::new()); | ||||
|         return solve_part_2_rec(0, goal, &map, &mut HashSet::new(), &mut HashMap::new()); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										186
									
								
								src/day11.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								src/day11.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,186 @@ | |||
| use aoc_runner_derive::{aoc, aoc_generator}; | ||||
| use std::io::Write; | ||||
| #[derive(Debug, Copy, Clone, Eq, PartialEq)] | ||||
| pub enum Seat { | ||||
|     Floor, | ||||
|     Empty, | ||||
|     Occupied, | ||||
| } | ||||
| 
 | ||||
| pub struct Data(Vec<Vec<Seat>>); | ||||
| 
 | ||||
| impl Data { | ||||
|     fn print(&self) { | ||||
|         for row in &self.0 { | ||||
|             for seat in row { | ||||
|                 let c = match seat { | ||||
|                     Seat::Floor => '.', | ||||
|                     Seat::Empty => 'L', | ||||
|                     Seat::Occupied => '#', | ||||
|                 }; | ||||
|                 print!("{}", c); | ||||
|             } | ||||
|             println!(""); | ||||
|         } | ||||
|     } | ||||
|     fn count_nb_p1(&self, x: usize, y: usize) -> usize { | ||||
|         let mut ret = 0; | ||||
|         for dy in &[-1i64, 0, 1] { | ||||
|             for dx in &[-1i64, 0, 1] { | ||||
|                 if *dx == 0 && *dy == 0 { | ||||
|                     continue; | ||||
|                 } | ||||
|                 let x = ((x as i64) + dx) as usize; | ||||
|                 let y = ((y as i64) + dy) as usize; | ||||
|                 if let Some(v) = self.0.get(y).map(|v| v.get(x)).flatten() { | ||||
|                     match v { | ||||
|                         Seat::Occupied => { | ||||
|                             ret += 1; | ||||
|                         } | ||||
|                         _ => (), | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return ret; | ||||
|     } | ||||
| 
 | ||||
|     fn count_nb_p2(&self, x: usize, y: usize) -> usize { | ||||
|         let mut ret = 0; | ||||
|         for dy in &[-1i64, 0, 1] { | ||||
|             for dx in &[-1i64, 0, 1] { | ||||
|                 if *dx == 0 && *dy == 0 { | ||||
|                     continue; | ||||
|                 } | ||||
|                 for l in 1.. { | ||||
|                     let x = (x as i64) + dx * l; | ||||
|                     let y = (y as i64) + dy * l; | ||||
|                     if x < 0 || y < 0 { | ||||
|                         break; | ||||
|                     } | ||||
|                     if let Some(v) = self.0.get(y as usize).map(|v| v.get(x as usize)).flatten() { | ||||
|                         match v { | ||||
|                             Seat::Occupied => { | ||||
|                                 ret += 1; | ||||
|                                 break; | ||||
|                             } | ||||
|                             Seat::Empty => { | ||||
|                                 break; | ||||
|                             } | ||||
|                             _ => (), | ||||
|                         } | ||||
|                     } else { | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return ret; | ||||
|     } | ||||
| 
 | ||||
|     fn update_p1(&mut self) -> bool { | ||||
|         let mut data = self.0.clone(); | ||||
|         for (y, row) in self.0.iter().enumerate() { | ||||
|             for (x, seat) in row.iter().enumerate() { | ||||
|                 let occupied = self.count_nb_p1(x, y); | ||||
|                 match seat { | ||||
|                     Seat::Floor => {} | ||||
|                     Seat::Empty => { | ||||
|                         if occupied == 0 { | ||||
|                             data[y][x] = Seat::Occupied; | ||||
|                         } | ||||
|                     } | ||||
|                     Seat::Occupied => { | ||||
|                         if occupied > 3 { | ||||
|                             data[y][x] = Seat::Empty; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         let changed = data != self.0; | ||||
|         self.0 = data; | ||||
|         return changed; | ||||
|     } | ||||
| 
 | ||||
|     fn update_p2(&mut self) -> bool { | ||||
|         let mut data = self.0.clone(); | ||||
|         for (y, row) in self.0.iter().enumerate() { | ||||
|             for (x, seat) in row.iter().enumerate() { | ||||
|                 let occupied = self.count_nb_p2(x, y); | ||||
|                 match seat { | ||||
|                     Seat::Floor => {} | ||||
|                     Seat::Empty => { | ||||
|                         if occupied == 0 { | ||||
|                             data[y][x] = Seat::Occupied; | ||||
|                         } | ||||
|                     } | ||||
|                     Seat::Occupied => { | ||||
|                         if occupied > 4 { | ||||
|                             data[y][x] = Seat::Empty; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         let changed = data != self.0; | ||||
|         self.0 = data; | ||||
|         return changed; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[aoc_generator(day11)] | ||||
| pub fn input_generator(input: &str) -> Data { | ||||
|     let ret: Vec<Vec<_>> = input | ||||
|         .trim() | ||||
|         .lines() | ||||
|         .map(|line| { | ||||
|             line.trim() | ||||
|                 .chars() | ||||
|                 .map(|c| match c { | ||||
|                     'L' => Seat::Empty, | ||||
|                     '#' => Seat::Occupied, | ||||
|                     '.' => Seat::Floor, | ||||
|                     c => panic!("invalid character: {:?}", c), | ||||
|                 }) | ||||
|                 .collect() | ||||
|         }) | ||||
|         .collect(); | ||||
|     for line in &ret { | ||||
|         if ret[0].len() != line.len() { | ||||
|             panic!("Non rectangular input!"); | ||||
|         } | ||||
|     } | ||||
|     Data(ret) | ||||
| } | ||||
| 
 | ||||
| #[aoc(day11, part1)] | ||||
| pub fn solve_part1(input: &Data) -> usize { | ||||
|     let mut input = Data(input.0.clone()); | ||||
|     let mut n = 0; | ||||
|     while input.update_p1() {} | ||||
|     for row in &input.0 { | ||||
|         for seat in row { | ||||
|             if *seat == Seat::Occupied { | ||||
|                 n += 1; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     return n; | ||||
| } | ||||
| 
 | ||||
| #[aoc(day11, part2)] | ||||
| pub fn solve_part2(input: &Data) -> usize { | ||||
|     let mut input = Data(input.0.clone()); | ||||
|     while input.update_p2() {} | ||||
| 
 | ||||
|     let mut n = 0; | ||||
|     for row in &input.0 { | ||||
|         for seat in row { | ||||
|             if *seat == Seat::Occupied { | ||||
|                 n += 1; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     return n; | ||||
| } | ||||
|  | @ -9,4 +9,5 @@ pub mod day07; | |||
| pub mod day08; | ||||
| pub mod day09; | ||||
| pub mod day10; | ||||
| pub mod day11; | ||||
| aoc_lib! { year = 2020 } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue