Add day 10 part 1 (rough version)
parent
33362cef62
commit
7e12367e85
|
|
@ -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()
|
||||
}
|
||||
|
|
@ -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
|
||||
)
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue