Skip to content
Snippets Groups Projects
Commit e14a0d1d authored by Falk Rehse's avatar Falk Rehse
Browse files

Day 14-2

parent 37810485
No related branches found
No related tags found
No related merge requests found
#[derive(Debug, PartialEq, Copy, Clone)]
enum Tile {
Air,
Rock,
Sand,
}
#[derive(Debug, PartialEq)]
enum SimulationState {
InMotion,
AtRest,
OutOfBounds,
}
const SAND_SPAWN_X: usize = 500;
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| {
let mut data = point.split(',');
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!");
(x, y)
})
.collect()).collect();
solve(&paths)
}
pub fn solve(paths: &Vec<Vec<(usize, usize)>>) -> u32 {
let mut min_x = usize::MAX;
let mut max_x = usize::MIN;
let mut min_y = usize::MAX;
let mut max_y = usize::MIN;
for path in paths {
for point in path {
min_x = usize::min(min_x, point.0);
max_x = usize::max(max_x, point.0);
min_y = usize::min(min_y, point.1);
max_y = usize::max(max_y, point.1);
}
}
min_x = 0;
max_x = 1000;
min_y = 0;
let floor_y = max_y + 2;
max_y += 4;
dbg!(min_x);
dbg!(max_x);
dbg!(min_y);
dbg!(floor_y);
dbg!(max_y);
let mut cave = Vec::with_capacity(max_x);
for _ in 0..max_x {
let mut cave_column = Vec::with_capacity(max_y);
for _ in 0..max_y {
cave_column.push(Tile::Air);
}
cave.push(cave_column);
}
for path in paths {
draw_path(&mut cave, path);
}
draw_line(&mut cave, &(0, floor_y), &(max_x - 1, floor_y));
let mut sum = 0;
while spawn_sand(&mut cave, floor_y + 1) {
sum += 1;
}
sum + 1
}
fn draw_path(cave: &mut Vec<Vec<Tile>>, path: &Vec<(usize, usize)>) {
for point_pair in path.windows(2) {
draw_line(cave, &point_pair[0], &point_pair[1]);
}
}
fn draw_line(cave: &mut Vec<Vec<Tile>>, from: &(usize, usize), to: &(usize, usize)) {
if from.0 == to.0 {
let (from_y, to_y) = if from.1 < to.1 {
(from.1, to.1)
} else {
(to.1, from.1)
};
for y in from_y..=to_y {
cave[from.0][y] = Tile::Rock;
}
} else if from.1 == to.1 {
let (from_x, to_x) = if from.0 < to.0 {
(from.0, to.0)
} else {
(to.0, from.0)
};
for x in from_x..=to_x {
cave[x][from.1] = Tile::Rock;
}
} else {
panic!("Expected a straight line!");
}
}
fn spawn_sand(cave: &mut Vec<Vec<Tile>>, out_of_bounds_y: usize) -> bool {
let mut sand_location = (SAND_SPAWN_X, SAND_SPAWN_Y);
let mut blocked_immidiately = true;
let mut result = simulate_sand(cave, &mut sand_location, out_of_bounds_y);
while result == SimulationState::InMotion {
result = simulate_sand(cave, &mut sand_location, out_of_bounds_y);
blocked_immidiately = false;
}
if result == SimulationState::OutOfBounds {
panic!("Floor should be infinite!");
}
if blocked_immidiately{
false
} else {
cave[sand_location.0][sand_location.1] = Tile::Sand;
true
}
}
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 {
sand_location.0 -= 1;
sand_location.1 += 1;
} else if cave[sand_location.0 + 1][sand_location.1 + 1] == Tile::Air {
sand_location.0 += 1;
sand_location.1 += 1;
} else {
return SimulationState::AtRest;
}
if sand_location.1 >= out_of_bounds_y {
SimulationState::OutOfBounds
} else {
SimulationState::InMotion
}
}
......@@ -25,13 +25,14 @@ mod day_12_2;
mod day_13_1;
mod day_13_2;
mod day_14_1;
mod day_14_2;
use std::fs;
fn main() {
let input = fs::read_to_string("input").expect("Could not read input!");
let solution = day_14_1::solve_from_str(input.as_str());
let solution = day_14_2::solve_from_str(input.as_str());
println!("Solution: {}", solution);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment