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