This commit is contained in:
Jan-Bulthuis 2024-12-12 06:36:59 +01:00
parent a576f4712f
commit 8cd421a8ef
3 changed files with 176 additions and 4 deletions

View File

@ -1,13 +1,10 @@
use std::collections::VecDeque;
use aoc_runner_derive::{aoc, aoc_generator}; use aoc_runner_derive::{aoc, aoc_generator};
use hashbrown::{hash_map::Entry, HashMap}; use hashbrown::HashMap;
use nom::{ use nom::{
character::complete::{space1, u64 as parse_usize}, character::complete::{space1, u64 as parse_usize},
error::Error, error::Error,
multi::separated_list1, multi::separated_list1,
}; };
use rayon::prelude::*;
type Input = Vec<usize>; type Input = Vec<usize>;

174
aoc_2024/src/day12.rs Normal file
View File

@ -0,0 +1,174 @@
use aoc_runner_derive::{aoc, aoc_generator};
type Input = Vec<Vec<char>>;
#[aoc_generator(day12)]
fn parse(input: &str) -> Input {
input.lines().map(|line| line.chars().collect()).collect()
}
#[aoc(day12, part1)]
fn part1(input: &Input) -> usize {
let w = input[0].len();
let h = input.len();
let mut region_idx = -1;
let mut region_border_size = vec![];
let mut region_size = vec![];
let mut region = vec![vec![-1; w]; h];
for y in 0..h {
for x in 0..w {
let val = input[y][x];
if region[y][x] == -1 {
region_idx += 1;
let mut queue = vec![(x, y)];
let mut size = 0;
let mut border_size = 0;
while let Some((x, y)) = queue.pop() {
if region[y][x] != -1 {
continue;
}
region[y][x] = region_idx;
size += 1;
let mut sides = 4;
if x > 0 && input[y][x - 1] == val {
queue.push((x - 1, y));
sides -= 1;
}
if x < w - 1 && input[y][x + 1] == val {
queue.push((x + 1, y));
sides -= 1;
}
if y > 0 && input[y - 1][x] == val {
queue.push((x, y - 1));
sides -= 1;
}
if y < h - 1 && input[y + 1][x] == val {
queue.push((x, y + 1));
sides -= 1;
}
border_size += sides;
}
region_size.push(size);
region_border_size.push(border_size);
}
}
}
region_size
.iter()
.zip(region_border_size.iter())
.map(|(a, b)| *a * *b)
.sum()
}
#[aoc(day12, part2)]
fn part2(input: &Input) -> usize {
let w = input[0].len();
let h = input.len();
let mut region_idx = -1;
let mut region_border_size = vec![];
let mut region_size = vec![];
let mut region = vec![vec![-1; w]; h];
for y in 0..h {
for x in 0..w {
let val = input[y][x];
if region[y][x] == -1 {
region_idx += 1;
let mut queue = vec![(x, y)];
let mut size = 0;
let mut border_size = 0;
while let Some((x, y)) = queue.pop() {
if region[y][x] != -1 {
continue;
}
region[y][x] = region_idx;
size += 1;
let mut up = false;
let mut down = false;
let mut left = false;
let mut right = false;
let mut up_right = false;
let mut down_left = false;
if x > 0 && input[y][x - 1] == val {
queue.push((x - 1, y));
left = true;
}
if x < w - 1 && input[y][x + 1] == val {
queue.push((x + 1, y));
right = true;
}
if y > 0 && input[y - 1][x] == val {
queue.push((x, y - 1));
up = true;
}
if y < h - 1 && input[y + 1][x] == val {
queue.push((x, y + 1));
down = true;
}
if y > 0 && x < w - 1 && input[y - 1][x + 1] == val {
up_right = true;
}
if y < h - 1 && x > 0 && input[y + 1][x - 1] == val {
down_left = true;
}
if !up && !left {
border_size += 2;
}
if !down && !right {
border_size += 2;
}
if up && right && !up_right {
border_size += 2;
}
if down && left && !down_left {
border_size += 2;
}
}
region_size.push(size);
region_border_size.push(border_size);
}
}
}
region_size
.iter()
.zip(region_border_size.iter())
.map(|(a, b)| *a * *b)
.sum()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn part1_example() {
assert_eq!(part1(&parse("AAAA\nBBCD\nBBCC\nEEEC")), 140);
assert_eq!(part1(&parse("OOOOO\nOXOXO\nOOOOO\nOXOXO\nOOOOO")), 772);
assert_eq!(part1(&parse("RRRRIICCFF\nRRRRIICCCF\nVVRRRCCFFF\nVVRCCCJFFF\nVVVVCJJCFE\nVVIVCCJJEE\nVVIIICJJEE\nMIIIIIJJEE\nMIIISIJEEE\nMMMISSJEEE")), 1930);
}
#[test]
fn part2_example() {
assert_eq!(part2(&parse("AAAA\nBBCD\nBBCC\nEEEC")), 80);
assert_eq!(part2(&parse("OOO\nOXO\nOOO")), 68);
assert_eq!(part2(&parse("OOOOO\nOXXXX\nOOOOO\nOXXXX\nOOOOO")), 236);
assert_eq!(part2(&parse("RRRRIICCFF\nRRRRIICCCF\nVVRRRCCFFF\nVVRCCCJFFF\nVVVVCJJCFE\nVVIVCCJJEE\nVVIIICJJEE\nMIIIIIJJEE\nMIIISIJEEE\nMMMISSJEEE")), 1206);
}
}

View File

@ -1,6 +1,7 @@
mod day1; mod day1;
mod day10; mod day10;
mod day11; mod day11;
mod day12;
mod day2; mod day2;
mod day3; mod day3;
mod day4; mod day4;