use automata::FiniteAutomaton;
pub(crate) struct Grain {
low: u64,
high: u16,
}
const MASK: u64 = 0x40_08_00_40_00_80_20_01;
impl Grain {
}
impl FiniteAutomaton for Grain {
type Init = (u64, u16);
type State = (u64, u16);
type Input = ();
type Output = bool;
fn init(init: Self::Init) -> Self {
let (low, high) = init;
Grain { low, high }
}
fn transition_mut(&mut self, _input: Self::Input) -> Self::Output {
let bits_to_xor = self.low & MASK;
let xor_of_bits = bits_to_xor.count_ones() % 2;
self.low >>= 1;
let bit_to_transfer = self.high & 0b1;
self.low |= (bit_to_transfer as u64) << 63;
self.high >>= 1;
match xor_of_bits {
0 => {
self.high |= 0b0000_0000_0000_0000;
false
}
_ => {
self.high |= 0b1000_0000_0000_0000;
true
}
}
}
}