Skip to content

Commit

Permalink
add day12
Browse files Browse the repository at this point in the history
  • Loading branch information
mirsella committed Dec 12, 2024
1 parent a8766d2 commit c27d5a5
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 0 deletions.
19 changes: 19 additions & 0 deletions 2024/day12/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
input.txt
flamegraph.svg
perf.data*
### Rust
# Generated by Cargo
# will have compiled files and executables
debug/
target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb

16 changes: 16 additions & 0 deletions 2024/day12/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "day12"
authors = ["mirsella <[email protected]>"]
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
regex = { workspace = true }
itertools = { workspace = true }
pathfinding = { workspace = true }
rayon = { workspace = true }
indexmap = { workspace = true }
hashbrown = { workspace = true }
fix_fn = { workspace = true }
138 changes: 138 additions & 0 deletions 2024/day12/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
use hashbrown::HashSet;
use itertools::Itertools;
use std::collections::BTreeSet;
// use std::collections::HashSet;
use pathfinding::{
matrix::{directions::DIRECTIONS_4, Matrix},
prelude::bfs_reach,
};

type Regions = HashSet<BTreeSet<(usize, usize)>>;
fn part1(input: &str) -> usize {
let m = Matrix::from_rows(input.lines().map(str::chars)).unwrap();
let mut regions: Regions = Default::default();
for pos in m.keys() {
if regions.iter().any(|r| r.contains(&pos)) {
continue;
}
let region = bfs_reach(pos, |&p| m.neighbours(p, false).filter(|&n| m[n] == m[pos]))
.collect::<BTreeSet<_>>();
regions.insert(region);
}
let mut price = 0;
for region in regions.iter() {
let mut fences = 0;
for &pos in region {
let neighbours = m.neighbours(pos, false).collect_vec();
fences += neighbours.iter().filter(|n| !region.contains(n)).count();
fences += 4 - neighbours.len();
}
price += fences * region.len();
}
price
}

fn part2(input: &str) -> usize {
let m = Matrix::from_rows(input.lines().map(str::chars)).unwrap();
let mut regions: Regions = Default::default();
for pos in m.keys() {
if regions.iter().any(|r| r.contains(&pos)) {
continue;
}
let region = bfs_reach(pos, |&p| m.neighbours(p, false).filter(|&n| m[n] == m[pos]))
.collect::<BTreeSet<_>>();
regions.insert(region);
}
let mut price = 0;
for region in regions.iter() {
let mut corners = 0;
for dir in DIRECTIONS_4 {
let mut sides = HashSet::new();
for pos in region {
let tmp = (pos.0 as isize + dir.0, pos.1 as isize + dir.1);
if !region.contains(&(tmp.0 as usize, tmp.1 as usize)) {
sides.insert(tmp);
}
}
let mut extra_sides = HashSet::new();
for side in &sides {
let mut tmp = (side.0 + dir.1, side.1 + dir.0);
while sides.contains(&tmp) {
extra_sides.insert(tmp);
tmp = (tmp.0 + dir.1, tmp.1 + dir.0);
}
}
corners += sides.len() - extra_sides.len();
}
price += corners * region.len();
}
price
}

fn main() {
let input = include_str!("../input.txt");
println!("Part 1: {}", part1(input));
println!("Part 2: {}", part2(input));
}

#[cfg(test)]
mod tests {
const INPUT: &str = "RRRRIICCFF
RRRRIICCCF
VVRRRCCFFF
VVRCCCJFFF
VVVVCJJCFE
VVIVCCJJEE
VVIIICJJEE
MIIIIIJJEE
MIIISIJEEE
MMMISSJEEE";
#[test]
fn part1() {
assert_eq!(super::part1(INPUT), 1930);
}
#[test]
fn part2() {
assert_eq!(super::part2(INPUT), 1206);
}
#[test]
fn part2_2() {
assert_eq!(
super::part2(
"AAAA
BBCD
BBCC
EEEC"
),
80
);
}
#[test]
fn part2_3() {
assert_eq!(
super::part2(
"EEEEE
EXXXX
EEEEE
EXXXX
EEEEE"
),
236
);
}

#[test]
fn part2_4() {
assert_eq!(
super::part2(
"AAAAAA
AAABBA
AAABBA
ABBAAA
ABBAAA
AAAAAA"
),
368
);
}
}

0 comments on commit c27d5a5

Please sign in to comment.