Add day 10 part 1 (rough version)

bram
Bram 2025-12-10 10:26:47 +01:00
parent 33362cef62
commit 7e12367e85
3 changed files with 133 additions and 0 deletions

View File

@ -0,0 +1,55 @@
use crate::utils;
use super::test_machine::TestMachine;
use itertools::Itertools;
pub struct Machine<'a> {
exp_result: &'a str,
buttons: Vec<Vec<u8>>,
}
impl Machine<'_> {
pub fn from<'a>(text: &'a str) -> Option<Machine<'a>> {
let mut items = text.split_whitespace();
let ( res, _joltages ) = (items.next()?, items.next_back()?);
// Parse expected result string
let mut c = res.chars();
match ( c.next(), c.next_back() ) {
(Some('['), Some(']')) => {},
_ => { return None; },
}
Some(Machine {
exp_result: c.as_str(),
buttons: items.map(str_to_btn).collect(),
})
}
pub fn find_least_buttons(&self) -> u8 {
let mut pushes: u8 = 1;
loop {
if self.buttons
.iter()
.combinations(usize::from(pushes))
.any(|config| correct_config(config, self.exp_result))
{
break;
}
pushes += 1;
}
pushes
}
}
fn correct_config(config: Vec<&Vec<u8>>, exp_result: &str) -> bool {
let mut t = TestMachine::new();
t.push_buttons(config);
t.verify(exp_result)
}
fn str_to_btn(text: &str) -> Vec<u8> {
text.chars().filter_map(utils::char_to_u8).collect()
}

View File

@ -0,0 +1,24 @@
use crate::utils;
mod test_machine;
mod machine;
use itertools::Itertools;
use machine::Machine;
use test_machine::TestMachine;
pub fn answer(text: String) -> ( u32, u32 ) {
let machines: Vec<Machine> = text
.trim()
.split("\n")
.filter_map(Machine::from)
.collect();
( machines
.iter()
.map(|m| m.find_least_buttons())
.map(u32::from)
.sum()
, 0
)
}

View File

@ -0,0 +1,54 @@
pub struct TestMachine {
buttons: u16,
}
struct TestMachineIterator {
buttons: u16,
i: u8,
}
impl TestMachine {
fn iter(&self) -> TestMachineIterator {
TestMachineIterator { buttons: self.buttons, i: 0 }
}
pub fn new() -> TestMachine {
TestMachine { buttons: 0 }
}
fn push_button(&mut self, btns: &Vec<u8>) {
self.buttons = btns
.iter()
.fold(
self.buttons,
|tot, &btn| 2u16.pow(u32::from(btn)) ^ tot
);
}
pub fn push_buttons(&mut self, btns: Vec<&Vec<u8>>) {
for btn in btns {
self.push_button(btn);
}
}
pub fn verify(&self, text: &str) -> bool {
text.chars()
.zip(self.iter())
.all(|(c, turned_on)| (c == '#') == turned_on)
}
}
impl Iterator for TestMachineIterator {
type Item = bool;
fn next(&mut self) -> Option<Self::Item> {
let offset = self.i;
if offset >= 16 {
return None;
}
self.i += 1;
Some(((self.buttons >> offset) & 1) == 1)
}
}