Compare commits
2 commits
7de9bb33b3
...
724572d5be
Author | SHA1 | Date | |
---|---|---|---|
|
724572d5be | ||
|
80e57358e5 |
4 changed files with 192 additions and 3 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -64,6 +64,10 @@ version = "0.1.0"
|
||||||
name = "day11"
|
name = "day11"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day12"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.7.4"
|
version = "2.7.4"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
resolver = "2"
|
resolver = "3"
|
||||||
members = ["day01", "day02", "day03", "day04", "day05", "day06", "day07", "day08", "day09", "day10", "day11"]
|
members = ["day01", "day02", "day03", "day04", "day05", "day06", "day07", "day08", "day09", "day10", "day11", "day12"]
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
winnow = "0.6"
|
winnow = "*"
|
||||||
|
|
6
day12/Cargo.toml
Normal file
6
day12/Cargo.toml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[package]
|
||||||
|
name = "day12"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
179
day12/src/main.rs
Normal file
179
day12/src/main.rs
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
use std::collections::{HashSet, VecDeque};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let input = std::fs::read_to_string("input").unwrap();
|
||||||
|
let grid = Garden::new(&input);
|
||||||
|
println!("{}", pt1(&grid));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pt1(grid: &Garden) -> usize {
|
||||||
|
let mut visited = HashSet::new();
|
||||||
|
let mut cost = 0;
|
||||||
|
for row in grid.rows.iter() {
|
||||||
|
for plot in row.iter() {
|
||||||
|
let root = plot.loc;
|
||||||
|
if visited.contains(&root) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let mut q = VecDeque::new();
|
||||||
|
q.push_back(root);
|
||||||
|
let mut region = HashSet::new();
|
||||||
|
let mut visiting = HashSet::new();
|
||||||
|
while let Some(current) = q.pop_front() {
|
||||||
|
visited.insert(current);
|
||||||
|
visiting.remove(¤t);
|
||||||
|
let nexts = grid.neighbors(¤t);
|
||||||
|
for next in nexts
|
||||||
|
.iter()
|
||||||
|
.map(|n| grid.get(n).unwrap())
|
||||||
|
.filter(|n| !region.contains(n))
|
||||||
|
{
|
||||||
|
if !visiting.contains(&next.loc) {
|
||||||
|
q.push_back(next.loc);
|
||||||
|
visiting.insert(next.loc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
region.insert(grid.get(¤t).unwrap());
|
||||||
|
}
|
||||||
|
let a = region.len();
|
||||||
|
let mut p = 0;
|
||||||
|
for plot in region {
|
||||||
|
p += plot.p_val;
|
||||||
|
}
|
||||||
|
cost += a * p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cost
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct Garden {
|
||||||
|
rows: Vec<Vec<Plot>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Garden {
|
||||||
|
fn new(input: &str) -> Self {
|
||||||
|
let mut rows = Vec::new();
|
||||||
|
for (row, line) in input.lines().enumerate() {
|
||||||
|
let row = line
|
||||||
|
.chars()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(col, c)| Plot {
|
||||||
|
loc: Loc { row, col },
|
||||||
|
p_val: 0,
|
||||||
|
plant: c,
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
rows.push(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut g = Self { rows };
|
||||||
|
let rows = g.rows.len();
|
||||||
|
let cols = g.rows[0].len();
|
||||||
|
for row in 0..rows {
|
||||||
|
for col in 0..cols {
|
||||||
|
let mut p = 4;
|
||||||
|
for _ in g.neighbors(&Loc { row, col }) {
|
||||||
|
p -= 1;
|
||||||
|
}
|
||||||
|
g.rows[row][col].p_val = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get(&self, loc: &Loc) -> Option<&Plot> {
|
||||||
|
self.rows.get(loc.row).and_then(|row| row.get(loc.col))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next(&self, loc: &Loc) -> Vec<&Plot> {
|
||||||
|
let Loc { row, col } = *loc;
|
||||||
|
let mut out = Vec::new();
|
||||||
|
|
||||||
|
// north
|
||||||
|
{
|
||||||
|
let row = row.wrapping_sub(1);
|
||||||
|
if let Some(plot) = self.rows.get(row).and_then(|r| r.get(col)) {
|
||||||
|
out.push(plot)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// south
|
||||||
|
{
|
||||||
|
let row = row + 1;
|
||||||
|
if let Some(plot) = self.rows.get(row).and_then(|r| r.get(col)) {
|
||||||
|
out.push(plot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// east
|
||||||
|
{
|
||||||
|
let col = col + 1;
|
||||||
|
if let Some(plot) = self.rows.get(row).and_then(|r| r.get(col)) {
|
||||||
|
out.push(plot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// west
|
||||||
|
{
|
||||||
|
let col = col.wrapping_sub(1);
|
||||||
|
if let Some(plot) = self.rows.get(row).and_then(|r| r.get(col)) {
|
||||||
|
out.push(plot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns list of neighbor nodes in a dag where the edges are all one step in
|
||||||
|
// distance
|
||||||
|
fn neighbors(&self, loc: &Loc) -> Vec<Loc> {
|
||||||
|
let plot = self.rows[loc.row][loc.col];
|
||||||
|
self.next(loc)
|
||||||
|
.iter()
|
||||||
|
.filter_map(|t| {
|
||||||
|
if t.plant == plot.plant {
|
||||||
|
Some(t.loc)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
struct Loc {
|
||||||
|
row: usize,
|
||||||
|
col: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
struct Plot {
|
||||||
|
loc: Loc,
|
||||||
|
p_val: usize,
|
||||||
|
plant: char,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
static INPUT: &str = "RRRRIICCFF
|
||||||
|
RRRRIICCCF
|
||||||
|
VVRRRCCFFF
|
||||||
|
VVRCCCJFFF
|
||||||
|
VVVVCJJCFE
|
||||||
|
VVIVCCJJEE
|
||||||
|
VVIIICJJEE
|
||||||
|
MIIIIIJJEE
|
||||||
|
MIIISIJEEE
|
||||||
|
MMMISSJEEE";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn p1() {
|
||||||
|
let g = Garden::new(INPUT);
|
||||||
|
assert_eq!(1930, pt1(&g));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue