Start day 14 - Docking Data
This commit is contained in:
94
14-docking_data/src/main.rs
Normal file
94
14-docking_data/src/main.rs
Normal file
@@ -0,0 +1,94 @@
|
||||
use std::{collections::HashMap, convert::{TryFrom}, str::FromStr};
|
||||
|
||||
#[derive(Debug, PartialEq, thiserror::Error)]
|
||||
enum DDError {
|
||||
#[error("Mask Error: {0}")]
|
||||
MaskError(&'static str)
|
||||
}
|
||||
#[derive(Debug, PartialEq)]
|
||||
enum MaskItem {
|
||||
Zero,
|
||||
One,
|
||||
X,
|
||||
}
|
||||
|
||||
impl TryFrom<char> for MaskItem {
|
||||
type Error = DDError;
|
||||
|
||||
fn try_from(c: char) -> Result<Self, Self::Error> {
|
||||
Ok(match c {
|
||||
'0' => MaskItem::Zero,
|
||||
'1' => MaskItem::One,
|
||||
'X' => MaskItem::X,
|
||||
_ => return Err(DDError::MaskError("Invalid Mask character"))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type Mem = HashMap<i64, i64>;
|
||||
struct Mask {
|
||||
set: i64,
|
||||
reset: i64,
|
||||
}
|
||||
|
||||
impl Default for Mask {
|
||||
fn default() -> Self {
|
||||
Mask {
|
||||
set: 0,
|
||||
reset: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Mask {
|
||||
type Err = DDError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let (mut set, mut reset) = (0, 0);
|
||||
for (shift, c) in s.chars().rev().enumerate() {
|
||||
match MaskItem::try_from(c)? {
|
||||
MaskItem::Zero => reset |= 1 << shift,
|
||||
MaskItem::One => set |= 1<<shift,
|
||||
MaskItem::X => {}
|
||||
};
|
||||
}
|
||||
Ok(Mask {set,reset})
|
||||
}
|
||||
}
|
||||
|
||||
impl Mask {
|
||||
fn apply(&self, n: i64) -> i64 {
|
||||
(n | self.set) & !self.reset
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::convert::TryInto;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_char() {
|
||||
assert_eq!(TryInto::<MaskItem>::try_into('X').unwrap(), MaskItem::X);
|
||||
assert_eq!(TryInto::<MaskItem>::try_into('1').unwrap(), MaskItem::One);
|
||||
assert_eq!(TryInto::<MaskItem>::try_into('0').unwrap(), MaskItem::Zero);
|
||||
assert_eq!(TryInto::<MaskItem>::try_into('d').is_err(), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mask() {
|
||||
let mask = Mask {
|
||||
set: 12, // 0b001100
|
||||
reset: 19, // 0b010011
|
||||
};
|
||||
// 31 = 0b011111
|
||||
assert_eq!(mask.apply(31), 12);
|
||||
// 32 = 0b100000
|
||||
assert_eq!(mask.apply(32), 44);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user