5 files + 265 − 26 Inline Compare changes Side-by-side Inline Show whitespace changes Files 5 src/day_14_1/mod.rs +27 −11 Original line number Diff line number Diff line Loading @@ -18,16 +18,28 @@ const SAND_SPAWN_Y: usize = 0; pub fn solve_from_str(input: &str) -> u32 { let paths = input .split("\n") .map(|path| path.split(" -> ").map(|point| { .map(|path| { path.split(" -> ") .map(|point| { let mut data = point.split(','); let x = data.next().unwrap().parse().expect("Expected x-coordinate to be a number!"); let x = data .next() .unwrap() .parse() .expect("Expected x-coordinate to be a number!"); let y = data.next().unwrap().parse().expect("Expected x-coordinate to be a number!"); let y = data .next() .unwrap() .parse() .expect("Expected x-coordinate to be a number!"); (x, y) }) .collect()).collect(); .collect() }) .collect(); solve(&paths) } Loading Loading @@ -134,7 +146,11 @@ fn spawn_sand(cave: &mut Vec<Vec<Tile>>, out_of_bounds_y: usize) -> bool { } } fn simulate_sand(cave: &Vec<Vec<Tile>>, sand_location: &mut (usize, usize), out_of_bounds_y: usize) -> SimulationState { fn simulate_sand( cave: &Vec<Vec<Tile>>, sand_location: &mut (usize, usize), out_of_bounds_y: usize, ) -> SimulationState { if cave[sand_location.0][sand_location.1 + 1] == Tile::Air { sand_location.1 += 1; } else if cave[sand_location.0 - 1][sand_location.1 + 1] == Tile::Air { Loading src/day_14_2/mod.rs +30 −14 Original line number Diff line number Diff line Loading @@ -18,16 +18,28 @@ const SAND_SPAWN_Y: usize = 0; pub fn solve_from_str(input: &str) -> u32 { let paths = input .split("\n") .map(|path| path.split(" -> ").map(|point| { .map(|path| { path.split(" -> ") .map(|point| { let mut data = point.split(','); let x = data.next().unwrap().parse().expect("Expected x-coordinate to be a number!"); let x = data .next() .unwrap() .parse() .expect("Expected x-coordinate to be a number!"); let y = data.next().unwrap().parse().expect("Expected x-coordinate to be a number!"); let y = data .next() .unwrap() .parse() .expect("Expected x-coordinate to be a number!"); (x, y) }) .collect()).collect(); .collect() }) .collect(); solve(&paths) } Loading Loading @@ -144,7 +156,11 @@ fn spawn_sand(cave: &mut Vec<Vec<Tile>>, out_of_bounds_y: usize) -> bool { } } fn simulate_sand(cave: &Vec<Vec<Tile>>, sand_location: &mut (usize, usize), out_of_bounds_y: usize) -> SimulationState { fn simulate_sand( cave: &Vec<Vec<Tile>>, sand_location: &mut (usize, usize), out_of_bounds_y: usize, ) -> SimulationState { if cave[sand_location.0][sand_location.1 + 1] == Tile::Air { sand_location.1 += 1; } else if cave[sand_location.0 - 1][sand_location.1 + 1] == Tile::Air { Loading src/day_15_1/mod.rs 0 → 100644 +121 −0 Original line number Diff line number Diff line use std::collections::HashMap; const ROW: i32 = 2_000_000; pub fn solve_from_str(input: &str) -> u32 { let pairs = input .split("\n") .map(|pair| { let mut data = pair.split(' '); let sensor_x = data .nth(2) .unwrap() .strip_prefix("x=") .unwrap() .strip_suffix(",") .unwrap() .parse() .expect("Expected sensor x-coordinate to be a number!"); let sensor_y = data .nth(0) .unwrap() .strip_prefix("y=") .unwrap() .strip_suffix(":") .unwrap() .parse() .expect("Expected sensor y-coordinate to be a number!"); let beacon_x = data .nth(4) .unwrap() .strip_prefix("x=") .unwrap() .strip_suffix(",") .unwrap() .parse() .expect("Expected beacon x-coordinate to be a number!"); let beacon_y = data .nth(0) .unwrap() .strip_prefix("y=") .unwrap() .parse() .expect("Expected beacon y-coordinate to be a number!"); ((sensor_x, sensor_y), (beacon_x, beacon_y)) }) .collect(); solve(&pairs) } pub fn solve(pairs: &Vec<((i32, i32), (i32, i32))>) -> u32 { let mut cave = HashMap::new(); println!("Marking sensor area!"); for (i, pair) in pairs.iter().enumerate() { println!("Marking sensor area for sensor {i}!"); mark_sensor_area(&mut cave, &pair.0, &pair.1); println!("Marked sensor area for sensor {i}!"); } println!("Marked sensor area!"); let min_x = cave.keys().min_by_key(|position| position.0).unwrap().0; let max_x = cave.keys().max_by_key(|position| position.0).unwrap().0; let min_y = cave.keys().min_by_key(|position| position.1).unwrap().1; let max_y = cave.keys().max_by_key(|position| position.1).unwrap().1; dbg!(min_x); dbg!(max_x); dbg!(min_y); dbg!(max_y); let mut sum = 0; println!("Searching row!"); for x in min_x - 1..max_x + 1 { if cave.contains_key(&(x, ROW)) && !cave[&(x, ROW)] { sum += 1; } } println!("Done!"); sum } fn mark_sensor_area( cave: &mut HashMap<(i32, i32), bool>, sensor: &(i32, i32), beacon: &(i32, i32), ) { let manhatten_distance = get_manhatten_distance(sensor, beacon); let start_x = sensor.0 - manhatten_distance; let end_x = sensor.0 + manhatten_distance; for x in start_x..end_x { let y = ROW; if (sensor.1 - manhatten_distance..sensor.1 + manhatten_distance).contains(&y) { if get_manhatten_distance(sensor, &(x, y)) <= manhatten_distance { if &(x, y) == beacon { cave.insert((x, y), true); } cave.entry((x, y)).or_insert(false); } } } } fn get_manhatten_distance(from: &(i32, i32), to: &(i32, i32)) -> i32 { i32::abs(from.0 - to.0) + i32::abs(from.1 - to.1) } src/day_15_2/mod.rs 0 → 100644 +84 −0 Original line number Diff line number Diff line const MIN_X: usize = 0; const MAX_X: usize = 4_000_000; const MIN_Y: usize = 0; const MAX_Y: usize = 4_000_000; pub fn solve_from_str(input: &str) -> usize { let pairs = input .split("\n") .map(|pair| { let mut data = pair.split(' '); let sensor_x = data .nth(2) .unwrap() .strip_prefix("x=") .unwrap() .strip_suffix(",") .unwrap() .parse() .expect("Expected sensor x-coordinate to be a number!"); let sensor_y = data .nth(0) .unwrap() .strip_prefix("y=") .unwrap() .strip_suffix(":") .unwrap() .parse() .expect("Expected sensor y-coordinate to be a number!"); let beacon_x = data .nth(4) .unwrap() .strip_prefix("x=") .unwrap() .strip_suffix(",") .unwrap() .parse() .expect("Expected beacon x-coordinate to be a number!"); let beacon_y = data .nth(0) .unwrap() .strip_prefix("y=") .unwrap() .parse() .expect("Expected beacon y-coordinate to be a number!"); ((sensor_x, sensor_y), (beacon_x, beacon_y)) }) .collect(); solve(&pairs) } pub fn solve(pairs: &Vec<((i32, i32), (i32, i32))>) -> usize { let areas: Vec<((i32, i32), i32)> = pairs.iter().map(|pair| (pair.0, get_manhatten_distance(&pair.0, &pair.1))).collect(); let mut beacon = None; for x in MIN_X..=MAX_X { dbg!(x); for y in MIN_Y..=MAX_Y { for area in &areas { if get_manhatten_distance(&(x as i32, y as i32), &area.0) <= area.1 { continue; } } beacon = Some((x, y)); } } let beacon = beacon.unwrap(); dbg!(&beacon); beacon.0 * 4_000_000 + beacon.1 } fn get_manhatten_distance(from: &(i32, i32), to: &(i32, i32)) -> i32 { i32::abs(from.0 - to.0) + i32::abs(from.1 - to.1) } src/main.rs +3 −1 Original line number Diff line number Diff line Loading @@ -26,13 +26,15 @@ mod day_13_1; mod day_13_2; mod day_14_1; mod day_14_2; mod day_15_1; mod day_15_2; use std::fs; fn main() { let input = fs::read_to_string("input").expect("Could not read input!"); let solution = day_14_2::solve_from_str(input.as_str()); let solution = day_15_2::solve_from_str(input.as_str()); println!("Solution: {}", solution); }
src/day_14_1/mod.rs +27 −11 Original line number Diff line number Diff line Loading @@ -18,16 +18,28 @@ const SAND_SPAWN_Y: usize = 0; pub fn solve_from_str(input: &str) -> u32 { let paths = input .split("\n") .map(|path| path.split(" -> ").map(|point| { .map(|path| { path.split(" -> ") .map(|point| { let mut data = point.split(','); let x = data.next().unwrap().parse().expect("Expected x-coordinate to be a number!"); let x = data .next() .unwrap() .parse() .expect("Expected x-coordinate to be a number!"); let y = data.next().unwrap().parse().expect("Expected x-coordinate to be a number!"); let y = data .next() .unwrap() .parse() .expect("Expected x-coordinate to be a number!"); (x, y) }) .collect()).collect(); .collect() }) .collect(); solve(&paths) } Loading Loading @@ -134,7 +146,11 @@ fn spawn_sand(cave: &mut Vec<Vec<Tile>>, out_of_bounds_y: usize) -> bool { } } fn simulate_sand(cave: &Vec<Vec<Tile>>, sand_location: &mut (usize, usize), out_of_bounds_y: usize) -> SimulationState { fn simulate_sand( cave: &Vec<Vec<Tile>>, sand_location: &mut (usize, usize), out_of_bounds_y: usize, ) -> SimulationState { if cave[sand_location.0][sand_location.1 + 1] == Tile::Air { sand_location.1 += 1; } else if cave[sand_location.0 - 1][sand_location.1 + 1] == Tile::Air { Loading
src/day_14_2/mod.rs +30 −14 Original line number Diff line number Diff line Loading @@ -18,16 +18,28 @@ const SAND_SPAWN_Y: usize = 0; pub fn solve_from_str(input: &str) -> u32 { let paths = input .split("\n") .map(|path| path.split(" -> ").map(|point| { .map(|path| { path.split(" -> ") .map(|point| { let mut data = point.split(','); let x = data.next().unwrap().parse().expect("Expected x-coordinate to be a number!"); let x = data .next() .unwrap() .parse() .expect("Expected x-coordinate to be a number!"); let y = data.next().unwrap().parse().expect("Expected x-coordinate to be a number!"); let y = data .next() .unwrap() .parse() .expect("Expected x-coordinate to be a number!"); (x, y) }) .collect()).collect(); .collect() }) .collect(); solve(&paths) } Loading Loading @@ -144,7 +156,11 @@ fn spawn_sand(cave: &mut Vec<Vec<Tile>>, out_of_bounds_y: usize) -> bool { } } fn simulate_sand(cave: &Vec<Vec<Tile>>, sand_location: &mut (usize, usize), out_of_bounds_y: usize) -> SimulationState { fn simulate_sand( cave: &Vec<Vec<Tile>>, sand_location: &mut (usize, usize), out_of_bounds_y: usize, ) -> SimulationState { if cave[sand_location.0][sand_location.1 + 1] == Tile::Air { sand_location.1 += 1; } else if cave[sand_location.0 - 1][sand_location.1 + 1] == Tile::Air { Loading
src/day_15_1/mod.rs 0 → 100644 +121 −0 Original line number Diff line number Diff line use std::collections::HashMap; const ROW: i32 = 2_000_000; pub fn solve_from_str(input: &str) -> u32 { let pairs = input .split("\n") .map(|pair| { let mut data = pair.split(' '); let sensor_x = data .nth(2) .unwrap() .strip_prefix("x=") .unwrap() .strip_suffix(",") .unwrap() .parse() .expect("Expected sensor x-coordinate to be a number!"); let sensor_y = data .nth(0) .unwrap() .strip_prefix("y=") .unwrap() .strip_suffix(":") .unwrap() .parse() .expect("Expected sensor y-coordinate to be a number!"); let beacon_x = data .nth(4) .unwrap() .strip_prefix("x=") .unwrap() .strip_suffix(",") .unwrap() .parse() .expect("Expected beacon x-coordinate to be a number!"); let beacon_y = data .nth(0) .unwrap() .strip_prefix("y=") .unwrap() .parse() .expect("Expected beacon y-coordinate to be a number!"); ((sensor_x, sensor_y), (beacon_x, beacon_y)) }) .collect(); solve(&pairs) } pub fn solve(pairs: &Vec<((i32, i32), (i32, i32))>) -> u32 { let mut cave = HashMap::new(); println!("Marking sensor area!"); for (i, pair) in pairs.iter().enumerate() { println!("Marking sensor area for sensor {i}!"); mark_sensor_area(&mut cave, &pair.0, &pair.1); println!("Marked sensor area for sensor {i}!"); } println!("Marked sensor area!"); let min_x = cave.keys().min_by_key(|position| position.0).unwrap().0; let max_x = cave.keys().max_by_key(|position| position.0).unwrap().0; let min_y = cave.keys().min_by_key(|position| position.1).unwrap().1; let max_y = cave.keys().max_by_key(|position| position.1).unwrap().1; dbg!(min_x); dbg!(max_x); dbg!(min_y); dbg!(max_y); let mut sum = 0; println!("Searching row!"); for x in min_x - 1..max_x + 1 { if cave.contains_key(&(x, ROW)) && !cave[&(x, ROW)] { sum += 1; } } println!("Done!"); sum } fn mark_sensor_area( cave: &mut HashMap<(i32, i32), bool>, sensor: &(i32, i32), beacon: &(i32, i32), ) { let manhatten_distance = get_manhatten_distance(sensor, beacon); let start_x = sensor.0 - manhatten_distance; let end_x = sensor.0 + manhatten_distance; for x in start_x..end_x { let y = ROW; if (sensor.1 - manhatten_distance..sensor.1 + manhatten_distance).contains(&y) { if get_manhatten_distance(sensor, &(x, y)) <= manhatten_distance { if &(x, y) == beacon { cave.insert((x, y), true); } cave.entry((x, y)).or_insert(false); } } } } fn get_manhatten_distance(from: &(i32, i32), to: &(i32, i32)) -> i32 { i32::abs(from.0 - to.0) + i32::abs(from.1 - to.1) }
src/day_15_2/mod.rs 0 → 100644 +84 −0 Original line number Diff line number Diff line const MIN_X: usize = 0; const MAX_X: usize = 4_000_000; const MIN_Y: usize = 0; const MAX_Y: usize = 4_000_000; pub fn solve_from_str(input: &str) -> usize { let pairs = input .split("\n") .map(|pair| { let mut data = pair.split(' '); let sensor_x = data .nth(2) .unwrap() .strip_prefix("x=") .unwrap() .strip_suffix(",") .unwrap() .parse() .expect("Expected sensor x-coordinate to be a number!"); let sensor_y = data .nth(0) .unwrap() .strip_prefix("y=") .unwrap() .strip_suffix(":") .unwrap() .parse() .expect("Expected sensor y-coordinate to be a number!"); let beacon_x = data .nth(4) .unwrap() .strip_prefix("x=") .unwrap() .strip_suffix(",") .unwrap() .parse() .expect("Expected beacon x-coordinate to be a number!"); let beacon_y = data .nth(0) .unwrap() .strip_prefix("y=") .unwrap() .parse() .expect("Expected beacon y-coordinate to be a number!"); ((sensor_x, sensor_y), (beacon_x, beacon_y)) }) .collect(); solve(&pairs) } pub fn solve(pairs: &Vec<((i32, i32), (i32, i32))>) -> usize { let areas: Vec<((i32, i32), i32)> = pairs.iter().map(|pair| (pair.0, get_manhatten_distance(&pair.0, &pair.1))).collect(); let mut beacon = None; for x in MIN_X..=MAX_X { dbg!(x); for y in MIN_Y..=MAX_Y { for area in &areas { if get_manhatten_distance(&(x as i32, y as i32), &area.0) <= area.1 { continue; } } beacon = Some((x, y)); } } let beacon = beacon.unwrap(); dbg!(&beacon); beacon.0 * 4_000_000 + beacon.1 } fn get_manhatten_distance(from: &(i32, i32), to: &(i32, i32)) -> i32 { i32::abs(from.0 - to.0) + i32::abs(from.1 - to.1) }
src/main.rs +3 −1 Original line number Diff line number Diff line Loading @@ -26,13 +26,15 @@ mod day_13_1; mod day_13_2; mod day_14_1; mod day_14_2; mod day_15_1; mod day_15_2; use std::fs; fn main() { let input = fs::read_to_string("input").expect("Could not read input!"); let solution = day_14_2::solve_from_str(input.as_str()); let solution = day_15_2::solve_from_str(input.as_str()); println!("Solution: {}", solution); }