Day 8.1, 9 and 10, plus formatting and optimization
This commit is contained in:
		
							parent
							
								
									54700e121b
								
							
						
					
					
						commit
						21fcc07f3c
					
				
					 10 changed files with 788 additions and 471 deletions
				
			
		
							
								
								
									
										230
									
								
								src/day02.rs
									
										
									
									
									
								
							
							
						
						
									
										230
									
								
								src/day02.rs
									
										
									
									
									
								
							|  | @ -1,115 +1,115 @@ | ||||||
| use aoc_runner_derive::{aoc, aoc_generator}; | use aoc_runner_derive::{aoc, aoc_generator}; | ||||||
| use std::{error::Error, str::FromStr}; | use std::{error::Error, str::FromStr}; | ||||||
| 
 | 
 | ||||||
| #[derive(Debug, Copy, Clone)] | #[derive(Debug, Copy, Clone)] | ||||||
| enum Direction { | enum Direction { | ||||||
|     Forward, |     Forward, | ||||||
|     Down, |     Down, | ||||||
|     Up, |     Up, | ||||||
| } | } | ||||||
| #[derive(Debug, Copy, Clone)] | #[derive(Debug, Copy, Clone)] | ||||||
| pub struct Instruction { | pub struct Instruction { | ||||||
|     direction: Direction, |     direction: Direction, | ||||||
|     amount: usize, |     amount: usize, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug, Copy, Clone, Default)] | #[derive(Debug, Copy, Clone, Default)] | ||||||
| pub struct Submarine{ | pub struct Submarine { | ||||||
|     depth: i64, |     depth: i64, | ||||||
|     pos: i64, |     pos: i64, | ||||||
|     aim: i64 |     aim: i64, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Submarine { | impl Submarine { | ||||||
|     fn new() -> Self { |     fn new() -> Self { | ||||||
|         Default::default() |         Default::default() | ||||||
|     } |     } | ||||||
|     fn run_p1(&mut self, inst: &Instruction) { |     fn run_p1(&mut self, inst: &Instruction) { | ||||||
|         let d = inst.direction; |         let d = inst.direction; | ||||||
|         let a = inst.amount as i64; |         let a = inst.amount as i64; | ||||||
|         match d { |         match d { | ||||||
|             Direction::Forward => { |             Direction::Forward => { | ||||||
|                 self.pos += a; |                 self.pos += a; | ||||||
|             } |             } | ||||||
|             Direction::Down => { |             Direction::Down => { | ||||||
|                 self.depth += a; |                 self.depth += a; | ||||||
|             } |             } | ||||||
|             Direction::Up => { |             Direction::Up => { | ||||||
|                 self.depth -= a; |                 self.depth -= a; | ||||||
|             } |             } | ||||||
|         }; |         }; | ||||||
|     } |     } | ||||||
|     fn run_p2(&mut self, inst: &Instruction) { |     fn run_p2(&mut self, inst: &Instruction) { | ||||||
|         let d = inst.direction; |         let d = inst.direction; | ||||||
|         let a = inst.amount as i64; |         let a = inst.amount as i64; | ||||||
|         match d { |         match d { | ||||||
|             Direction::Forward => { |             Direction::Forward => { | ||||||
|                 self.pos += a; |                 self.pos += a; | ||||||
|                 self.depth += self.aim*a; |                 self.depth += self.aim * a; | ||||||
|             } |             } | ||||||
|             Direction::Down => { |             Direction::Down => { | ||||||
|                 self.aim += a; |                 self.aim += a; | ||||||
|             } |             } | ||||||
|             Direction::Up => { |             Direction::Up => { | ||||||
|                 self.aim -= a; |                 self.aim -= a; | ||||||
|             } |             } | ||||||
|         }; |         }; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl FromStr for Instruction { | impl FromStr for Instruction { | ||||||
|     type Err = Box<dyn Error>; |     type Err = Box<dyn Error>; | ||||||
| 
 | 
 | ||||||
|     fn from_str(s: &str) -> Result<Self, Self::Err> { |     fn from_str(s: &str) -> Result<Self, Self::Err> { | ||||||
|         let mut s = s.split_ascii_whitespace(); |         let mut s = s.split_ascii_whitespace(); | ||||||
|         let inst = s.next().unwrap(); |         let inst = s.next().unwrap(); | ||||||
|         let amount: usize = s.next().unwrap().parse().unwrap(); |         let amount: usize = s.next().unwrap().parse().unwrap(); | ||||||
|         let ret = match inst { |         let ret = match inst { | ||||||
|             "forward" => Self { |             "forward" => Self { | ||||||
|                 direction: Direction::Forward, |                 direction: Direction::Forward, | ||||||
|                 amount, |                 amount, | ||||||
|             }, |             }, | ||||||
|             "up" => Self { |             "up" => Self { | ||||||
|                 direction: Direction::Up, |                 direction: Direction::Up, | ||||||
|                 amount, |                 amount, | ||||||
|             }, |             }, | ||||||
|             "down" => Self { |             "down" => Self { | ||||||
|                 direction: Direction::Down, |                 direction: Direction::Down, | ||||||
|                 amount, |                 amount, | ||||||
|             }, |             }, | ||||||
|             other => { |             other => { | ||||||
|                 panic!("Invalid instruction: {}", other) |                 panic!("Invalid instruction: {}", other) | ||||||
|             } |             } | ||||||
|         }; |         }; | ||||||
|         Ok(ret) |         Ok(ret) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub type Data = Vec<Instruction>; | pub type Data = Vec<Instruction>; | ||||||
| 
 | 
 | ||||||
| #[aoc_generator(day02)] | #[aoc_generator(day02)] | ||||||
| pub fn input_generator(input: &str) -> Data { | pub fn input_generator(input: &str) -> Data { | ||||||
|     input |     input | ||||||
|         .lines() |         .lines() | ||||||
|         .map(Instruction::from_str) |         .map(Instruction::from_str) | ||||||
|         .collect::<Result<Vec<_>, _>>() |         .collect::<Result<Vec<_>, _>>() | ||||||
|         .unwrap() |         .unwrap() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[aoc(day02, part1)] | #[aoc(day02, part1)] | ||||||
| pub fn solve_part1(input: &Data) -> usize { | pub fn solve_part1(input: &Data) -> usize { | ||||||
|     let mut sm = Submarine::new(); |     let mut sm = Submarine::new(); | ||||||
|     for inst in input { |     for inst in input { | ||||||
|         sm.run_p1(inst); |         sm.run_p1(inst); | ||||||
|     } |     } | ||||||
|     (sm.pos * sm.depth) as usize |     (sm.pos * sm.depth) as usize | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[aoc(day02, part2)] | #[aoc(day02, part2)] | ||||||
| pub fn solve_part2(input: &Data) -> usize { | pub fn solve_part2(input: &Data) -> usize { | ||||||
|     let mut sm = Submarine::new(); |     let mut sm = Submarine::new(); | ||||||
|     for inst in input { |     for inst in input { | ||||||
|         sm.run_p2(inst); |         sm.run_p2(inst); | ||||||
|     } |     } | ||||||
|     (sm.pos * sm.depth) as usize |     (sm.pos * sm.depth) as usize | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										173
									
								
								src/day03.rs
									
										
									
									
									
								
							
							
						
						
									
										173
									
								
								src/day03.rs
									
										
									
									
									
								
							|  | @ -1,91 +1,82 @@ | ||||||
| use aoc_runner_derive::{aoc, aoc_generator}; | use aoc_runner_derive::{aoc, aoc_generator}; | ||||||
| 
 | type Data = Vec<u16>; | ||||||
| type Data = Vec<u16>; | fn make_histogram(input: &[u16]) -> Vec<(usize, i64)> { | ||||||
| 
 |     let counts: &mut [Option<i64>] = &mut [None; 64]; | ||||||
| fn make_histogram(input: &[u16]) -> Vec<(usize, i64)> { |     input.iter().for_each(|val| { | ||||||
|     let counts: &mut [Option<i64>] = &mut [None; 64]; |         for (n, count) in counts.iter_mut().enumerate().take(12) { | ||||||
|     input.iter().for_each(|val| { |             let v = count.get_or_insert(0); | ||||||
|         for (n, count) in counts.iter_mut().enumerate().take(12) { |             if ((val >> n) & 1) == 1 { | ||||||
|             let v = count.get_or_insert(0); |                 *v += 1; | ||||||
|             if ((val >> n) & 1) == 1 { |             } else { | ||||||
|                 *v += 1; |                 *v -= 1; | ||||||
|             } else { |             } | ||||||
|                 *v -= 1; |         } | ||||||
|             } |     }); | ||||||
|         } |     counts.reverse(); | ||||||
|     }); |     counts | ||||||
|     counts.reverse(); |         .iter() | ||||||
|     counts |         .enumerate() | ||||||
|         .iter() |         .filter_map(|(a, b)| b.map(|b| (a, b))) | ||||||
|         .enumerate() |         .collect::<Vec<_>>() | ||||||
|         .filter_map(|(a, b)| b.map(|b| (a, b))) | } | ||||||
|         .collect::<Vec<_>>() | #[aoc_generator(day03)] | ||||||
| } | pub fn input_generator(input: &str) -> Vec<u16> { | ||||||
| 
 |     input | ||||||
| #[aoc_generator(day03)] |         .lines() | ||||||
| pub fn input_generator(input: &str) -> Vec<u16> { |         .map(|l| u16::from_str_radix(l, 2).unwrap()) | ||||||
|     input |         .collect() | ||||||
|         .lines() | } | ||||||
|         .map(|l| u16::from_str_radix(l, 2).unwrap()) | #[derive(Debug)] | ||||||
|         .collect() | enum Mode { | ||||||
| } |     MostCommon, | ||||||
| 
 |     LeastCommon, | ||||||
| 
 | } | ||||||
| #[derive(Debug)] | fn tree_filter(data: &[u16], mut pos: usize, mode: Mode) -> u16 { | ||||||
| enum Mode { |     let (zero, one) = data | ||||||
|     MostCommon, |         .iter() | ||||||
|     LeastCommon, |         .partition::<Vec<u16>, _>(|&v| ((v >> pos) & 1) == 0); | ||||||
| } |      if data.is_empty() { | ||||||
| 
 |         panic!("Uh Oh!"); | ||||||
| fn tree_filter(data: &[u16], pos: usize, mode: Mode) -> u16 { |     } | ||||||
|     let (zero, one) = data |     if data.len() == 1 { | ||||||
|         .iter() |         return data[0]; | ||||||
|         .partition::<Vec<u16>, _>(|&v| ((v >> pos) & 1) == 0); |     } | ||||||
|      if data.is_empty() { |     pos=pos.wrapping_sub(1); | ||||||
|         panic!("Uh Oh!"); |     if zero.len() == one.len() { | ||||||
|     } |         match mode { | ||||||
|     if data.len() == 1 { |             Mode::MostCommon => tree_filter(&one, pos, mode), | ||||||
|         return data[0]; |             Mode::LeastCommon => tree_filter(&zero, pos, mode), | ||||||
|     } |         } | ||||||
|     if zero.len() == one.len() { |     } else { | ||||||
|         match mode { |         let mut srt = vec![zero, one]; | ||||||
|             Mode::MostCommon => tree_filter(&one, pos - 1, mode), |         srt.sort_by_key(|v| v.len()); | ||||||
|             Mode::LeastCommon => tree_filter(&zero, pos - 1, mode), |         match mode { | ||||||
|         } |             Mode::MostCommon => tree_filter(&srt[1], pos, mode), | ||||||
|     } else { |             Mode::LeastCommon => tree_filter(&srt[0], pos, mode), | ||||||
|         let mut srt = vec![zero, one]; |         } | ||||||
|         srt.sort_by_key(|v| v.len()); |     } | ||||||
|         match mode { | } | ||||||
|             Mode::MostCommon => tree_filter(&srt[1], pos - 1, mode), | const ASCII_ZERO: u8 = 0x30; | ||||||
|             Mode::LeastCommon => tree_filter(&srt[0], pos - 1, mode), | #[aoc(day03, part1)] // 1997414
 | ||||||
|         } | pub fn solve_part1(input: &Data) -> usize { | ||||||
|     } |     let counts = make_histogram(input); | ||||||
| } |     let (gamma, epsilon): (String, String) = counts | ||||||
| 
 |         .iter() | ||||||
| 
 |         .map(|(_, v)| { | ||||||
| const ASCII_ZERO: u8 = 0x30; |             ( | ||||||
| 
 |                 (ASCII_ZERO + (*v >= 0) as u8) as char, | ||||||
| #[aoc(day03, part1)] // 1997414
 |                 (ASCII_ZERO + (*v < 0) as u8) as char, | ||||||
| pub fn solve_part1(input: &Data) -> usize { |             ) | ||||||
|     let counts = make_histogram(input); |         }) | ||||||
|     let (gamma, epsilon): (String, String) = counts |         .unzip(); | ||||||
|         .iter() |     let gamma = usize::from_str_radix(&gamma, 2).unwrap(); | ||||||
|         .map(|(_, v)| { |     let epsilon = usize::from_str_radix(&epsilon, 2).unwrap(); | ||||||
|             ( |     gamma * epsilon | ||||||
|                 (ASCII_ZERO + (*v >= 0) as u8) as char, | } | ||||||
|                 (ASCII_ZERO + (*v < 0) as u8) as char, | #[aoc(day03, part2)] // 1032597
 | ||||||
|             ) | pub fn solve_part2(input: &[u16]) -> usize { | ||||||
|         }) |     // let input: Vec<bool> = input.iter().for_each(|v| v[0]).collect();
 | ||||||
|         .unzip(); |     let a = tree_filter(input, 11, Mode::MostCommon) as usize; | ||||||
|     let gamma = usize::from_str_radix(&gamma, 2).unwrap(); |     let b = tree_filter(input, 11, Mode::LeastCommon) as usize; | ||||||
|     let epsilon = usize::from_str_radix(&epsilon, 2).unwrap(); |     a * b | ||||||
|     gamma * epsilon | } | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[aoc(day03, part2)] |  | ||||||
| pub fn solve_part2(input: &[u16]) -> usize { |  | ||||||
|     // let input: Vec<bool> = input.iter().for_each(|v| v[0]).collect();
 |  | ||||||
|     let a = tree_filter(input, 11, Mode::MostCommon) as usize; |  | ||||||
|     let b = tree_filter(input, 11, Mode::LeastCommon) as usize; |  | ||||||
|     a * b |  | ||||||
| } |  | ||||||
							
								
								
									
										239
									
								
								src/day04.rs
									
										
									
									
									
								
							
							
						
						
									
										239
									
								
								src/day04.rs
									
										
									
									
									
								
							|  | @ -1,92 +1,147 @@ | ||||||
| use aoc_runner_derive::{aoc, aoc_generator}; | use aoc_runner_derive::{aoc, aoc_generator}; | ||||||
| 
 | 
 | ||||||
| #[derive(Debug,Clone)] | #[derive(Debug, Clone)] | ||||||
| pub struct Data { | pub struct Data { | ||||||
|     pub numbers: Vec<u8>, |     pub numbers: Vec<u8>, | ||||||
|     pub boards: Vec<[[(u8,bool); 5]; 5]>, |     pub boards: Vec<[[(u8, bool); 5]; 5]>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[aoc_generator(day04)] | #[aoc_generator(day04)] | ||||||
| pub fn input_generator(input: &str) -> Data { | pub fn input_generator(input: &str) -> Data { | ||||||
|     let mut lines = input.lines(); |     let mut lines = input.lines(); | ||||||
|     let mut boards = vec![]; |     let mut boards = vec![]; | ||||||
|     let numbers = lines |     let numbers = lines | ||||||
|         .next() |         .next() | ||||||
|         .unwrap() |         .unwrap() | ||||||
|         .split(',') |         .split(',') | ||||||
|         .map(|s| s.parse()) |         .map(|s| s.parse()) | ||||||
|         .collect::<Result<Vec<u8>, _>>() |         .collect::<Result<Vec<u8>, _>>() | ||||||
|         .unwrap(); |         .unwrap(); | ||||||
|     let mut row = 0; |     let mut row = 0; | ||||||
|     let mut board = [[(0u8,false); 5]; 5]; |     let mut board = [[(0u8, false); 5]; 5]; | ||||||
|     for line in lines { |     for line in lines { | ||||||
|         if line.is_empty() { |         if line.is_empty() { | ||||||
|             continue; |             continue; | ||||||
|         } |         } | ||||||
|         let line = line |         let line = line | ||||||
|             .split_ascii_whitespace() |             .split_ascii_whitespace() | ||||||
|             .map(|s| s.parse()) |             .map(|s| s.parse()) | ||||||
|             .collect::<Result<Vec<u8>, _>>() |             .collect::<Result<Vec<u8>, _>>() | ||||||
|             .unwrap(); |             .unwrap(); | ||||||
|         line.iter().enumerate().for_each(|(i, v)| { |         line.iter().enumerate().for_each(|(i, v)| { | ||||||
|             board[row][i] = (*v,false); |             board[row][i] = (*v, false); | ||||||
|         }); |         }); | ||||||
|         row = (row + 1) % 5; |         row = (row + 1) % 5; | ||||||
|         if row == 0 { |         if row == 0 { | ||||||
|             boards.push(board); |             boards.push(board); | ||||||
|             board = [[(0u8,false); 5]; 5]; |             board = [[(0u8, false); 5]; 5]; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     Data { numbers, boards } |     Data { numbers, boards } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[aoc(day04, part1)] | #[aoc(day04, part1)] | ||||||
| pub fn solve_part1(input: &Data) -> usize { | pub fn solve_part1(input: &Data) -> usize { | ||||||
|     let Data {numbers,mut boards} =input.clone(); |     let Data { | ||||||
|     for number in numbers.iter() { |         numbers, | ||||||
|         for board in &mut boards { |         mut boards, | ||||||
|             for row in board.iter_mut() { |     } = input.clone(); | ||||||
|                 for (n,b) in row { |     for number in numbers.iter() { | ||||||
|                     if n==number { |         for board in &mut boards { | ||||||
|                         *b=true; |             for row in board.iter_mut() { | ||||||
|                     } |                 for (n, b) in row { | ||||||
|                 } |                     if n == number { | ||||||
|             } |                         *b = true; | ||||||
|             let win=(0..5).map(|v| { |                     } | ||||||
|                 [board[v][0],board[v][1],board[v][2],board[v][3],board[v][4]].iter().all(|v| v.1)| |                 } | ||||||
|                 [board[0][v],board[1][v],board[2][v],board[3][v],board[4][v]].iter().all(|v| v.1) |             } | ||||||
|             }).any(|v| v); |             let win = (0..5) | ||||||
|             if win { |                 .map(|v| { | ||||||
|                 return board.iter().flatten().filter_map(|(v,b)| (!*b).then(|| *v as usize)).sum::<usize>()*(*number as usize) |                     [ | ||||||
|             } |                         board[v][0], | ||||||
|         } |                         board[v][1], | ||||||
|     } |                         board[v][2], | ||||||
|     unreachable!() |                         board[v][3], | ||||||
| } |                         board[v][4], | ||||||
| 
 |                     ] | ||||||
| #[aoc(day04, part2)] |                     .iter() | ||||||
| pub fn solve_part2(input: &Data) -> usize { |                     .all(|v| v.1) | ||||||
|     let mut ret=None; |                         | [ | ||||||
|     let Data {numbers,mut boards} =input.clone(); |                             board[0][v], | ||||||
|     let mut board_wins: Vec<bool> = vec![false;boards.len()]; |                             board[1][v], | ||||||
|     for number in numbers.iter() { |                             board[2][v], | ||||||
|         for (board_n,board) in boards.iter_mut().enumerate() { |                             board[3][v], | ||||||
|             for row in board.iter_mut() { |                             board[4][v], | ||||||
|                 for (n,b) in row { |                         ] | ||||||
|                     if n==number { |                         .iter() | ||||||
|                         *b=true; |                         .all(|v| v.1) | ||||||
|                     } |                 }) | ||||||
|                 } |                 .any(|v| v); | ||||||
|             } |             if win { | ||||||
|             let win=(0..5).map(|v| { |                 return board | ||||||
|                 [board[v][0],board[v][1],board[v][2],board[v][3],board[v][4]].iter().all(|v| v.1)| |                     .iter() | ||||||
|                 [board[0][v],board[1][v],board[2][v],board[3][v],board[4][v]].iter().all(|v| v.1) |                     .flatten() | ||||||
|             }).any(|v| v); |                     .filter_map(|(v, b)| (!*b).then(|| *v as usize)) | ||||||
|             if win && !board_wins[board_n] { |                     .sum::<usize>() | ||||||
|                 ret=Some(board.iter().flatten().filter(|(_,b)| !*b).map(|(v,_)| *v as usize).sum::<usize>()*(*number as usize)); |                     * (*number as usize); | ||||||
|                 board_wins[board_n]=true; |             } | ||||||
|             } |         } | ||||||
|         } |     } | ||||||
|     } |     unreachable!() | ||||||
|     return ret.unwrap(); | } | ||||||
| } | 
 | ||||||
|  | #[aoc(day04, part2)] | ||||||
|  | pub fn solve_part2(input: &Data) -> usize { | ||||||
|  |     let mut ret = None; | ||||||
|  |     let Data { | ||||||
|  |         numbers, | ||||||
|  |         mut boards, | ||||||
|  |     } = input.clone(); | ||||||
|  |     let mut board_wins: Vec<bool> = vec![false; boards.len()]; | ||||||
|  |     for number in numbers.iter() { | ||||||
|  |         for (board_n, board) in boards.iter_mut().enumerate() { | ||||||
|  |             for row in board.iter_mut() { | ||||||
|  |                 for (n, b) in row { | ||||||
|  |                     if n == number { | ||||||
|  |                         *b = true; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             let win = (0..5) | ||||||
|  |                 .map(|v| { | ||||||
|  |                     [ | ||||||
|  |                         board[v][0], | ||||||
|  |                         board[v][1], | ||||||
|  |                         board[v][2], | ||||||
|  |                         board[v][3], | ||||||
|  |                         board[v][4], | ||||||
|  |                     ] | ||||||
|  |                     .iter() | ||||||
|  |                     .all(|v| v.1) | ||||||
|  |                         | [ | ||||||
|  |                             board[0][v], | ||||||
|  |                             board[1][v], | ||||||
|  |                             board[2][v], | ||||||
|  |                             board[3][v], | ||||||
|  |                             board[4][v], | ||||||
|  |                         ] | ||||||
|  |                         .iter() | ||||||
|  |                         .all(|v| v.1) | ||||||
|  |                 }) | ||||||
|  |                 .any(|v| v); | ||||||
|  |             if win && !board_wins[board_n] { | ||||||
|  |                 ret = Some( | ||||||
|  |                     board | ||||||
|  |                         .iter() | ||||||
|  |                         .flatten() | ||||||
|  |                         .filter(|(_, b)| !*b) | ||||||
|  |                         .map(|(v, _)| *v as usize) | ||||||
|  |                         .sum::<usize>() | ||||||
|  |                         * (*number as usize), | ||||||
|  |                 ); | ||||||
|  |                 board_wins[board_n] = true; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return ret.unwrap(); | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										216
									
								
								src/day05.rs
									
										
									
									
									
								
							
							
						
						
									
										216
									
								
								src/day05.rs
									
										
									
									
									
								
							|  | @ -1,106 +1,110 @@ | ||||||
| use aoc_runner_derive::{aoc, aoc_generator}; | use aoc_runner_derive::{aoc, aoc_generator}; | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct Line { | pub struct Line { | ||||||
|     x: (i64, i64), |     x: (i64, i64), | ||||||
|     y: (i64, i64), |     y: (i64, i64), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Line { | impl Line { | ||||||
|     fn iter(&self) -> LineIterator { |     fn iter(&self) -> LineIterator { | ||||||
|         let ret= LineIterator { |         let ret = LineIterator { | ||||||
|             line: self, |             line: self, | ||||||
|             px: self.x.0, |             px: self.x.0, | ||||||
|             py: self.y.0, |             py: self.y.0, | ||||||
|             sx: match self.x.0.cmp(&self.x.1) { |             sx: match self.x.0.cmp(&self.x.1) { | ||||||
|                 std::cmp::Ordering::Less => 1, |                 std::cmp::Ordering::Less => 1, | ||||||
|                 std::cmp::Ordering::Equal => 0, |                 std::cmp::Ordering::Equal => 0, | ||||||
|                 std::cmp::Ordering::Greater => -1, |                 std::cmp::Ordering::Greater => -1, | ||||||
|             }, |             }, | ||||||
|             sy: match self.y.0.cmp(&self.y.1) { |             sy: match self.y.0.cmp(&self.y.1) { | ||||||
|                 std::cmp::Ordering::Less => 1, |                 std::cmp::Ordering::Less => 1, | ||||||
|                 std::cmp::Ordering::Equal => 0, |                 std::cmp::Ordering::Equal => 0, | ||||||
|                 std::cmp::Ordering::Greater => -1, |                 std::cmp::Ordering::Greater => -1, | ||||||
|             }, |             }, | ||||||
|         }; |         }; | ||||||
|         assert!(ret.sx!=0||ret.sy!=0); |         assert!(ret.sx != 0 || ret.sy != 0); | ||||||
|         ret |         ret | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| struct LineIterator<'a> { | struct LineIterator<'a> { | ||||||
|     line: &'a Line, |     line: &'a Line, | ||||||
|     px: i64, |     px: i64, | ||||||
|     py: i64, |     py: i64, | ||||||
|     sx: i64, |     sx: i64, | ||||||
|     sy: i64, |     sy: i64, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<'a> Iterator for LineIterator<'a> { | impl<'a> Iterator for LineIterator<'a> { | ||||||
|     type Item = (i64, i64); |     type Item = (i64, i64); | ||||||
| 
 | 
 | ||||||
|     fn next(&mut self) -> Option<Self::Item> { |     fn next(&mut self) -> Option<Self::Item> { | ||||||
|         let ret = (self.px,self.py); |         let ret = (self.px, self.py); | ||||||
|         if self.sx>0 && self.px>self.line.x.1 { |         if self.sx > 0 && self.px > self.line.x.1 { | ||||||
|             return None; |             return None; | ||||||
|         } |         } | ||||||
|         if self.sx<0 && self.px<self.line.x.1 { |         if self.sx < 0 && self.px < self.line.x.1 { | ||||||
|             return None; |             return None; | ||||||
|         } |         } | ||||||
|         if self.sy>0 && self.py>self.line.y.1 { |         if self.sy > 0 && self.py > self.line.y.1 { | ||||||
|             return None; |             return None; | ||||||
|         } |         } | ||||||
|         if self.sy<0 && self.py<self.line.y.1 { |         if self.sy < 0 && self.py < self.line.y.1 { | ||||||
|             return None; |             return None; | ||||||
|         } |         } | ||||||
|         self.px+=self.sx; |         self.px += self.sx; | ||||||
|         self.py+=self.sy; |         self.py += self.sy; | ||||||
|         Some(ret) |         Some(ret) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type Data = Vec<Line>; | type Data = Vec<Line>; | ||||||
| 
 | 
 | ||||||
| #[aoc_generator(day05)] | #[aoc_generator(day05)] | ||||||
| pub fn input_generator(input: &str) -> Data { | pub fn input_generator(input: &str) -> Data { | ||||||
|     input |     input | ||||||
|         .lines() |         .lines() | ||||||
|         .map(|line| { |         .map(|line| { | ||||||
|             let  parts= line.split(" -> ").collect::<Vec<_>>(); |             let parts = line.split(" -> ").collect::<Vec<_>>(); | ||||||
|             let start = parts[0] |             let start = parts[0] | ||||||
|                 .split(',') |                 .split(',') | ||||||
|                 .map(|v| v.parse().unwrap()) |                 .map(|v| v.parse().unwrap()) | ||||||
|                 .collect::<Vec<i64>>(); |                 .collect::<Vec<i64>>(); | ||||||
|             let end = parts[1] |             let end = parts[1] | ||||||
|                 .split(',') |                 .split(',') | ||||||
|                 .map(|v| v.parse().unwrap()) |                 .map(|v| v.parse().unwrap()) | ||||||
|                 .collect::<Vec<i64>>(); |                 .collect::<Vec<i64>>(); | ||||||
|             Line { |             Line { | ||||||
|                 x: (start[0], end[0]), |                 x: (start[0], end[0]), | ||||||
|                 y: (start[1], end[1]), |                 y: (start[1], end[1]), | ||||||
|             } |             } | ||||||
|         }) |         }) | ||||||
|         .collect() |         .collect() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[aoc(day05, part1)] | #[aoc(day05, part1)] | ||||||
| pub fn solve_part1(input: &Data) -> usize { | pub fn solve_part1(input: &Data) -> usize { | ||||||
|     let mut grid = vec![vec![0u8; 1000]; 1000]; |     let mut grid = vec![vec![0u8; 1000]; 1000]; | ||||||
|     for (x,y) in input.iter().filter(|l| l.x.0==l.x.1||l.y.0==l.y.1).flat_map(|v| v.iter()) { |     for (x, y) in input | ||||||
|         let x: usize=x.try_into().unwrap(); |         .iter() | ||||||
|         let y: usize=y.try_into().unwrap(); |         .filter(|l| l.x.0 == l.x.1 || l.y.0 == l.y.1) | ||||||
|         grid[x][y] += 1; |         .flat_map(|v| v.iter()) | ||||||
|     } |     { | ||||||
|     return grid.iter().flatten().filter(|&v| *v > 1).count(); |         let x: usize = x.try_into().unwrap(); | ||||||
| } |         let y: usize = y.try_into().unwrap(); | ||||||
| 
 |         grid[x][y] += 1; | ||||||
| #[aoc(day05, part2)] |     } | ||||||
| pub fn solve_part2(input: &Data) -> usize { |     return grid.iter().flatten().filter(|&v| *v > 1).count(); | ||||||
|     let mut grid = vec![vec![0u8; 1000]; 1000]; | } | ||||||
|     for (x,y) in input.iter().flat_map(|v| v.iter()) { | 
 | ||||||
|         let x: usize=x.try_into().unwrap(); | #[aoc(day05, part2)] | ||||||
|         let y: usize=y.try_into().unwrap(); | pub fn solve_part2(input: &Data) -> usize { | ||||||
|         grid[x][y] += 1; |     let mut grid = vec![vec![0u8; 1000]; 1000]; | ||||||
|     } |     for (x, y) in input.iter().flat_map(|v| v.iter()) { | ||||||
|     return grid.iter().flatten().filter(|&v| *v > 1).count(); |         let x: usize = x.try_into().unwrap(); | ||||||
| } |         let y: usize = y.try_into().unwrap(); | ||||||
|  |         grid[x][y] += 1; | ||||||
|  |     } | ||||||
|  |     return grid.iter().flatten().filter(|&v| *v > 1).count(); | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										64
									
								
								src/day06.rs
									
										
									
									
									
								
							
							
						
						
									
										64
									
								
								src/day06.rs
									
										
									
									
									
								
							|  | @ -1,33 +1,31 @@ | ||||||
| use aoc_runner_derive::{aoc, aoc_generator}; | use aoc_runner_derive::{aoc, aoc_generator}; | ||||||
| 
 | 
 | ||||||
| type Data = [usize;9]; | type Data = [usize; 9]; | ||||||
| 
 | 
 | ||||||
| #[aoc_generator(day06)] | #[aoc_generator(day06)] | ||||||
| pub fn input_generator(input: &str) -> [usize;9] { | pub fn input_generator(input: &str) -> [usize; 9] { | ||||||
|     let mut state: [usize;9] = [0;9]; |     let mut state: [usize; 9] = [0; 9]; | ||||||
|     let input = input.trim().split(',').map(|v| v.parse::<usize>().unwrap()); |     let input = input.trim().split(',').map(|v| v.parse::<usize>().unwrap()); | ||||||
|     for v in input { |     for v in input { | ||||||
|         state[v]+=1; |         state[v] += 1; | ||||||
|     } |     } | ||||||
|     state |     state | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | fn simulate(input: &Data, n: usize) -> usize { | ||||||
| fn simulate(input: &Data,n: usize) -> usize { |     let mut state = *input; | ||||||
|     let mut state=*input; |     for i in 0..n { | ||||||
|     for i in 0..n { |         state[(7 + i) % 9] += state[i % 9]; | ||||||
|         state[(7+i)%9]+=state[i%9]; |     } | ||||||
|     } |     state.iter().sum() | ||||||
|     state.iter().sum() | } | ||||||
| 
 | 
 | ||||||
| } | #[aoc(day06, part1)] // 353274
 | ||||||
| 
 | pub fn solve_part1(input: &Data) -> usize { | ||||||
| #[aoc(day06, part1)] // 353274
 |     simulate(input, 80) | ||||||
| pub fn solve_part1(input: &Data) -> usize { | } | ||||||
|     simulate(input,80) | 
 | ||||||
| } | #[aoc(day06, part2)] // 1609314870967
 | ||||||
| 
 | pub fn solve_part2(input: &Data) -> usize { | ||||||
| #[aoc(day06, part2)] // 1609314870967
 |     simulate(input, 256) | ||||||
| pub fn solve_part2(input: &Data) -> usize { | } | ||||||
|     simulate(input,256) |  | ||||||
| } |  | ||||||
|  |  | ||||||
							
								
								
									
										71
									
								
								src/day07.rs
									
										
									
									
									
								
							
							
						
						
									
										71
									
								
								src/day07.rs
									
										
									
									
									
								
							|  | @ -1,33 +1,38 @@ | ||||||
| use aoc_runner_derive::{aoc, aoc_generator}; | use aoc_runner_derive::{aoc, aoc_generator}; | ||||||
| 
 | 
 | ||||||
| type Data = Vec<i64>; | type Data = Vec<i64>; | ||||||
| 
 | 
 | ||||||
| #[aoc_generator(day07)] | #[aoc_generator(day07)] | ||||||
| pub fn input_generator(input: &str) -> Data { | pub fn input_generator(input: &str) -> Data { | ||||||
|     let mut input: Vec<_> = input.split(',').map(|v| v.parse().unwrap()).collect(); |     let mut input: Vec<_> = input.split(',').map(|v| v.parse().unwrap()).collect(); | ||||||
|     input.sort_unstable(); |     input.sort_unstable(); | ||||||
|     input |     input | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[aoc(day07, part1)] // 336040
 | #[aoc(day07, part1)] // 336040
 | ||||||
| pub fn solve_part1(input: &Data) -> i64 { | pub fn solve_part1(input: &Data) -> i64 { | ||||||
|     let start = *input.first().unwrap(); |     let start = *input.first().unwrap(); | ||||||
|     let end = *input.last().unwrap(); |     let end = *input.last().unwrap(); | ||||||
|     (start..=end).map(|n| { |     (start..=end) | ||||||
|         input.iter().map(|v| { |         .map(|n| input.iter().map(|v| (v - n).abs()).sum()) | ||||||
|             (v-n).abs() |         .min() | ||||||
|         }).sum() |         .unwrap() | ||||||
|     }).min().unwrap() | } | ||||||
| } | 
 | ||||||
| 
 | #[aoc(day07, part2)] // 94813675
 | ||||||
| #[aoc(day07, part2)] // 94813675
 | pub fn solve_part2(input: &Data) -> i64 { | ||||||
| pub fn solve_part2(input: &Data) -> i64 { |     let start = *input.first().unwrap(); | ||||||
|     let start = *input.first().unwrap(); |     let end = *input.last().unwrap(); | ||||||
|     let end = *input.last().unwrap(); |     (start..=end) | ||||||
|     (start..=end).map(|n| { |         .map(|n| { | ||||||
|         input.iter().map(|v| { |             input | ||||||
|             let diff=(v-n).abs(); |                 .iter() | ||||||
|             (diff*(diff+1))>>1 // Gauss
 |                 .map(|v| { | ||||||
|         }).sum() |                     let diff = (v - n).abs(); | ||||||
|     }).min().unwrap() |                     (diff * (diff + 1)) >> 1 // Gauss
 | ||||||
| } |                 }) | ||||||
|  |                 .sum() | ||||||
|  |         }) | ||||||
|  |         .min() | ||||||
|  |         .unwrap() | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										93
									
								
								src/day08.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								src/day08.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,93 @@ | ||||||
|  | use std::collections::{BTreeSet, HashMap, HashSet}; | ||||||
|  | 
 | ||||||
|  | use aoc_runner_derive::{aoc, aoc_generator}; | ||||||
|  | use itertools::Itertools; | ||||||
|  | 
 | ||||||
|  | type Data = HashMap<Vec<String>, Vec<String>>; | ||||||
|  | 
 | ||||||
|  | #[aoc_generator(day08)] | ||||||
|  | pub fn input_generator(input: &str) -> Data { | ||||||
|  |     // let input =
 | ||||||
|  |     //     "acedgfb cdfbe gcdfa fbcad dab cefabd cdfgeb eafb cagedb ab | cdfeb fcadb cdfeb cdbaf";
 | ||||||
|  |     let mut ret = HashMap::new(); | ||||||
|  |     for line in input.lines() { | ||||||
|  |         let mut line = line.split(" | ").map(|v| { | ||||||
|  |             v.split(' ') | ||||||
|  |                 .map(|v| v.chars().sorted().collect::<String>()) | ||||||
|  |                 .collect::<Vec<_>>() | ||||||
|  |         }); | ||||||
|  |         ret.insert(line.next().unwrap(), line.next().unwrap()); | ||||||
|  |     } | ||||||
|  |     ret | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn resolve_overlaps(digits: &HashMap<BTreeSet<char>, HashSet<u8>>) -> HashMap<BTreeSet<char>, u8> { | ||||||
|  |     todo!() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn unshuffle(input: &[String], output: &[String]) -> usize { | ||||||
|  |     let mut results: HashMap<BTreeSet<char>, u8> = HashMap::new(); | ||||||
|  |     // segments -> candidate digits
 | ||||||
|  |     let mut digits: HashMap<BTreeSet<char>, HashSet<u8>> = HashMap::new(); | ||||||
|  |     // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 digits
 | ||||||
|  |     // 6, 2, 5, 5, 4, 5, 6, 3, 7, 6 segments
 | ||||||
|  |     // println!("Unshuffling: {:?} -> {:?}", input, output);
 | ||||||
|  |     // LHS is sub-pattern of RHS
 | ||||||
|  |     let overlap: HashMap<u8,Vec<u8>> = HashMap::from([ | ||||||
|  |         (0,vec![8]), | ||||||
|  |         (1,vec![3,4,7,8,9]), | ||||||
|  |         (2,vec![8]), | ||||||
|  |     ]); | ||||||
|  |     for val in input { | ||||||
|  |         let candidates: Vec<u8> = match val.len() { | ||||||
|  |             2 => vec![1], | ||||||
|  |             3 => vec![7], | ||||||
|  |             4 => vec![4], | ||||||
|  |             5 => vec![2, 5, 3], | ||||||
|  |             6 => vec![6, 9], | ||||||
|  |             7 => vec![8], | ||||||
|  |             _ => unreachable!(), | ||||||
|  |         }; | ||||||
|  |         digits | ||||||
|  |             .entry(val.chars().collect()) | ||||||
|  |             .or_default() | ||||||
|  |             .extend(&candidates); | ||||||
|  |     } | ||||||
|  |     for _ in 0..10 { | ||||||
|  |         // println!("===================");
 | ||||||
|  |         // println!("D: {:?}", digits);
 | ||||||
|  |         // println!("R: {:?}", results);
 | ||||||
|  |         if results.len() == 10 { | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         for (k, v) in &digits { | ||||||
|  |             if v.len() == 1 { | ||||||
|  |                 let c = v.iter().copied().next().unwrap(); | ||||||
|  |                 results.insert(k.clone(), c); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         digits.values_mut().for_each(|v| { | ||||||
|  |             for c in results.values() { | ||||||
|  |                 v.remove(c); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |         digits = digits.drain().filter(|(_, v)| !v.is_empty()).collect(); | ||||||
|  |     } | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[aoc(day08, part1)] // 310
 | ||||||
|  | pub fn solve_part1(input: &Data) -> usize { | ||||||
|  |     input | ||||||
|  |         .values() | ||||||
|  |         .flatten() | ||||||
|  |         .filter(|v| { | ||||||
|  |             [2, 4, 3, 7].contains(&v.len()) | ||||||
|  |         }) | ||||||
|  |         .count() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[aoc(day08, part2)] | ||||||
|  | pub fn solve_part2(input: &Data) -> usize { | ||||||
|  |     input.iter().map(|(k, v)| unshuffle(k, v)).sum() | ||||||
|  | } | ||||||
							
								
								
									
										103
									
								
								src/day09.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								src/day09.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,103 @@ | ||||||
|  | use std::collections::{BTreeSet, VecDeque}; | ||||||
|  | 
 | ||||||
|  | use aoc_runner_derive::{aoc, aoc_generator}; | ||||||
|  | 
 | ||||||
|  | pub struct Data(Vec<Vec<u8>>); | ||||||
|  | 
 | ||||||
|  | impl Data { | ||||||
|  |     fn shape(&self) -> (usize, usize) { | ||||||
|  |         if !self.0.iter().all(|v| v.len() == self.0[0].len()) { | ||||||
|  |             panic!("Not rectangular!"); | ||||||
|  |         } | ||||||
|  |         (self.0.len(), self.0[0].len()) | ||||||
|  |     } | ||||||
|  |     fn get(&self, x: i64, y: i64) -> Option<u8> { | ||||||
|  |         if x < 0 || y < 0 { | ||||||
|  |             return None; | ||||||
|  |         } | ||||||
|  |         self.0 | ||||||
|  |             .get(x as usize) | ||||||
|  |             .map(|v| v.get(y as usize).copied()) | ||||||
|  |             .flatten() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[aoc_generator(day09)] | ||||||
|  | pub fn input_generator(input: &str) -> Data { | ||||||
|  |     Data( | ||||||
|  |         input | ||||||
|  |             .lines() | ||||||
|  |             .map(|l| { | ||||||
|  |                 l.chars() | ||||||
|  |                     .map(|c| c.to_digit(10).unwrap().try_into().unwrap()) | ||||||
|  |                     .collect() | ||||||
|  |             }) | ||||||
|  |             .collect(), | ||||||
|  |     ) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn get_low_points(input: &Data) -> Vec<(i64, i64, u8)> { | ||||||
|  |     let mut ret = vec![]; | ||||||
|  |     let (sx, sy) = input.shape(); | ||||||
|  |     let sx = sx as i64; | ||||||
|  |     let sy = sy as i64; | ||||||
|  |     for x in 0..sx { | ||||||
|  |         for y in 0..sy { | ||||||
|  |             let c = input.get(x, y); | ||||||
|  |             if c.is_none() { | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |             let c = c.unwrap(); | ||||||
|  |             let low_point = input | ||||||
|  |                 .get(x + 1, y) | ||||||
|  |                 .iter() | ||||||
|  |                 .chain(input.get(x - 1, y).iter()) | ||||||
|  |                 .chain(input.get(x, y + 1).iter()) | ||||||
|  |                 .chain(input.get(x, y - 1).iter()) | ||||||
|  |                 .all(|v| v > &c); | ||||||
|  |             if low_point { | ||||||
|  |                 ret.push((x, y, c)) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     ret | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[aoc(day09, part1)] // 468
 | ||||||
|  | pub fn solve_part1(input: &Data) -> usize { | ||||||
|  |     get_low_points(input) | ||||||
|  |         .iter() | ||||||
|  |         .map(|(_, _, v)| (*v as usize) + 1) | ||||||
|  |         .sum() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[aoc(day09, part2)] | ||||||
|  | pub fn solve_part2(input: &Data) -> usize { | ||||||
|  |     let mut basins: BTreeSet<usize> = BTreeSet::new(); | ||||||
|  |     let mut q = VecDeque::new(); | ||||||
|  |     let mut visited = BTreeSet::<(i64, i64)>::new(); | ||||||
|  |     for (x, y, c) in &get_low_points(input) { | ||||||
|  |         visited.clear(); | ||||||
|  |         q.clear(); | ||||||
|  |         q.push_back((*x, *y, *c)); | ||||||
|  |         while let Some((x, y, c)) = q.pop_front() { | ||||||
|  |             if c == 9 || !visited.insert((x, y)) { | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |             for d in [-1, 1] { | ||||||
|  |                 if let Some(v) = input.get(x + d, y) { | ||||||
|  |                     if v > c { | ||||||
|  |                         q.push_back((x + d, y, v)); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 if let Some(v) = input.get(x, y + d) { | ||||||
|  |                     if v > c { | ||||||
|  |                         q.push_back((x, y + d, v)); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         basins.insert(visited.len()); | ||||||
|  |     } | ||||||
|  |     return basins.iter().rev().take(3).product(); | ||||||
|  | } | ||||||
							
								
								
									
										66
									
								
								src/day10.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								src/day10.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,66 @@ | ||||||
|  | use aoc_runner_derive::{aoc, aoc_generator}; | ||||||
|  | type Data = Vec<Vec<char>>; | ||||||
|  | 
 | ||||||
|  | #[aoc_generator(day10)] | ||||||
|  | pub fn input_generator(input: &str) -> Data { | ||||||
|  |     input.lines().map(|l| l.chars().collect()).collect() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub fn error_score(line: &Vec<char>) -> (usize,Vec<char>) { | ||||||
|  |     let mut score=0; | ||||||
|  |     let mut stack=vec![]; | ||||||
|  |     for c in line { | ||||||
|  |         match c { | ||||||
|  |             '(' => {stack.push(')')}, | ||||||
|  |             '[' => {stack.push(']')}, | ||||||
|  |             '{' => {stack.push('}')}, | ||||||
|  |             '<' => {stack.push('>')}, | ||||||
|  |             ')'|']'|'}'|'>' => { | ||||||
|  |                 if let Some(ex) = stack.pop() { | ||||||
|  |                     if ex!=*c { | ||||||
|  |                         score+=match c { | ||||||
|  |                             ')' => 3, | ||||||
|  |                             ']' => 57, | ||||||
|  |                             '}' => 1197, | ||||||
|  |                             '>' => 25137, | ||||||
|  |                             c => unreachable!("Unexpected character {:?}!",c) | ||||||
|  |                         }; | ||||||
|  |                         break; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             }, | ||||||
|  |             c => unreachable!("Unexpected character {:?}!",c) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     (score,stack) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[aoc(day10, part1)] | ||||||
|  | pub fn solve_part1(input: &Data) -> usize { | ||||||
|  |     input.iter().map(|v| error_score(v).0).sum() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[aoc(day10, part2)] | ||||||
|  | pub fn solve_part2(input: &Data) -> usize { | ||||||
|  |     let mut scores=vec![]; | ||||||
|  |     for line in input { | ||||||
|  |         let mut line_score=0; | ||||||
|  |         let (error_score,mut stack) = error_score(line); | ||||||
|  |         stack.reverse(); | ||||||
|  |         if error_score==0 && !stack.is_empty() { | ||||||
|  |             for c in stack { | ||||||
|  |                 line_score*=5; | ||||||
|  |                 line_score+=match c { | ||||||
|  |                     ')' => 1, | ||||||
|  |                     ']' => 2, | ||||||
|  |                     '}' => 3, | ||||||
|  |                     '>' => 4, | ||||||
|  |                     c => unreachable!("Unexpected character {:?}!",c) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             scores.push(line_score); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     scores.sort_unstable(); | ||||||
|  |     scores[scores.len()/2] | ||||||
|  | } | ||||||
|  | @ -1,6 +1,5 @@ | ||||||
| #![allow(clippy::clippy::needless_return)] | #![allow(clippy::clippy::needless_return)] | ||||||
| #![feature(int_abs_diff)] | #![feature(int_abs_diff)] | ||||||
| 
 |  | ||||||
| use aoc_runner_derive::aoc_lib; | use aoc_runner_derive::aoc_lib; | ||||||
| pub mod day01; | pub mod day01; | ||||||
| pub mod day02; | pub mod day02; | ||||||
|  | @ -9,4 +8,7 @@ pub mod day04; | ||||||
| pub mod day05; | pub mod day05; | ||||||
| pub mod day06; | pub mod day06; | ||||||
| pub mod day07; | pub mod day07; | ||||||
|  | pub mod day08; | ||||||
|  | pub mod day09; | ||||||
|  | pub mod day10; | ||||||
| aoc_lib! { year = 2021 } | aoc_lib! { year = 2021 } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue