Day 13+formatting
This commit is contained in:
		
							parent
							
								
									7743a1cdc6
								
							
						
					
					
						commit
						d9e4bf6ad3
					
				
					 4 changed files with 232 additions and 157 deletions
				
			
		
							
								
								
									
										3
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							|  | @ -1,3 +1,4 @@ | |||
| /target | ||||
| .history | ||||
| input | ||||
| input | ||||
| src/template.rs | ||||
							
								
								
									
										311
									
								
								src/day12.rs
									
										
									
									
									
								
							
							
						
						
									
										311
									
								
								src/day12.rs
									
										
									
									
									
								
							|  | @ -1,156 +1,155 @@ | |||
| use aoc_runner_derive::{aoc, aoc_generator}; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub enum Direction { | ||||
|     North, | ||||
|     East, | ||||
|     South, | ||||
|     West | ||||
| } | ||||
| 
 | ||||
| impl Direction { | ||||
|     fn from_int(n: i64) -> Self { | ||||
|         match n%4 { | ||||
|             0 => Self::East, | ||||
|             1 => Self::South, | ||||
|             2 => Self::West, | ||||
|             3 => Self::North, | ||||
|             _ => unreachable!() | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub enum Command { | ||||
|     Direction(Direction,i64), | ||||
|     Left(i64), | ||||
|     Right(i64), | ||||
|     Forward(i64) | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct Ship { | ||||
|     rot: i64, | ||||
|     pos: (i64,i64), | ||||
|     wp: (i64,i64) | ||||
| } | ||||
| 
 | ||||
| impl Ship { | ||||
|     fn new() -> Self { | ||||
|         Self { | ||||
|             rot:0, | ||||
|             pos: (0,0), | ||||
|             wp: (10,1) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn facing(&self) -> Direction { | ||||
|         Direction::from_int(self.rot) | ||||
|     } | ||||
| 
 | ||||
|     fn cmd_p1(&mut self, cmd: &Command) { | ||||
|         match cmd { | ||||
|             Command::Direction(Direction::North,n) => { | ||||
|                 self.pos.1+=n; | ||||
|             } | ||||
|             Command::Direction(Direction::South,n) => { | ||||
|                 self.pos.1-=n; | ||||
|             } | ||||
|             Command::Direction(Direction::East,n) => { | ||||
|                 self.pos.0+=n; | ||||
|             } | ||||
|             Command::Direction(Direction::West,n) => { | ||||
|                 self.pos.0-=n; | ||||
|             } | ||||
|             Command::Left(n) => { | ||||
|                 self.rot-=n; | ||||
|             } | ||||
|             Command::Right(n) => { | ||||
|                 self.rot+=n; | ||||
|             } | ||||
|             Command::Forward(n) => { | ||||
|                 self.cmd_p1(&Command::Direction(self.facing(),*n)) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn cmd_p2(&mut self, cmd: &Command) { | ||||
|         match cmd { | ||||
|             Command::Direction(Direction::North,n) => { | ||||
|                 self.wp.1+=n; | ||||
|             } | ||||
|             Command::Direction(Direction::South,n) => { | ||||
|                 self.wp.1-=n; | ||||
|             } | ||||
|             Command::Direction(Direction::East,n) => { | ||||
|                 self.wp.0+=n; | ||||
|             } | ||||
|             Command::Direction(Direction::West,n) => { | ||||
|                 self.wp.0-=n; | ||||
|             } | ||||
|             Command::Right(n) => { | ||||
|                 let wp=self.wp; | ||||
|                 self.wp=match n%4 { | ||||
|                     0 => wp, | ||||
|                     1 => (wp.1,-wp.0), | ||||
|                     2 => (-wp.0,-wp.1), | ||||
|                     3 => (-wp.1,wp.0), | ||||
|                     _ => unreachable!() | ||||
|                 }; | ||||
|             } | ||||
|             Command::Left(n) => { | ||||
|                 let wp=self.wp; | ||||
|                 self.wp=match n%4 { | ||||
|                     0 => wp, | ||||
|                     1 => (-wp.1,wp.0), | ||||
|                     2 => (-wp.0,-wp.1), | ||||
|                     3 => (wp.1,-wp.0), | ||||
|                     _ => unreachable!() | ||||
|                 }; | ||||
|             } | ||||
|             Command::Forward(n) => { | ||||
|                 self.pos.0+=self.wp.0*n; | ||||
|                 self.pos.1+=self.wp.1*n; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[aoc_generator(day12)] | ||||
| pub fn input_generator(input: &str) -> Vec<Command> { | ||||
|     input | ||||
|         .lines() | ||||
|         .map(|l| { | ||||
|             let mut chars=l.chars(); | ||||
|             let cmd=chars.next().unwrap(); | ||||
|             let num = chars.collect::<String>().parse().unwrap(); | ||||
|             match cmd { | ||||
|                 'N' => Command::Direction(Direction::North, num), | ||||
|                 'S' => Command::Direction(Direction::South,num), | ||||
|                 'E' => Command::Direction(Direction::East,num), | ||||
|                 'W' => Command::Direction(Direction::West,num), | ||||
|                 'L' if num%90==0 => Command::Left((num/90)%4), | ||||
|                 'R' if num%90==0 => Command::Right((num/90)%4), | ||||
|                 'F' => Command::Forward(num), | ||||
|                 _ => panic!("Invalid command: {}",l) | ||||
|             } | ||||
|         }).collect::<Vec<Command>>() | ||||
| } | ||||
| 
 | ||||
| #[aoc(day12, part1)] | ||||
| pub fn solve_part1(input: &Vec<Command>) -> usize { | ||||
|     let mut ship=Ship::new(); | ||||
|     for cmd in input { | ||||
|         ship.cmd_p1(cmd); | ||||
|     } | ||||
|     return (ship.pos.0.abs() as usize) + (ship.pos.1.abs() as usize); | ||||
| } | ||||
| 
 | ||||
| #[aoc(day12, part2)] | ||||
| pub fn solve_part2(input: &Vec<Command>) -> usize { | ||||
|     let mut ship=Ship::new(); | ||||
|     for cmd in input { | ||||
|         ship.cmd_p2(cmd); | ||||
|     } | ||||
|     return (ship.pos.0.abs() as usize) + (ship.pos.1.abs() as usize); | ||||
| } | ||||
| use aoc_runner_derive::{aoc, aoc_generator}; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub enum Direction { | ||||
|     North, | ||||
|     East, | ||||
|     South, | ||||
|     West, | ||||
| } | ||||
| 
 | ||||
| impl Direction { | ||||
|     fn from_int(n: i64) -> Self { | ||||
|         match n % 4 { | ||||
|             0 => Self::East, | ||||
|             1 => Self::South, | ||||
|             2 => Self::West, | ||||
|             3 => Self::North, | ||||
|             _ => unreachable!(), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub enum Command { | ||||
|     Direction(Direction, i64), | ||||
|     Left(i64), | ||||
|     Right(i64), | ||||
|     Forward(i64), | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct Ship { | ||||
|     rot: i64, | ||||
|     pos: (i64, i64), | ||||
|     wp: (i64, i64), | ||||
| } | ||||
| 
 | ||||
| impl Ship { | ||||
|     fn new() -> Self { | ||||
|         Self { | ||||
|             rot: 0, | ||||
|             pos: (0, 0), | ||||
|             wp: (10, 1), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn facing(&self) -> Direction { | ||||
|         Direction::from_int(self.rot) | ||||
|     } | ||||
| 
 | ||||
|     fn cmd_p1(&mut self, cmd: &Command) { | ||||
|         match cmd { | ||||
|             Command::Direction(Direction::North, n) => { | ||||
|                 self.pos.1 += n; | ||||
|             } | ||||
|             Command::Direction(Direction::South, n) => { | ||||
|                 self.pos.1 -= n; | ||||
|             } | ||||
|             Command::Direction(Direction::East, n) => { | ||||
|                 self.pos.0 += n; | ||||
|             } | ||||
|             Command::Direction(Direction::West, n) => { | ||||
|                 self.pos.0 -= n; | ||||
|             } | ||||
|             Command::Left(n) => { | ||||
|                 self.rot -= n; | ||||
|             } | ||||
|             Command::Right(n) => { | ||||
|                 self.rot += n; | ||||
|             } | ||||
|             Command::Forward(n) => self.cmd_p1(&Command::Direction(self.facing(), *n)), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn cmd_p2(&mut self, cmd: &Command) { | ||||
|         match cmd { | ||||
|             Command::Direction(Direction::North, n) => { | ||||
|                 self.wp.1 += n; | ||||
|             } | ||||
|             Command::Direction(Direction::South, n) => { | ||||
|                 self.wp.1 -= n; | ||||
|             } | ||||
|             Command::Direction(Direction::East, n) => { | ||||
|                 self.wp.0 += n; | ||||
|             } | ||||
|             Command::Direction(Direction::West, n) => { | ||||
|                 self.wp.0 -= n; | ||||
|             } | ||||
|             Command::Right(n) => { | ||||
|                 let wp = self.wp; | ||||
|                 self.wp = match n % 4 { | ||||
|                     0 => wp, | ||||
|                     1 => (wp.1, -wp.0), | ||||
|                     2 => (-wp.0, -wp.1), | ||||
|                     3 => (-wp.1, wp.0), | ||||
|                     _ => unreachable!(), | ||||
|                 }; | ||||
|             } | ||||
|             Command::Left(n) => { | ||||
|                 let wp = self.wp; | ||||
|                 self.wp = match n % 4 { | ||||
|                     0 => wp, | ||||
|                     1 => (-wp.1, wp.0), | ||||
|                     2 => (-wp.0, -wp.1), | ||||
|                     3 => (wp.1, -wp.0), | ||||
|                     _ => unreachable!(), | ||||
|                 }; | ||||
|             } | ||||
|             Command::Forward(n) => { | ||||
|                 self.pos.0 += self.wp.0 * n; | ||||
|                 self.pos.1 += self.wp.1 * n; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[aoc_generator(day12)] | ||||
| pub fn input_generator(input: &str) -> Vec<Command> { | ||||
|     input | ||||
|         .lines() | ||||
|         .map(|l| { | ||||
|             let mut chars = l.chars(); | ||||
|             let cmd = chars.next().unwrap(); | ||||
|             let num = chars.collect::<String>().parse().unwrap(); | ||||
|             match cmd { | ||||
|                 'N' => Command::Direction(Direction::North, num), | ||||
|                 'S' => Command::Direction(Direction::South, num), | ||||
|                 'E' => Command::Direction(Direction::East, num), | ||||
|                 'W' => Command::Direction(Direction::West, num), | ||||
|                 'L' if num % 90 == 0 => Command::Left((num / 90) % 4), | ||||
|                 'R' if num % 90 == 0 => Command::Right((num / 90) % 4), | ||||
|                 'F' => Command::Forward(num), | ||||
|                 _ => panic!("Invalid command: {}", l), | ||||
|             } | ||||
|         }) | ||||
|         .collect::<Vec<Command>>() | ||||
| } | ||||
| 
 | ||||
| #[aoc(day12, part1)] | ||||
| pub fn solve_part1(input: &Vec<Command>) -> usize { | ||||
|     let mut ship = Ship::new(); | ||||
|     for cmd in input { | ||||
|         ship.cmd_p1(cmd); | ||||
|     } | ||||
|     return (ship.pos.0.abs() as usize) + (ship.pos.1.abs() as usize); | ||||
| } | ||||
| 
 | ||||
| #[aoc(day12, part2)] | ||||
| pub fn solve_part2(input: &Vec<Command>) -> usize { | ||||
|     let mut ship = Ship::new(); | ||||
|     for cmd in input { | ||||
|         ship.cmd_p2(cmd); | ||||
|     } | ||||
|     return (ship.pos.0.abs() as usize) + (ship.pos.1.abs() as usize); | ||||
| } | ||||
|  |  | |||
							
								
								
									
										74
									
								
								src/day13.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								src/day13.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,74 @@ | |||
| use aoc_runner_derive::{aoc, aoc_generator}; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct BusInfo { | ||||
|     earliest: u64, | ||||
|     busses: Vec<u64>, | ||||
| } | ||||
| 
 | ||||
| type Data = BusInfo; | ||||
| 
 | ||||
| #[aoc_generator(day13)] | ||||
| pub fn input_generator(input: &str) -> Data { | ||||
|     let mut l = input.lines(); | ||||
|     let earliest = l.next().unwrap().parse().unwrap(); | ||||
|     let busses = l | ||||
|         .next() | ||||
|         .unwrap() | ||||
|         .split(',') | ||||
|         .map(|c| match c { | ||||
|             "x" => 0, | ||||
|             n => n.parse().unwrap(), | ||||
|         }) | ||||
|         .collect(); | ||||
|     BusInfo { earliest, busses } | ||||
| } | ||||
| 
 | ||||
| #[aoc(day13, part1)] | ||||
| pub fn solve_part1(input: &Data) -> usize { | ||||
|     let e = input.earliest; | ||||
|     let mut min = std::u64::MAX; | ||||
|     let mut min_id = 0; | ||||
|     for n in &input.busses { | ||||
|         if *n == 0 { | ||||
|             continue; | ||||
|         } | ||||
|         let m = n - (e % n); | ||||
|         if m < min { | ||||
|             min = m; | ||||
|             min_id = *n; | ||||
|         } | ||||
|     } | ||||
|     return min as usize * min_id as usize; | ||||
| } | ||||
| 
 | ||||
| #[aoc(day13, part2)] | ||||
| pub fn solve_part2(input: &Data) -> i64 { | ||||
|     let b = input | ||||
|         .busses | ||||
|         .iter() | ||||
|         .enumerate() | ||||
|         .filter(|(_, n)| **n != 0) | ||||
|         .map(|(a, b)| (a as i64, *b as i64)) | ||||
|         .collect::<Vec<_>>(); | ||||
|     let mut t = 0; | ||||
|     let target = b.iter().map(|(_, b)| b).fold(1, |a, b| a * b); | ||||
|     loop { | ||||
|         let mut cnt = 0; | ||||
|         let dt = b | ||||
|             .iter() | ||||
|             .filter_map(|(i, n)| { | ||||
|                 if (t + i) % n == 0 { | ||||
|                     cnt += 1; | ||||
|                     Some(*n) | ||||
|                 } else { | ||||
|                     None | ||||
|                 } | ||||
|             }) | ||||
|             .fold(1, |a, b| a * b); | ||||
|         if dt == target { | ||||
|             return t % dt; | ||||
|         } | ||||
|         t += dt; | ||||
|     } | ||||
| } | ||||
|  | @ -11,4 +11,5 @@ pub mod day09; | |||
| pub mod day10; | ||||
| pub mod day11; | ||||
| pub mod day12; | ||||
| pub mod day13; | ||||
| aoc_lib! { year = 2020 } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue