day18: formatting and cleanup
This commit is contained in:
parent
3bc073f9b8
commit
8d178ddfc6
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user