Day 12 part 1 with a little work on part 2
This commit is contained in:
parent
e76498d60c
commit
61a5cd899e
2 changed files with 127 additions and 2 deletions
125
2024/rust/src/day12.rs
Normal file
125
2024/rust/src/day12.rs
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
mod prelude;
|
||||||
|
pub use crate::prelude::*;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let input = day_input(12);
|
||||||
|
show_answers(part1(&input), part2(&input));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
||||||
|
enum Dir {
|
||||||
|
N,
|
||||||
|
S,
|
||||||
|
E,
|
||||||
|
W,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Region {
|
||||||
|
locations: HashSet<(usize, usize)>,
|
||||||
|
perimeters: HashSet<(usize, usize, Dir)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Region {
|
||||||
|
fn measure_at(bytes: &Vec<Vec<u8>>, sx: usize, sy: usize) -> Self {
|
||||||
|
let target = bytes[sy][sx];
|
||||||
|
let (height, width) = (bytes.len(), bytes[0].len());
|
||||||
|
let mut candidates = vec![(sx, sy)];
|
||||||
|
let mut locations = HashSet::from_iter(candidates.clone());
|
||||||
|
let mut perimeters = HashSet::new();
|
||||||
|
|
||||||
|
while let Some((x, y)) = candidates.pop() {
|
||||||
|
print!("AT {x},{y}: ");
|
||||||
|
for (nx, ny, d) in [
|
||||||
|
(x, y.saturating_sub(1), Dir::N),
|
||||||
|
(x, y + 1, Dir::S),
|
||||||
|
(x + 1, y, Dir::E),
|
||||||
|
(x.saturating_sub(1), y, Dir::W),
|
||||||
|
] {
|
||||||
|
if (nx, ny) == (x, y) || nx >= width || ny >= height {
|
||||||
|
print!("EDGE@{nx},{ny}; ");
|
||||||
|
perimeters.insert((nx, ny, d));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if bytes[ny][nx] != target {
|
||||||
|
print!("EDGE@{nx},{ny}; ");
|
||||||
|
perimeters.insert((nx, ny, d));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if !locations.contains(&(nx, ny)) {
|
||||||
|
candidates.push((nx, ny));
|
||||||
|
locations.insert((nx, ny));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print!("\n");
|
||||||
|
}
|
||||||
|
Self {
|
||||||
|
locations,
|
||||||
|
perimeters,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1(input: &str) -> usize {
|
||||||
|
let mut regions = vec![];
|
||||||
|
let bytes: Vec<Vec<u8>> = input
|
||||||
|
.trim()
|
||||||
|
.lines()
|
||||||
|
.map(|l| l.trim().bytes().collect())
|
||||||
|
.collect();
|
||||||
|
let mut regionated: HashSet<(usize, usize)> = HashSet::new();
|
||||||
|
for y in 0..bytes.len() {
|
||||||
|
for x in 0..bytes[y].len() {
|
||||||
|
if regionated.contains(&(x, y)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let region = Region::measure_at(&bytes, x, y);
|
||||||
|
println!(
|
||||||
|
"New Region: (Byte: {}, Area: {}, Perimeter: {})",
|
||||||
|
bytes[y][x],
|
||||||
|
®ion.locations.len(),
|
||||||
|
®ion.perimeters.len(),
|
||||||
|
);
|
||||||
|
regionated.extend(®ion.locations);
|
||||||
|
regions.push(region);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!("{regions:?}");
|
||||||
|
regions
|
||||||
|
.iter()
|
||||||
|
.map(|r| r.locations.len() * r.perimeters.len())
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2(input: &str) -> usize {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test() {
|
||||||
|
let input = r#"RRRRIICCFF
|
||||||
|
RRRRIICCCF
|
||||||
|
VVRRRCCFFF
|
||||||
|
VVRCCCJFFF
|
||||||
|
VVVVCJJCFE
|
||||||
|
VVIVCCJJEE
|
||||||
|
VVIIICJJEE
|
||||||
|
MIIIIIJJEE
|
||||||
|
MIIISIJEEE
|
||||||
|
MMMISSJEEE"#;
|
||||||
|
let bytes: Vec<Vec<u8>> = input
|
||||||
|
.trim()
|
||||||
|
.lines()
|
||||||
|
.map(|l| l.trim().bytes().collect())
|
||||||
|
.collect();
|
||||||
|
let region = Region::measure_at(&bytes, 0, 0);
|
||||||
|
assert_eq!(region.locations.len(), 12);
|
||||||
|
assert_eq!(region.perimeters.len(), 18);
|
||||||
|
assert_eq!(part1(input), 1930);
|
||||||
|
assert_eq!(part2(input), 1206);
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,11 +6,11 @@ fn main() {
|
||||||
show_answers(part1(&input), part2(&input));
|
show_answers(part1(&input), part2(&input));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part1(input: &str) -> i64 {
|
fn part1(input: &str) -> usize {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part2(input: &str) -> i64 {
|
fn part2(input: &str) -> usize {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue