1
0
Fork 0

Solve 12.1

This commit is contained in:
Lars Martens 2024-12-12 21:30:15 +01:00
parent 700fe510c2
commit 1f49f71068
Signed by: haselkern
GPG key ID: B5CF1F363C179AD4
4 changed files with 118 additions and 22 deletions

View file

@ -56,7 +56,7 @@ fn check_x_mas(start: IVec2, field: &Field) -> usize {
}
fn count_xmas_at(start: IVec2, field: &Field) -> usize {
DIRECTIONS
DIRECTIONS8
.iter()
.filter(|&&dir| check_xmas(start, dir, field))
.count()
@ -69,17 +69,6 @@ fn check_xmas(start: IVec2, direction: IVec2, field: &Field) -> bool {
&& field.get(start + direction * 3) == 'S'
}
const DIRECTIONS: [IVec2; 8] = [
IVec2::new(1, 0),
IVec2::new(1, 1),
IVec2::new(0, 1),
IVec2::new(-1, 1),
IVec2::new(-1, 0),
IVec2::new(-1, -1),
IVec2::new(0, -1),
IVec2::new(1, -1),
];
struct Field {
data: Vec<Vec<char>>,
}

View file

@ -22,15 +22,6 @@ fn part2(input: &str) -> usize {
map.trailheads().map(|t| map.distinct_trails(t)).sum()
}
fn directions() -> [IVec2; 4] {
[
IVec2::new(1, 0),
IVec2::new(-1, 0),
IVec2::new(0, 1),
IVec2::new(0, -1),
]
}
#[derive(Debug)]
struct Map {
height: HashMap<IVec2, i64>,
@ -67,7 +58,7 @@ impl Map {
}
fn climb_up(&self, from: IVec2, from_height: i64) -> Vec<IVec2> {
directions()
DIRECTIONS4
.into_iter()
.filter_map(|dir| {
let pos = from + dir;

95
src/bin/12.rs Normal file
View file

@ -0,0 +1,95 @@
use aoc::*;
use glam::IVec2;
use std::collections::{HashMap, HashSet};
use std::iter;
const INPUT: &str = include_str!("../../input/12");
fn main() {
assert_example!(part1, "12-test", 140);
println!("Part 1: {}", part1(INPUT));
assert_example!(part2, "12-test", 0);
println!("Part 2: {}", part2(INPUT));
}
fn part1(input: &str) -> usize {
parse_regions(input).iter().map(Region::fence_cost).sum()
}
fn part2(_input: &str) -> usize {
0
}
fn parse_regions(input: &str) -> Vec<Region> {
let mut map = parse_map(input);
let mut regions = Vec::new();
loop {
let Some((&start_pos, &plant)) = map.iter().next() else {
break;
};
let mut visited = HashSet::new();
let mut region = Vec::new();
let mut check = vec![start_pos];
let mut perimeter = 0;
while let Some(next) = check.pop() {
if visited.contains(&next) {
continue;
}
visited.insert(next);
let Some(&p) = map.get(&next) else { continue };
if p != plant {
continue;
}
region.push(next);
map.remove(&next);
// Adjust perimeter
let empty_sides = DIRECTIONS4
.into_iter()
.map(|dir| dir + next)
.filter(|pos| !region.contains(pos))
.count();
let taken_sides = 4 - empty_sides;
perimeter = perimeter + empty_sides - taken_sides;
let neighbors = DIRECTIONS4.into_iter().map(|dir| dir + next);
check.extend(neighbors);
}
regions.push(Region {
_plant: plant,
fields: region,
perimeter,
});
}
regions
}
#[derive(Debug)]
struct Region {
_plant: char,
fields: Vec<IVec2>,
perimeter: usize,
}
impl Region {
fn area(&self) -> usize {
self.fields.len()
}
fn fence_cost(&self) -> usize {
self.perimeter * self.area()
}
}
fn parse_map(input: &str) -> HashMap<IVec2, char> {
// TODO Reading a grid with coordinates should be a helper function.
input
.lines()
.enumerate()
.flat_map(|(y, line)| line.chars().enumerate().zip(iter::repeat(y)))
.map(|((x, c), y)| {
let pos = IVec2::new(x as i32, y as i32);
(pos, c)
})
.collect()
}

View file

@ -1,5 +1,6 @@
//! This library contains useful helper functions that may be useful in several problems.
use glam::IVec2;
use std::{
fmt::{Debug, Display},
ops::{Div, Mul, Rem},
@ -106,3 +107,23 @@ macro_rules! assert_example {
)
};
}
/// 4 directions. Start pointing right and go CCW.
pub const DIRECTIONS4: [IVec2; 4] = [
IVec2::new(1, 0),
IVec2::new(0, 1),
IVec2::new(-1, 0),
IVec2::new(0, -1),
];
/// 8 directions. Start pointing right and go CCW.
pub const DIRECTIONS8: [IVec2; 8] = [
IVec2::new(1, 0),
IVec2::new(1, 1),
IVec2::new(0, 1),
IVec2::new(-1, 1),
IVec2::new(-1, 0),
IVec2::new(-1, -1),
IVec2::new(0, -1),
IVec2::new(1, -1),
];