Start day 14 - Docking Data

This commit is contained in:
2021-03-07 14:44:24 +10:00
parent fc8d16b6b8
commit f22e47f5c5
4 changed files with 737 additions and 0 deletions

View 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);
}
}