completely rework day 9, still broken though
This commit is contained in:
parent
6cc7cb8752
commit
8991100b59
117
2021/src/day9.rs
117
2021/src/day9.rs
@ -1,23 +1,24 @@
|
||||
use color_eyre::eyre;
|
||||
use eyre::eyre;
|
||||
|
||||
use crate::lib::Vec2;
|
||||
|
||||
// #[derive(Eq, PartialEq)]
|
||||
enum Elevation {
|
||||
High,
|
||||
Mid,
|
||||
Low,
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Cell {
|
||||
height: u32,
|
||||
min: bool,
|
||||
}
|
||||
use Elevation::*;
|
||||
|
||||
|
||||
fn load(data: &str) -> eyre::Result<Vec<Vec<u32>>> {
|
||||
let mut heights = Vec::new();
|
||||
fn load(data: &str) -> eyre::Result<Vec2<Cell>> {
|
||||
let num_columns = data.lines().next().unwrap().len();
|
||||
let mut heights = Vec2::new(num_columns);
|
||||
for line in data.lines() {
|
||||
let mut row = Vec::new();
|
||||
for c in line.chars() {
|
||||
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)),
|
||||
}
|
||||
}
|
||||
@ -27,79 +28,63 @@ fn load(data: &str) -> eyre::Result<Vec<Vec<u32>>> {
|
||||
}
|
||||
|
||||
|
||||
fn cmp_horizontal(row: &[u32], pos: usize) -> Elevation {
|
||||
let prev = if pos == 0 {None} else {Some(row[pos - 1])};
|
||||
let next = if pos == row.len() - 1 {None} else {Some(row[pos + 1])};
|
||||
let current = row[pos];
|
||||
|
||||
if current > prev.unwrap_or(0) && current > next.unwrap_or(0) {
|
||||
High
|
||||
fn scan(map: &mut Vec2<Cell>) {
|
||||
for r in 0..map.row_count() {
|
||||
for col in 0..map.col_count() {
|
||||
if col > 0 {
|
||||
if map[r][col].height <= map[r][col - 1].height {
|
||||
map[r][col - 1].min = false;
|
||||
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 {
|
||||
let above = &result[r - 1][col];
|
||||
if let (&High, &High) | (&Low, &Low) = (&elev, above) {
|
||||
result[r - 1][col] = Mid;
|
||||
if map[r][col].height <= map[r - 1][col].height {
|
||||
map[r - 1][col].min = false;
|
||||
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 {
|
||||
let mut result = 0;
|
||||
for (r, row) in compares.iter().enumerate() {
|
||||
for (col, elev) in row.iter().enumerate() {
|
||||
if let Low = elev {
|
||||
result += map[r][col] + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
result
|
||||
fn part1(map: &Vec2<Cell>) -> u32 {
|
||||
map.values()
|
||||
.filter(|c| c.min)
|
||||
.fold(0, |acc, c| acc + c.height + 1)
|
||||
}
|
||||
|
||||
|
||||
pub fn run(data: &str) -> eyre::Result<(u32, u32)> {
|
||||
let map = load(data)?;
|
||||
let compares = scan(&map);
|
||||
let sample = "2199943210\n3987894921\n9856789892\n8767896789\n9899965678";
|
||||
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))
|
||||
}
|
||||
|
@ -80,25 +80,31 @@ pub struct 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}
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
// This works just fine, for some reason
|
||||
fn rows(&self) -> impl Iterator<Item=&[T]> {
|
||||
pub fn row_count(&self) -> usize {
|
||||
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)
|
||||
}
|
||||
|
||||
// But this doesn't?
|
||||
fn rows_mut(&mut self) -> impl Iterator<Item=&mut [T]> {
|
||||
pub fn rows_mut(&mut self) -> impl Iterator<Item=&mut [T]> {
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user