completely rework day 9, still broken though

This commit is contained in:
Joseph Montanaro 2021-12-14 21:08:49 -08:00
parent 6cc7cb8752
commit 8991100b59
2 changed files with 70 additions and 79 deletions

View File

@ -1,23 +1,24 @@
use color_eyre::eyre; use color_eyre::eyre;
use eyre::eyre; use eyre::eyre;
use crate::lib::Vec2;
// #[derive(Eq, PartialEq)]
enum Elevation { #[derive(Debug)]
High, struct Cell {
Mid, height: u32,
Low, min: bool,
} }
use Elevation::*;
fn load(data: &str) -> eyre::Result<Vec<Vec<u32>>> { fn load(data: &str) -> eyre::Result<Vec2<Cell>> {
let mut heights = Vec::new(); let num_columns = data.lines().next().unwrap().len();
let mut heights = Vec2::new(num_columns);
for line in data.lines() { for line in data.lines() {
let mut row = Vec::new(); let mut row = Vec::new();
for c in line.chars() { for c in line.chars() {
match c.to_digit(10) { match c.to_digit(10) {
Some(d) => row.push(d), Some(d) => row.push(Cell {height: d, min: true}),
None => return Err(eyre!("Invalid character (not a digit): {}", c)), None => return Err(eyre!("Invalid character (not a digit): {}", c)),
} }
} }
@ -27,79 +28,63 @@ fn load(data: &str) -> eyre::Result<Vec<Vec<u32>>> {
} }
fn cmp_horizontal(row: &[u32], pos: usize) -> Elevation { fn scan(map: &mut Vec2<Cell>) {
let prev = if pos == 0 {None} else {Some(row[pos - 1])}; for r in 0..map.row_count() {
let next = if pos == row.len() - 1 {None} else {Some(row[pos + 1])}; for col in 0..map.col_count() {
let current = row[pos]; if col > 0 {
if map[r][col].height <= map[r][col - 1].height {
if current > prev.unwrap_or(0) && current > next.unwrap_or(0) { map[r][col - 1].min = false;
High if map[r][col].height == map[r][col - 1].height {
map[r][col].min = false;
} }
else if current < prev.unwrap_or(9) && current < next.unwrap_or(9) {
Low
} }
else {
Mid
} }
}
fn scan(map: &[Vec<u32>]) -> Vec<Vec<Elevation>> {
let mut result: Vec<Vec<Elevation>> = Vec::new();
for (r, row) in map.iter().enumerate() {
let mut scanned_row = Vec::new();
for (col, height) in row.iter().enumerate() {
let elev = match cmp_horizontal(row, col) {
High => {
if r == 0 || height > &map[r - 1][col] {
High
}
else {
Mid
}
},
Low => {
if r == 0 || height < &map[r - 1][col] {
Low
}
else {
Mid
}
},
Mid => Mid,
};
if r > 0 { if r > 0 {
let above = &result[r - 1][col]; if map[r][col].height <= map[r - 1][col].height {
if let (&High, &High) | (&Low, &Low) = (&elev, above) { map[r - 1][col].min = false;
result[r - 1][col] = Mid; if map[r][col].height == map[r - 1][col].height {
map[r][col].min = false;
} }
} }
scanned_row.push(elev);
} }
result.push(scanned_row);
} }
result }
// for (r, row) in map.rows().enumerate() {
// for (col, cell) in row.iter().enumerate() {
// if col > 0 && cell.height < row[col - 1].height {
// map[r][col - 1].min = false;
// }
// if r > 0 && cell.height < map[r - 1][col].height {
// map[r - 1][col].min = false;
// }
// }
// }
} }
fn part1(map: &[Vec<u32>], compares: &[Vec<Elevation>]) -> u32 { fn part1(map: &Vec2<Cell>) -> u32 {
let mut result = 0; map.values()
for (r, row) in compares.iter().enumerate() { .filter(|c| c.min)
for (col, elev) in row.iter().enumerate() { .fold(0, |acc, c| acc + c.height + 1)
if let Low = elev {
result += map[r][col] + 1
}
}
}
result
} }
pub fn run(data: &str) -> eyre::Result<(u32, u32)> { pub fn run(data: &str) -> eyre::Result<(u32, u32)> {
let map = load(data)?; let sample = "2199943210\n3987894921\n9856789892\n8767896789\n9899965678";
let compares = scan(&map); let mut map = load(sample)?;
scan(&mut map);
let one = part1(&map, &compares); dbg!(&map[1], &map[2]);
for (i, cell) in map.values().enumerate() {
if cell.min {
println!("{}, {} ({})", i / map.row_count(), i % map.row_count(), cell.height)
}
}
let one = part1(&map);
Ok((one, 0)) Ok((one, 0))
} }

View File

@ -80,25 +80,31 @@ pub struct Vec2<T> {
impl<T> Vec2<T> { impl<T> Vec2<T> {
fn new(columns: usize) -> Vec2<T> { pub fn new(columns: usize) -> Vec2<T> {
Vec2 {data: Vec::<T>::new(), columns} Vec2 {data: Vec::<T>::new(), columns}
} }
fn push<S: IntoIterator<Item=T>>(&mut self, row: S) { pub fn push<S: IntoIterator<Item=T>>(&mut self, row: S) {
self.data.extend(row.into_iter()); self.data.extend(row.into_iter());
} }
// This works just fine, for some reason pub fn row_count(&self) -> usize {
fn rows(&self) -> impl Iterator<Item=&[T]> { self.data.len() / self.columns
}
pub fn col_count(&self) -> usize {
self.columns
}
pub fn rows(&self) -> impl Iterator<Item=&[T]> {
self.data.chunks_exact(self.columns) self.data.chunks_exact(self.columns)
} }
// But this doesn't? pub fn rows_mut(&mut self) -> impl Iterator<Item=&mut [T]> {
fn rows_mut(&mut self) -> impl Iterator<Item=&mut [T]> {
self.data.chunks_exact_mut(self.columns) self.data.chunks_exact_mut(self.columns)
} }
fn values(&self) -> impl Iterator<Item=&T> { pub fn values(&self) -> impl Iterator<Item=&T> {
self.data.iter() self.data.iter()
} }
} }