#[derive(PartialEq, Debug, Clone)]
pub enum NatNum {
Zero,
Mult(Vec<NatNum>),
}
impl NatNum {
pub fn to_number(&self) -> u32 {
match self {
NatNum::Zero => return 0,
NatNum::Mult(nat_num) => return simple_nat_to_num(nat_num),
}
}
pub fn add_rec(&self, other: &NatNum) -> NatNum {
match &self {
NatNum::Zero => return other.clone(),
NatNum::Mult(tree1) => {
match other {
NatNum::Zero => return self.clone(),
NatNum::Mult(tree2) => {
if tree1.len() >= tree2.len() {
let mut tree_data = tree1.clone();
recursive_nat_tree_increment(&mut tree_data, tree2.len() as u32);
return NatNum::Mult(tree_data)
} else {
let mut tree_data = tree2.clone();
recursive_nat_tree_increment(&mut tree_data, tree1.len() as u32);
return NatNum::Mult(tree_data)
}
}
}
}
}
}
pub fn to_number_checked(&self) -> u32 {
unimplemented!()
}
pub fn to_string(&self) -> String {
match self {
NatNum::Zero => String::from("{}"),
NatNum::Mult(tree) => {
let mut graph = String::from("{}\n");
recursive_nat_tree_to_string_simple(tree, &mut graph, 0);
graph
}
}
}
}
impl From<u32> for NatNum {
fn from(num: u32) -> NatNum {
if num == 0 {
return NatNum::Zero
}
let mut nat_num_data: Vec<NatNum> = Vec::new();
populate_nat_tree(&mut nat_num_data, num);
let nat_num = NatNum::Mult(nat_num_data);
nat_num
}
}
fn simple_nat_to_num(num: &Vec<NatNum>) -> u32 {
return num.len() as u32;
}
fn populate_nat_tree(tree: &mut Vec<NatNum>, curr: u32) {
match curr {
0 => return,
1 => {
tree.insert(0,NatNum::Zero);
populate_nat_tree(tree, curr - 1);
},
_ => {
let mut sub_tree_data = Vec::new();
populate_nat_tree(&mut sub_tree_data, curr - 1);
let sub_tree = NatNum::Mult(sub_tree_data);
tree.insert(0,sub_tree);
populate_nat_tree(tree, curr - 1)
},
}
}
fn recursive_nat_tree_increment(tree: &mut Vec<NatNum>, rem: u32) {
if rem == 0 {
return;
}
let new_subtree = tree.clone();
let end_num = NatNum::Mult(new_subtree);
tree.push(end_num);
recursive_nat_tree_increment(tree, rem - 1)
}
fn recursive_nat_tree_to_string_simple(tree: &Vec<NatNum>, graph: &mut String, level: u32) {
for x in tree {
match x {
NatNum::Zero => {
graph.push_str(&format!("{}{{}}\n", simple_graph_intonation(level)));
}
NatNum::Mult(subtree) => {
graph.push_str(&format!("{}{{}}\n", simple_graph_intonation(level)));
recursive_nat_tree_to_string_simple(subtree, graph, level + 1)
}
}
}
}
fn simple_graph_intonation(level: u32) -> String {
let mut intonation = String::new();
intonation.push_str("|");
for _ in 0..level {
intonation.push_str(" |");
}
intonation.push_str("->");
intonation
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn create_zero() {
let num = NatNum::Zero;
assert_eq!(num.to_number(), 0);
}
#[test]
fn create_one() {
let num = NatNum::Mult(vec![NatNum::Zero]);
assert_eq!(num.to_number(), 1)
}
#[test]
fn create_two() {
let num = NatNum::Mult(vec![NatNum::Zero, NatNum::Mult(vec![NatNum::Zero])]);
assert_eq!(num.to_number(), 2)
}
#[test]
#[rustfmt::skip]
fn create_three() {
let num = NatNum::Mult(vec![
NatNum::Zero,
NatNum::Mult(vec![
NatNum::Zero
]),
NatNum::Mult(vec![
NatNum::Zero,
NatNum::Mult(vec![
NatNum::Zero
])
]),
]);
assert_eq!(num.to_number(), 3)
}
#[test]
fn from_zero() {
let num = NatNum::from(0);
assert_eq!(num, NatNum::Zero);
assert_eq!(num.to_number(), 0);
}
#[test]
fn from_one() {
let num = NatNum::from(1);
assert_eq!(num, NatNum::Mult(vec![NatNum::Zero]));
assert_eq!(num.to_number(), 1);
}
#[test]
#[rustfmt::skip]
fn from_two() {
let num = NatNum::from(2);
assert_eq!(num, NatNum::Mult(vec![
NatNum::Zero,
NatNum::Mult(vec![
NatNum::Zero
])
]));
assert_eq!(num.to_number(), 2);
}
#[test]
#[rustfmt::skip]
fn from_three() {
let num = NatNum::from(3);
assert_eq!(num, NatNum::Mult(vec![
NatNum::Zero,
NatNum::Mult(vec![
NatNum::Zero
]),
NatNum::Mult(vec![
NatNum::Zero,
NatNum::Mult(vec![
NatNum::Zero
])
])
]));
}
#[test]
#[rustfmt::skip]
fn from_four() {
let num = NatNum::from(4);
assert_eq!(num, NatNum::Mult(vec![
NatNum::Zero,
NatNum::Mult(vec![
NatNum::Zero
]),
NatNum::Mult(vec![
NatNum::Zero,
NatNum::Mult(vec![
NatNum::Zero
])
]),
NatNum::Mult(vec![
NatNum::Zero,
NatNum::Mult(vec![
NatNum::Zero
]),
NatNum::Mult(vec![
NatNum::Zero,
NatNum::Mult(vec![
NatNum::Zero
])
])
])
]));
}
#[test]
fn add_zeros() {
let num1 = NatNum::from(0);
let num2 = NatNum::from(0);
let num3 = NatNum::from(2);
assert_eq!(num1.add_rec(&num2), NatNum::from(0));
assert_eq!(num1.add_rec(&num3), NatNum::from(2));
assert_eq!(num3.add_rec(&num1), NatNum::from(2));
}
#[test]
fn add_non_zero() {
let num1 = NatNum::from(1);
let num2 = NatNum::from(2);
let num3 = NatNum::from(3);
assert_eq!(num1.add_rec(&num2), NatNum::from(3));
assert_eq!(num2.add_rec(&num2), NatNum::from(4));
assert_eq!(num3.add_rec(&num2), NatNum::from(5));
}
#[test]
fn prints() {
let num0 = NatNum::from(0);
let num1 = NatNum::from(1);
let num4 = NatNum::from(4);
assert_eq!(num0.to_string(), "{}");
assert_eq!(num1.to_string(), "{}\n|->{}\n");
assert_eq!(num4.to_string(), "{}\n|->{}\n|->{}\n| |->{}\n|->{}\n| |->{}\n| |->{}\n| | |->{}\n|->{}\n| |->{}\n| |->{}\n| | |->{}\n| |->{}\n| | |->{}\n| | |->{}\n| | | |->{}\n");
}
}