Solve 12.1
This commit is contained in:
parent
700fe510c2
commit
1f49f71068
4 changed files with 118 additions and 22 deletions
|
@ -56,7 +56,7 @@ fn check_x_mas(start: IVec2, field: &Field) -> usize {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn count_xmas_at(start: IVec2, field: &Field) -> usize {
|
fn count_xmas_at(start: IVec2, field: &Field) -> usize {
|
||||||
DIRECTIONS
|
DIRECTIONS8
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|&&dir| check_xmas(start, dir, field))
|
.filter(|&&dir| check_xmas(start, dir, field))
|
||||||
.count()
|
.count()
|
||||||
|
@ -69,17 +69,6 @@ fn check_xmas(start: IVec2, direction: IVec2, field: &Field) -> bool {
|
||||||
&& field.get(start + direction * 3) == 'S'
|
&& 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 {
|
struct Field {
|
||||||
data: Vec<Vec<char>>,
|
data: Vec<Vec<char>>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,15 +22,6 @@ fn part2(input: &str) -> usize {
|
||||||
map.trailheads().map(|t| map.distinct_trails(t)).sum()
|
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)]
|
#[derive(Debug)]
|
||||||
struct Map {
|
struct Map {
|
||||||
height: HashMap<IVec2, i64>,
|
height: HashMap<IVec2, i64>,
|
||||||
|
@ -67,7 +58,7 @@ impl Map {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn climb_up(&self, from: IVec2, from_height: i64) -> Vec<IVec2> {
|
fn climb_up(&self, from: IVec2, from_height: i64) -> Vec<IVec2> {
|
||||||
directions()
|
DIRECTIONS4
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|dir| {
|
.filter_map(|dir| {
|
||||||
let pos = from + dir;
|
let pos = from + dir;
|
||||||
|
|
95
src/bin/12.rs
Normal file
95
src/bin/12.rs
Normal 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()
|
||||||
|
}
|
21
src/lib.rs
21
src/lib.rs
|
@ -1,5 +1,6 @@
|
||||||
//! This library contains useful helper functions that may be useful in several problems.
|
//! This library contains useful helper functions that may be useful in several problems.
|
||||||
|
|
||||||
|
use glam::IVec2;
|
||||||
use std::{
|
use std::{
|
||||||
fmt::{Debug, Display},
|
fmt::{Debug, Display},
|
||||||
ops::{Div, Mul, Rem},
|
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),
|
||||||
|
];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue