day18: formatting and cleanup

This commit is contained in:
Keenan Tims 2023-12-18 02:03:48 -08:00
parent 3bc073f9b8
commit 8d178ddfc6
Signed by: ktims
GPG Key ID: 11230674D69038D4

View File

@ -1,9 +1,7 @@
use itertools::Itertools;
use std::collections::{HashMap, LinkedList};
use std::fmt::{Display, Write};
use std::collections::LinkedList;
use std::fs::File;
use std::io::{BufRead, BufReader, Lines};
use std::ops::Range;
use std::time::Instant;
// BOILERPLATE
@ -47,12 +45,7 @@ enum Turn {
impl Direction {
const fn all() -> &'static [Self; 4] {
&[
Direction::Left,
Direction::Right,
Direction::Up,
Direction::Down,
]
&[Direction::Left, Direction::Right, Direction::Up, Direction::Down]
}
const fn opposite(&self) -> Self {
match self {
@ -127,13 +120,7 @@ impl From<&str> for DigInstruction {
let (dir, count, color) = (
parts.next().unwrap(),
parts.next().unwrap(),
parts
.next()
.unwrap()
.chars()
.skip(2)
.take(6)
.collect::<String>(),
parts.next().unwrap().chars().skip(2).take(6).collect::<String>(),
);
Self {
dir: dir.into(),
@ -152,7 +139,7 @@ impl DigInstruction {
"1" => Direction::Down,
"2" => Direction::Left,
"3" => Direction::Up,
s => panic!("`{}` is not a valid direction code", s)
s => panic!("`{}` is not a valid direction code", s),
};
}
}
@ -177,9 +164,7 @@ struct DigTile {
impl Default for DigTile {
fn default() -> Self {
Self {
position: (0, 0),
}
Self { position: (0, 0) }
}
}
@ -188,9 +173,6 @@ type Position = (isize, isize);
#[derive(Debug)]
struct DigHole {
tiles_loop: LinkedList<DigTile>,
tiles_map: HashMap<Position, DigTile>,
x_range: Range<isize>,
y_range: Range<isize>,
area: u64,
}
@ -203,9 +185,6 @@ impl DigHole {
fn new() -> Self {
DigHole {
tiles_loop: LinkedList::new(),
tiles_map: HashMap::new(),
x_range: 0..0,
y_range: 0..0,
area: 0,
}
}
@ -215,9 +194,7 @@ impl DigHole {
fn run_plan(&mut self, plan: &DigPlan) {
let mut cur_pos = (0, 0);
self.tiles_loop.push_back(DigTile {
position: cur_pos,
});
self.tiles_loop.push_back(DigTile { position: cur_pos });
let mut move_offset;
for (idx, i) in plan.instructions.iter().enumerate() {
let prev_instruction = if idx > 0 {
@ -225,17 +202,14 @@ impl DigHole {
} else {
&plan.instructions[plan.instructions.len() - 1]
};
let Some(next_instruction) = plan
.instructions
.get(idx + 1)
.or(Some(&plan.instructions[0]))
else {
let Some(next_instruction) = plan.instructions.get(idx + 1).or(Some(&plan.instructions[0])) else {
panic!()
};
let cur_turn = prev_instruction.dir.turn_kind(i.dir);
let next_turn = i.dir.turn_kind(next_instruction.dir);
// point needs to live on the 'outside' corner of the character. to
// achieve this we need to offset the move by the following
// Point needs to live on the 'outside' corner of the character. to achieve this we need to offset the move
// by the following. Found this empirically but there's probably some mathematical principle behind it...
move_offset = match (cur_turn, next_turn) {
(Turn::RightNinety, Turn::RightNinety) => 1,
(Turn::RightNinety, Turn::LeftNinety) => 0,
@ -244,14 +218,8 @@ impl DigHole {
t => panic!("turn {:?} not allowed here", t),
};
cur_pos = self.pos_offset_n(
cur_pos,
i.dir.offset(),
(i.count as isize + move_offset) as usize,
);
self.tiles_loop.push_back(DigTile {
position: cur_pos,
});
cur_pos = self.pos_offset_n(cur_pos, i.dir.offset(), (i.count as isize + move_offset) as usize);
self.tiles_loop.push_back(DigTile { position: cur_pos });
}
// Shoelace formula
@ -266,36 +234,15 @@ impl DigHole {
}
}
impl Display for DigHole {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for y in self.y_range.clone() {
for x in self.x_range.clone() {
f.write_char(if (x, y) == (133, -267) {
'*'
} else if self.tiles_map.contains_key(&(x, y)) {
'#'
} else {
'.'
})?;
}
writeln!(f)?;
}
Ok(())
}
}
impl<T: BufRead> From<Lines<T>> for DigPlan {
fn from(lines: Lines<T>) -> Self {
Self {
instructions: lines
.map(|line| DigInstruction::from(line.unwrap().as_str()))
.collect(),
instructions: lines.map(|line| DigInstruction::from(line.unwrap().as_str())).collect(),
}
}
}
// PROBLEM 1 solution
fn problem1<T: BufRead>(input: Lines<T>) -> u64 {
let plan = DigPlan::from(input);
let mut dig = DigHole::new();