days 14 and 15 i suppose!
This commit is contained in:
		
							parent
							
								
									dda3e2d511
								
							
						
					
					
						commit
						51777c2af8
					
				
							
								
								
									
										7
									
								
								day14/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								day14/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| [package] | ||||
| name = "day14" | ||||
| version = "0.1.0" | ||||
| edition = "2021" | ||||
| 
 | ||||
| [dependencies] | ||||
| regex = "1.11.1" | ||||
							
								
								
									
										116
									
								
								day14/src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								day14/src/main.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,116 @@ | ||||
| use std::collections::HashSet; | ||||
| use regex::Regex; | ||||
| use std::env; | ||||
| 
 | ||||
| use std::fs; | ||||
| 
 | ||||
| use crate::Dir::{North, South, East, West }; | ||||
| 
 | ||||
| type Coord = (i128, i128); | ||||
| #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] | ||||
| enum Dir { North, South, East, West } | ||||
| 
 | ||||
| fn step(start: &Coord, d: Dir, steps: i128) -> Coord { | ||||
|     match d { | ||||
|         North => (start.0, start.1 - steps), | ||||
|         South => (start.0, start.1 + steps), | ||||
|         East => (start.0 + steps, start.1), | ||||
|         West => (start.0 - steps, start.1), | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn walk(start: &Coord, diff: &Coord) -> Coord { | ||||
|     (start.0 + diff.0, start.1 + diff.1) | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Copy, Clone)] | ||||
| struct Robot { start: Coord, velocity: Coord } | ||||
| 
 | ||||
| fn main() { | ||||
|     println!("Hello, AoC day 13!"); | ||||
| 
 | ||||
|     let args: Vec<String> = env::args().collect(); | ||||
|     if args.len() != 2 { | ||||
|         println!("wrong number of arguments!"); | ||||
|         std::process::exit(1); | ||||
|     } | ||||
| 
 | ||||
|     let file_path = &args[1]; | ||||
| 
 | ||||
|     let find_record = Regex::new(r"p=([0-9]+),([0-9]+) v=(-?[0-9]+),(-?[0-9]+)").unwrap(); | ||||
| 
 | ||||
|     let binding = fs::read_to_string(file_path) | ||||
|         .expect("should be able to read the file"); | ||||
|     let robots = binding.lines() | ||||
|         .filter_map(|l| find_record.captures(l) ) | ||||
|         .map(|caps| Robot { | ||||
|             start: (caps[1].parse().unwrap(), caps[2].parse().unwrap()), | ||||
|             velocity: (caps[3].parse().unwrap(), caps[4].parse().unwrap()) 
 | ||||
|         }) | ||||
|         .collect::<Vec<Robot>>(); | ||||
| 
 | ||||
|     let corner = (101, 103); | ||||
| 
 | ||||
|     let mut new_robots = robots.clone(); | ||||
|     for _ in 0..100 { iterate(&mut new_robots, corner); } | ||||
|     println!("the safety factor after 100 seconsd is {}", safety_factor(&mut new_robots, corner)); | ||||
| 
 | ||||
|     let seconds = 17774; | ||||
| 
 | ||||
|     let mut new_robots = robots.clone(); | ||||
|     iterate_n(&mut new_robots, corner, seconds); | ||||
|     print_scene(&new_robots, corner); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| fn iterate(robots: &mut Vec<Robot>, corner: Coord) -> usize { | ||||
|     let mut positions: HashSet<Coord> = HashSet::new(); | ||||
|     for r in robots { | ||||
|         r.start.0 = (r.start.0 + r.velocity.0).rem_euclid(corner.0); | ||||
|         r.start.1 = (r.start.1 + r.velocity.1).rem_euclid(corner.1); | ||||
|         positions.insert(r.start); | ||||
|     } | ||||
|     return positions.len(); | ||||
| } | ||||
| 
 | ||||
| fn iterate_n(robots: &mut Vec<Robot>, corner: Coord, seconds: i128) -> usize { | ||||
|     let mut positions: HashSet<Coord> = HashSet::new(); | ||||
|     for r in robots { | ||||
|         r.start.0 = (r.start.0 + r.velocity.0*seconds).rem_euclid(corner.0); | ||||
|         r.start.1 = (r.start.1 + r.velocity.1*seconds).rem_euclid(corner.1); | ||||
|         positions.insert(r.start); | ||||
|     } | ||||
|     return positions.len(); | ||||
| } | ||||
| 
 | ||||
| fn print_scene(robots: &Vec<Robot>, corner: Coord) { | ||||
|     let mut positions: HashSet<Coord> = HashSet::new(); | ||||
|     for Robot {start, velocity: _} in robots.iter() { | ||||
|         positions.insert(*start); | ||||
|     } | ||||
|     for x in 0..corner.0 { | ||||
|         for y in 0..corner.1 { | ||||
|             print!("{}", if positions.contains(&(x,y)) { "#" } else { "." }); | ||||
|         } | ||||
|         print!("\n"); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn safety_factor(robots: &mut Vec<Robot>, corner: Coord) -> i128 { | ||||
|     let mut q: [i128; 4] = [0,0,0,0]; | ||||
| 
 | ||||
|     let halfs = ((corner.0 - 1) / 2, (corner.1 - 1) / 2); | ||||
|     for Robot { start, velocity: _ } in robots { | ||||
|         if start.0 < halfs.0 && start.1 < halfs.1 { | ||||
|             q[0] += 1; | ||||
|         } else if start.0 > halfs.0 && start.1 < halfs.1 { | ||||
|             q[1] += 1; | ||||
|         } else if start.0 < halfs.0 && start.1 > halfs.1  { | ||||
|             q[2] += 1; | ||||
|         } else if start.0 > halfs.0 && start.1 > halfs.1 { | ||||
|             q[3] += 1; | ||||
|         } | ||||
|     } | ||||
|     
 | ||||
|     return q[0]*q[1]*q[2]*q[3]; | ||||
| } | ||||
							
								
								
									
										7
									
								
								day15/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								day15/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| [package] | ||||
| name = "day15" | ||||
| version = "0.1.0" | ||||
| edition = "2021" | ||||
| 
 | ||||
| [dependencies] | ||||
| itertools = "0.13.0" | ||||
							
								
								
									
										228
									
								
								day15/src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										228
									
								
								day15/src/main.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,228 @@ | ||||
| use std::collections::HashMap; | ||||
| use std::collections::HashSet; | ||||
| 
 | ||||
| use std::env; | ||||
| use std::fs; | ||||
| 
 | ||||
| use itertools::Itertools; | ||||
| 
 | ||||
| use crate::Dir::{North, South, East, West }; | ||||
| 
 | ||||
| type Coord = (i32, i32); | ||||
| #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] | ||||
| enum Dir { North, South, East, West } | ||||
| 
 | ||||
| fn step(start: &Coord, d: Dir, steps: i32) -> Coord { | ||||
|     match d { | ||||
|         North => (start.0, start.1 - steps), | ||||
|         South => (start.0, start.1 + steps), | ||||
|         East => (start.0 + steps, start.1), | ||||
|         West => (start.0 - steps, start.1), | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn main() { | ||||
|     println!("Hello, AoC day 13!"); | ||||
| 
 | ||||
|     let args: Vec<String> = env::args().collect(); | ||||
|     if args.len() != 2 { | ||||
|         println!("wrong number of arguments!"); | ||||
|         std::process::exit(1); | ||||
|     } | ||||
| 
 | ||||
|     let file_path = &args[1]; | ||||
| 
 | ||||
|     let binding = fs::read_to_string(file_path) | ||||
|         .expect("should be able to read the file"); | ||||
|     let (map_string, instructions_string) = binding | ||||
|         .split_once("\n\n") | ||||
|         .expect("should have a map and an instructions section"); | ||||
| 
 | ||||
|     let mut map = HashMap::new(); | ||||
| 
 | ||||
|     let mut robot = (0,0); | ||||
|     let mut y = 0; | ||||
|     for line in map_string.lines() { | ||||
|         let mut x = 0; | ||||
|         for c in line.chars() { | ||||
|             if c == '@' { | ||||
|                 robot = (x,y); | ||||
|                 map.insert((x,y), '.'); | ||||
|             } else { | ||||
|                 map.insert((x,y), c); | ||||
|             } | ||||
|             x += 1; | ||||
|         } | ||||
|         y += 1; | ||||
|     } | ||||
| 
 | ||||
|     let binding = instructions_string | ||||
|         .lines() | ||||
|         .join(""); | ||||
|     let instructions = binding | ||||
|         .chars() | ||||
|         .map(|c| match c { '^'=>North, '>'=>East, 'v'=>South, '<'=>West, _=>North }); | ||||
| 
 | ||||
|     for direction in instructions { 
 | ||||
|         let next = step(&robot, direction, 1); | ||||
|         let neighbor = map.get(&next); | ||||
|         if neighbor == Some(&'.') { | ||||
|             robot = next; | ||||
|         } else if neighbor == Some(&'#') { | ||||
|             continue; | ||||
|         } else if neighbor == Some(&'O') { | ||||
|             let mut steps = 1; | ||||
|             let mut stack_top = map.get(&step(&robot, direction, steps)); | ||||
|             while stack_top == Some(&'O') { | ||||
|                 steps = steps + 1; | ||||
|                 stack_top = map.get(&step(&robot, direction, steps)); | ||||
|             } | ||||
|             if stack_top == Some(&'.') { | ||||
|                 map.insert(step(&robot, direction, steps), 'O'); | ||||
|                 map.insert(next, '.'); | ||||
|                 robot = next; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     println!("the gps score after all the instructions is {}", sum_of_box_gps(&map)); | ||||
| 
 | ||||
|     let mut map = HashMap::new(); | ||||
| 
 | ||||
|     let mut robot = (0,0); | ||||
|     let mut y = 0; | ||||
|     for line in map_string.lines() { | ||||
|         let mut x = 0; | ||||
|         for c in line.chars() { | ||||
|             match c { | ||||
|                 '@' => { | ||||
|                     robot = (2*x,y); | ||||
|                     map.insert((2*x,y), '.'); | ||||
|                     map.insert((2*x+1,y), '.'); | ||||
|                 }, | ||||
|                 '.' => { | ||||
|                     map.insert((2*x, y), '.'); | ||||
|                     map.insert((2*x+1, y), '.'); | ||||
|                 }, | ||||
|                 'O' => { | ||||
|                     map.insert((2*x, y), '['); | ||||
|                     map.insert((2*x+1, y), ']'); | ||||
|                 }, | ||||
|                 '#' => { | ||||
|                     map.insert((2*x, y), '#'); | ||||
|                     map.insert((2*x+1, y), '#'); | ||||
|                 }, | ||||
|                 _ => { | ||||
|                     map.insert((2*x, y), '.'); | ||||
|                     map.insert((2*x+1, y), '.'); | ||||
|                 } | ||||
|             } | ||||
|             x += 1; | ||||
|         } | ||||
|         y += 1; | ||||
|     } | ||||
| 
 | ||||
|     let binding = instructions_string | ||||
|         .lines() | ||||
|         .join(""); | ||||
|     let instructions = binding | ||||
|         .chars() | ||||
|         .map(|c| match c { '^'=>North, '>'=>East, 'v'=>South, '<'=>West, _=>North }); | ||||
| 
 | ||||
|     for direction in instructions { 
 | ||||
|         let next = step(&robot, direction, 1); | ||||
|         let neighbor = map.get(&next); | ||||
|         if neighbor == Some(&'.') { | ||||
|             robot = next; | ||||
|         } else if neighbor == Some(&'#') { | ||||
|             continue; | ||||
|         } else if neighbor == Some(&'[') || neighbor == Some(&']') { | ||||
|             let mut boxes_to_move: HashSet<Coord> = HashSet::new(); | ||||
|             let mut unexamined_boxes: HashSet<Coord> = HashSet::new(); | ||||
| 
 | ||||
|             unexamined_boxes.insert(next); | ||||
| 
 | ||||
|             while !unexamined_boxes.is_empty() { | ||||
|                 let mut candidate_boxes: HashSet<Coord> = HashSet::new(); | ||||
|                 for spot in unexamined_boxes.drain() { | ||||
|                     match map.get(&spot) { | ||||
|                         Some('[') => { | ||||
|                             let other_half = step(&spot, East, 1); | ||||
|                             if !boxes_to_move.contains(&other_half) { | ||||
|                                 candidate_boxes.insert(other_half); | ||||
|                             } | ||||
|                             candidate_boxes.insert(step(&spot, direction, 1)); | ||||
|                             boxes_to_move.insert(spot); | ||||
|                         }, | ||||
|                         Some(']') => { | ||||
|                             let other_half = step(&spot, West, 1); | ||||
|                             if !boxes_to_move.contains(&other_half) { | ||||
|                                 candidate_boxes.insert(other_half); | ||||
|                             } | ||||
|                             candidate_boxes.insert(step(&spot, direction, 1)); | ||||
|                             boxes_to_move.insert(spot); | ||||
|                         }, | ||||
|                         Some('#') => { | ||||
|                             boxes_to_move.drain(); | ||||
|                             candidate_boxes.drain(); | ||||
|                             break; | ||||
|                         }, | ||||
|                         Some('.') => { | ||||
|                             continue; | ||||
|                         }, | ||||
|                         _ => { | ||||
|                             println!("encountered something weird in the map"); | ||||
|                         } | ||||
| 
 | ||||
|                     } | ||||
|                 } | ||||
|                 unexamined_boxes = candidate_boxes; | ||||
|             } | ||||
| 
 | ||||
|             if !boxes_to_move.is_empty() { | ||||
|                 robot = next; | ||||
|                 let mut fulls: HashMap<Coord, char> = HashMap::new(); | ||||
|                 for b in &boxes_to_move { | ||||
|                     fulls.insert(step(&b, direction, 1), *map.get(&b).unwrap()); | ||||
|                 } | ||||
| 
 | ||||
|                 for x in boxes_to_move { | ||||
|                     map.insert(x, '.'); | ||||
|                 } | ||||
|                 for (x, c) in fulls { | ||||
|                     map.insert(x, c); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     print_map(&map); | ||||
|     
 | ||||
|     println!("the gps score after all the instructions in wide mode is {}", sum_of_box_gps(&map)); | ||||
| } | ||||
| 
 | ||||
| fn sum_of_box_gps(grid: &HashMap<Coord, char>) -> i32 { | ||||
|     let mut sum = 0; | ||||
| 
 | ||||
|     for ((x, y), stuff) in grid { | ||||
|         if *stuff == 'O' { sum += x + 100*y; } | ||||
|         if *stuff == '[' { sum += x + 100*y; } | ||||
|     } | ||||
|     
 | ||||
|     return sum; | ||||
| } | ||||
| 
 | ||||
| fn print_map(grid: &HashMap<Coord, char>) { | ||||
|     let (mut x_max, mut y_max): (i32, i32) = (0,0); | ||||
|     for ((x, y), _) in grid { | ||||
|         x_max = x_max.max(*x); | ||||
|         y_max = y_max.max(*y) | ||||
|     } | ||||
| 
 | ||||
|     for y in 0..y_max { | ||||
|         for x in 0..x_max { | ||||
|             print!("{}", grid.get(&(x,y)).unwrap()) | ||||
|         } | ||||
|         println!(); | ||||
|     } | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user