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