Add day 7 part 2 + refactor day 1

bram
Bram 2025-12-07 14:53:41 +01:00
parent 61e0d608cc
commit 4f5cf2e4c4
1 changed files with 37 additions and 77 deletions

View File

@ -1,107 +1,67 @@
use crate::utils; use crate::utils;
use std::collections::HashMap;
pub fn answer(text : String) -> ( u16, u16 ) { pub fn answer(text : String) -> ( u16, u64 ) {
( text.trim() let tachyons: TachyonLayer = text.trim()
.split_whitespace() .split_whitespace()
.fold(TachyonLayer::new(), |tl, s| tl.next_layer(s)) .fold(
.splits TachyonLayer::new(),
// 71 incorrect |tl, s| tl.next_layer(s)
// 1652 too high );
, 0
( tachyons.splits
, tachyons.beams.values().sum()
) )
} }
struct TachyonLayer { struct TachyonLayer {
beams : Vec<u8>, beams : HashMap<usize, u64>,
layer: u8,
splits : u16, splits : u16,
} }
impl TachyonLayer { impl TachyonLayer {
fn get(&self, x : &usize) -> &u64 {
self.beams.get(x).unwrap_or(&0)
}
fn insert(&mut self, x : usize, amount : u64) {
self.beams
.entry(x)
.and_modify(|v| *v += amount)
.or_insert(amount);
}
fn new() -> TachyonLayer { fn new() -> TachyonLayer {
TachyonLayer { TachyonLayer {
beams : Vec::new(), beams : HashMap::new(),
layer : 0,
splits : 0, splits : 0,
} }
} }
fn next_layer(&self, manifold : &str) -> TachyonLayer { fn next_layer(&self, manifold : &str) -> TachyonLayer {
// println!("----------------------------------"); let mut new_beams = TachyonLayer::new();
// println!("Old layer looks like: {:?}", self.beams); new_beams.splits += self.splits;
// Currently tracked beams for (x, c) in manifold.chars().enumerate() {
// The list is sorted to make iteration easier
let mut beam_i: usize = 0;
let mut beam: Option<u8> = self.beams.get(beam_i).map(|&b| b);
// Last pushed beam, to avoid duplicates
let mut latest_push: Option<usize> = None;
// New Layer data
let mut new: Vec<u8> = Vec::new();
let mut splits: u16 = self.splits;
// Loop over the manifold string
for (i, c) in manifold.chars().enumerate() {
match c { match c {
'S' => {
new_beams.insert(x, 1);
},
'.' => { '.' => {
if let Some(b) = beam { new_beams.insert(x, *self.get(&x));
if i == usize::from(b) {
if let Some(lp) = latest_push {
if i == lp {} else {
new.push(b);
}
} else {
new.push(b);
}
beam_i += 1;
beam = self.beams.get(beam_i).map(|&b| b);
latest_push = Some(i);
}
}
}, },
'^' => { '^' => {
if let Some(b) = beam { let &rays: &u64 = self.get(&x);
if i == usize::from(b) {
if let Some(lp) = latest_push {
if i - 1 == lp {} else {
new.push(b-1);
}
} else {
new.push(b-1);
}
new.push(b+1);
beam_i += 1; if rays > 0 {
beam = self.beams.get(beam_i).map(|&b| b); new_beams.splits += 1;
new_beams.insert(x - 1, rays);
latest_push = Some(i+1); new_beams.insert(x + 1, rays);
splits += 1;
// println!("Encountered split #{} at x={} and y={}", splits, i, self.layer);
}
} }
}, },
'S' => { _ => {},
new.push(i as u8);
latest_push = Some(i);
if let Some(b) = beam {
if i == usize::from(b) {
beam_i += 1;
beam = self.beams.get(beam_i).map(|&b| b);
}
}
},
_ => {
panic!("Encountered unexpected input char")
},
} }
} }
// println!("New layer looks like: {:?}", new); new_beams
TachyonLayer { beams: new, layer : self.layer + 1, splits: splits }
} }
} }