mirror of
https://github.com/Ajetski/advent-of-code.git
synced 2025-09-30 19:23:17 -09:00
119 lines
3.2 KiB
Rust
119 lines
3.2 KiB
Rust
use State::*;
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
enum State {
|
|
Air,
|
|
Rock,
|
|
Sand,
|
|
}
|
|
type Coord = (i32, i32);
|
|
type Data = Vec<Vec<Coord>>;
|
|
type Output = i32;
|
|
fn parse(input: &str) -> Data {
|
|
input
|
|
.lines()
|
|
.map(|line| {
|
|
line.split(" -> ")
|
|
.map(|coord| {
|
|
let (x, y) = coord.split_once(',').unwrap();
|
|
(x.parse().unwrap(), y.parse().unwrap())
|
|
})
|
|
.collect()
|
|
})
|
|
.collect()
|
|
}
|
|
fn part_one(data: Data) -> Output {
|
|
let sim_height = 300;
|
|
let sim_width = 1000;
|
|
let mut sim = vec![vec![Air; sim_height]; sim_width];
|
|
for line in data {
|
|
for w in line.windows(2) {
|
|
let (x1, y1) = w[0];
|
|
let (x2, y2) = w[1];
|
|
if x1 == x2 {
|
|
for y in std::cmp::min(y1, y2)..=std::cmp::max(y1, y2) {
|
|
sim[x1 as usize][y as usize] = Rock;
|
|
}
|
|
} else if y1 == y2 {
|
|
for x in std::cmp::min(x1, x2)..=std::cmp::max(x1, x2) {
|
|
sim[x as usize][y1 as usize] = Rock;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
let spawn = (500, 0);
|
|
for i in 1.. {
|
|
let (mut x, mut y) = spawn;
|
|
loop {
|
|
if y + 1 >= sim_height {
|
|
return i - 1;
|
|
}
|
|
if sim[x][y + 1] == Air {
|
|
y += 1;
|
|
} else if sim[x - 1][y + 1] == Air {
|
|
x -= 1;
|
|
y += 1;
|
|
} else if sim[x + 1][y + 1] == Air {
|
|
x += 1;
|
|
y += 1;
|
|
} else {
|
|
sim[x][y] = Sand;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
unreachable!()
|
|
}
|
|
fn part_two(mut data: Data) -> Output {
|
|
let sim_height = 300;
|
|
let sim_width = 1000;
|
|
let mut sim = vec![vec![Air; sim_height]; sim_width];
|
|
let max_y = data.iter().flatten().map(|c| c.1).max().unwrap();
|
|
data.push(vec![(0, max_y + 2), (sim_width as i32 - 1, max_y + 2)]);
|
|
for line in data {
|
|
for w in line.windows(2) {
|
|
let (x1, y1) = w[0];
|
|
let (x2, y2) = w[1];
|
|
if x1 == x2 {
|
|
for y in std::cmp::min(y1, y2)..=std::cmp::max(y1, y2) {
|
|
sim[x1 as usize][y as usize] = Rock;
|
|
}
|
|
} else if y1 == y2 {
|
|
for x in std::cmp::min(x1, x2)..=std::cmp::max(x1, x2) {
|
|
sim[x as usize][y1 as usize] = Rock;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
let spawn = (500, 0);
|
|
for i in 1.. {
|
|
let (mut x, mut y) = spawn;
|
|
loop {
|
|
if sim[x][y + 1] == Air {
|
|
y += 1;
|
|
} else if sim[x - 1][y + 1] == Air {
|
|
x -= 1;
|
|
y += 1;
|
|
} else if sim[x + 1][y + 1] == Air {
|
|
x += 1;
|
|
y += 1;
|
|
} else {
|
|
if (x, y) == spawn {
|
|
return i;
|
|
}
|
|
sim[x][y] = Sand;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
unreachable!()
|
|
}
|
|
|
|
advent_of_code_macro::generate_tests!(
|
|
day 14,
|
|
parse,
|
|
part_one,
|
|
part_two,
|
|
sample tests [24, 93],
|
|
star tests [674, 24_958]
|
|
);
|