mirror of
https://github.com/Noratrieb/advent-of-code.git
synced 2026-01-14 09:35:01 +01:00
cleanup
This commit is contained in:
parent
c54bc78362
commit
aa651ae78c
2 changed files with 107 additions and 25 deletions
|
|
@ -59,6 +59,19 @@ enum Direction {
|
|||
None,
|
||||
}
|
||||
|
||||
fn left(pos: usize, width: usize) -> Option<usize> {
|
||||
(pos % width > 0).then(|| pos - 1)
|
||||
}
|
||||
fn right(pos: usize, width: usize) -> Option<usize> {
|
||||
((pos % width) < (width - 1)).then(|| pos + 1)
|
||||
}
|
||||
fn top(pos: usize, width: usize) -> Option<usize> {
|
||||
(pos >= width).then(|| pos - width)
|
||||
}
|
||||
fn bottom(pos: usize, len: usize, width: usize) -> Option<usize> {
|
||||
(pos < (len - width)).then(|| pos + width)
|
||||
}
|
||||
|
||||
impl Candidates<'_> {
|
||||
fn push(&mut self, new: Candidate) {
|
||||
match (new.came_from, self.bytes[new.pos]) {
|
||||
|
|
@ -71,39 +84,31 @@ impl Candidates<'_> {
|
|||
}
|
||||
|
||||
fn push_left(&mut self, from: Candidate) {
|
||||
if from.came_from != Direction::Left && from.pos % self.width > 0 {
|
||||
self.push(Candidate::new(
|
||||
from.count + 1,
|
||||
from.pos - 1,
|
||||
Direction::Right,
|
||||
));
|
||||
if from.came_from != Direction::Left {
|
||||
if let Some(left) = left(from.pos, self.width) {
|
||||
self.push(Candidate::new(from.count + 1, left, Direction::Right));
|
||||
}
|
||||
}
|
||||
}
|
||||
fn push_right(&mut self, from: Candidate) {
|
||||
if from.came_from != Direction::Right && (from.pos % self.width) < (self.width - 1) {
|
||||
self.push(Candidate::new(
|
||||
from.count + 1,
|
||||
from.pos + 1,
|
||||
Direction::Left,
|
||||
));
|
||||
if from.came_from != Direction::Right {
|
||||
if let Some(right) = right(from.pos, self.width) {
|
||||
self.push(Candidate::new(from.count + 1, right, Direction::Left));
|
||||
}
|
||||
}
|
||||
}
|
||||
fn push_top(&mut self, from: Candidate) {
|
||||
if from.came_from != Direction::Top && from.pos >= self.width {
|
||||
self.push(Candidate::new(
|
||||
from.count + 1,
|
||||
from.pos - self.width,
|
||||
Direction::Bottom,
|
||||
));
|
||||
if from.came_from != Direction::Top {
|
||||
if let Some(top) = top(from.pos, self.width) {
|
||||
self.push(Candidate::new(from.count + 1, top, Direction::Bottom));
|
||||
}
|
||||
}
|
||||
}
|
||||
fn push_bottom(&mut self, from: Candidate) {
|
||||
if from.came_from != Direction::Bottom && from.pos < (self.len - self.width) {
|
||||
self.push(Candidate::new(
|
||||
from.count + 1,
|
||||
from.pos + self.width,
|
||||
Direction::Top,
|
||||
));
|
||||
if from.came_from != Direction::Bottom {
|
||||
if let Some(bottom) = bottom(from.pos, self.bytes.len(), self.width) {
|
||||
self.push(Candidate::new(from.count + 1, bottom, Direction::Top));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -247,12 +252,14 @@ fn part1(input: &str) -> u64 {
|
|||
get_loop(input).highest_value
|
||||
}
|
||||
|
||||
fn part2(_input: &str) -> u64 {
|
||||
fn part2(input: &str) -> u64 {
|
||||
// Step 1: Find the loop
|
||||
// We do this by using the step-map from before, counting backwards from the target basically.
|
||||
// Step 2: Cellular-automata-ish, start from the borders and start eating away
|
||||
// everything connected to that, only stopping at the main loop.
|
||||
// Open question: How do we squeeze between main loop pipes?
|
||||
let the_loop = get_loop(input);
|
||||
let mut tiles = vec![0; the_loop.step_map.len()];
|
||||
|
||||
0
|
||||
}
|
||||
|
|
|
|||
75
file.rs
Normal file
75
file.rs
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
use std::ops::Add;
|
||||
|
||||
fn parse(input: &str, into: &mut Vec<i64>, mut line_callback: impl FnMut(&mut Vec<i64>)) {
|
||||
let mut neg = false;
|
||||
let mut acc = 0;
|
||||
|
||||
for byte in input.bytes() {
|
||||
match byte {
|
||||
b' ' => {
|
||||
if neg {
|
||||
acc = -acc
|
||||
};
|
||||
into.push(acc);
|
||||
acc = 0;
|
||||
neg = false;
|
||||
}
|
||||
b'-' => neg = true,
|
||||
b'\n' => {
|
||||
if neg {
|
||||
acc = -acc
|
||||
};
|
||||
into.push(acc);
|
||||
line_callback(into);
|
||||
into.clear();
|
||||
acc = 0;
|
||||
neg = false;
|
||||
}
|
||||
// must be b'0'..=b'9'
|
||||
_ => {
|
||||
let value = byte - b'0';
|
||||
acc = (acc * 10) + (value as i64);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn execute(
|
||||
input: &str,
|
||||
last_or_first: impl Fn(&[i64]) -> i64,
|
||||
fold: impl Fn(i64, i64) -> i64 + Copy,
|
||||
) -> i64 {
|
||||
let mut row1 = Vec::with_capacity(128);
|
||||
let mut row2 = Vec::with_capacity(128);
|
||||
|
||||
let mut last_values = Vec::with_capacity(16);
|
||||
|
||||
let mut total = 0;
|
||||
|
||||
parse(input, &mut row1, |row1| {
|
||||
row2.clone_from(&row1);
|
||||
|
||||
last_values.clear();
|
||||
last_values.push(last_or_first(&row1));
|
||||
while !row2.iter().all(|&n| n == 0) {
|
||||
row1.clear();
|
||||
row1.extend(row2.windows(2).map(|s| s[1] - s[0]));
|
||||
|
||||
last_values.push(last_or_first(&row1));
|
||||
|
||||
std::mem::swap(row1, &mut row2);
|
||||
}
|
||||
|
||||
total += last_values.iter().copied().rev().fold(0, fold);
|
||||
});
|
||||
|
||||
total
|
||||
}
|
||||
|
||||
pub fn run(input: &str) -> u64 {
|
||||
execute(input, |s| *s.last().unwrap(), Add::add) as u64
|
||||
}
|
||||
|
||||
pub fn part2(input: &str) -> u64 {
|
||||
execute(input, |s| *s.first().unwrap(), |a, b| b - a) as u64
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue