Compare commits
No commits in common. "724572d5be69d360499bed560aeef0aff7ac2b69" and "7de9bb33b3f5208b73f2ccbf5e27661e1dc7f000" have entirely different histories.
724572d5be
...
7de9bb33b3
4 changed files with 3 additions and 192 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -64,10 +64,6 @@ version = "0.1.0"
|
|||
name = "day11"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "day12"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[workspace]
|
||||
resolver = "3"
|
||||
members = ["day01", "day02", "day03", "day04", "day05", "day06", "day07", "day08", "day09", "day10", "day11", "day12"]
|
||||
resolver = "2"
|
||||
members = ["day01", "day02", "day03", "day04", "day05", "day06", "day07", "day08", "day09", "day10", "day11"]
|
||||
|
||||
[workspace.dependencies]
|
||||
winnow = "*"
|
||||
winnow = "0.6"
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
[package]
|
||||
name = "day12"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
|
@ -1,179 +0,0 @@
|
|||
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