mirror of
https://github.com/Noratrieb/advent-of-code.git
synced 2026-01-14 17:45:02 +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,
|
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<'_> {
|
impl Candidates<'_> {
|
||||||
fn push(&mut self, new: Candidate) {
|
fn push(&mut self, new: Candidate) {
|
||||||
match (new.came_from, self.bytes[new.pos]) {
|
match (new.came_from, self.bytes[new.pos]) {
|
||||||
|
|
@ -71,39 +84,31 @@ impl Candidates<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_left(&mut self, from: Candidate) {
|
fn push_left(&mut self, from: Candidate) {
|
||||||
if from.came_from != Direction::Left && from.pos % self.width > 0 {
|
if from.came_from != Direction::Left {
|
||||||
self.push(Candidate::new(
|
if let Some(left) = left(from.pos, self.width) {
|
||||||
from.count + 1,
|
self.push(Candidate::new(from.count + 1, left, Direction::Right));
|
||||||
from.pos - 1,
|
}
|
||||||
Direction::Right,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn push_right(&mut self, from: Candidate) {
|
fn push_right(&mut self, from: Candidate) {
|
||||||
if from.came_from != Direction::Right && (from.pos % self.width) < (self.width - 1) {
|
if from.came_from != Direction::Right {
|
||||||
self.push(Candidate::new(
|
if let Some(right) = right(from.pos, self.width) {
|
||||||
from.count + 1,
|
self.push(Candidate::new(from.count + 1, right, Direction::Left));
|
||||||
from.pos + 1,
|
}
|
||||||
Direction::Left,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn push_top(&mut self, from: Candidate) {
|
fn push_top(&mut self, from: Candidate) {
|
||||||
if from.came_from != Direction::Top && from.pos >= self.width {
|
if from.came_from != Direction::Top {
|
||||||
self.push(Candidate::new(
|
if let Some(top) = top(from.pos, self.width) {
|
||||||
from.count + 1,
|
self.push(Candidate::new(from.count + 1, top, Direction::Bottom));
|
||||||
from.pos - self.width,
|
}
|
||||||
Direction::Bottom,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn push_bottom(&mut self, from: Candidate) {
|
fn push_bottom(&mut self, from: Candidate) {
|
||||||
if from.came_from != Direction::Bottom && from.pos < (self.len - self.width) {
|
if from.came_from != Direction::Bottom {
|
||||||
self.push(Candidate::new(
|
if let Some(bottom) = bottom(from.pos, self.bytes.len(), self.width) {
|
||||||
from.count + 1,
|
self.push(Candidate::new(from.count + 1, bottom, Direction::Top));
|
||||||
from.pos + self.width,
|
}
|
||||||
Direction::Top,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -247,12 +252,14 @@ fn part1(input: &str) -> u64 {
|
||||||
get_loop(input).highest_value
|
get_loop(input).highest_value
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part2(_input: &str) -> u64 {
|
fn part2(input: &str) -> u64 {
|
||||||
// Step 1: Find the loop
|
// Step 1: Find the loop
|
||||||
// We do this by using the step-map from before, counting backwards from the target basically.
|
// 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
|
// Step 2: Cellular-automata-ish, start from the borders and start eating away
|
||||||
// everything connected to that, only stopping at the main loop.
|
// everything connected to that, only stopping at the main loop.
|
||||||
// Open question: How do we squeeze between main loop pipes?
|
// 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
|
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