~janbaudisch/euler-rs

df5d167a9b7d1dd23934994730f495c48ca5234c — Jan Baudisch 5 years ago e2fc659
common: add binary representation
A common/src/format/binary.rs => common/src/format/binary.rs +46 -0
@@ 0,0 1,46 @@
#[derive(Clone, Copy, PartialEq)]
pub enum Bit {
    One,
    Zero
}

pub trait ToBinary {
    fn to_binary(self) -> Vec<Bit>;
}

macro_rules! impl_to_binary {
    ($type: ident) => {
        impl ToBinary for $type {
            fn to_binary(self) -> Vec<Bit> {
                let mut n: $type = self;
                let mut bits = Vec::new();

                loop {
                    if n == 0 {
                        break;
                    }

                    let remainder = n % 2;

                    match remainder {
                        0 => bits.push(Bit::Zero),
                        1 => bits.push(Bit::One),
                        _ => bits.push(Bit::Zero),
                    }

                    n = n / 2;
                }

                bits.reverse();

                bits
            }
        }
    };
}

impl_to_binary!(u8);
impl_to_binary!(u16);
impl_to_binary!(u32);
impl_to_binary!(u64);
impl_to_binary!(u128);

A common/src/format/mod.rs => common/src/format/mod.rs +3 -0
@@ 0,0 1,3 @@
mod binary;

pub use binary::*;

M common/src/lib.rs => common/src/lib.rs +1 -0
@@ 1,2 1,3 @@
pub mod input;
pub mod format;
pub mod math;

M common/src/math/palindrome.rs => common/src/math/palindrome.rs +30 -1
@@ 1,3 1,5 @@
use crate::format::Bit;

pub trait IsPalindrome {
    fn is_palindrome(self) -> bool;
}


@@ 8,7 10,9 @@ macro_rules! impl_is_palindrome {
            fn is_palindrome(self) -> bool {
                let digits = self.to_string().chars().collect::<Vec<char>>();

                let (left, right) = if &digits.len() % 2 == 0 {
                let no_middle = &digits.len() % 2 == 0;

                let (left, right) = if no_middle {
                    digits.split_at(digits.len() / 2)
                } else {
                    digits.split_at((digits.len() - 1) / 2)


@@ 17,12 21,37 @@ macro_rules! impl_is_palindrome {
                let mut right = right.to_vec();
                right.reverse();

                if !no_middle {
                    right.pop();
                }

                left == right.as_slice()
            }
        }
    };
}

impl IsPalindrome for Vec<Bit> {
    fn is_palindrome(self) -> bool {
        let no_middle = &self.len() % 2 == 0;

        let (left, right) = if no_middle {
            self.split_at(self.len() / 2)
        } else {
            self.split_at((self.len() - 1) / 2)
        };

        let mut right = right.to_vec();
        right.reverse();

        if !no_middle {
            right.pop();
        }

        left == right.as_slice()
    }
}

impl_is_palindrome!(u8);
impl_is_palindrome!(u16);
impl_is_palindrome!(u32);