Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • main
1 result

Target

Select target project
  • falk.rehse/advent-of-code-2022
1 result
Select Git revision
  • main
1 result
Show changes

Commits on Source 2

#[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 -= 1;
max_x += 2;
min_y = 0;
max_y += 2;
dbg!(min_x);
dbg!(max_x);
dbg!(min_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);
}
let mut sum = 0;
while spawn_sand(&mut cave, max_y - 1) {
sum += 1;
}
sum
}
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 result = SimulationState::InMotion;
while result == SimulationState::InMotion {
result = simulate_sand(cave, &mut sand_location, out_of_bounds_y);
}
if result == SimulationState::OutOfBounds {
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
}
}
#[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
}
}
......@@ -24,13 +24,15 @@ mod day_12_1;
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_13_2::solve_from_str(input.as_str());
let solution = day_14_2::solve_from_str(input.as_str());
println!("Solution: {}", solution);
}