From 48952406d6b55fc32d53b3f2cbf090b11bf8440f Mon Sep 17 00:00:00 2001 From: William Ball Date: Thu, 9 Jul 2020 07:26:54 -0700 Subject: [PATCH] squarefree --- non_squarefree/src/main.rs | 8 +-- squarefree/Cargo.toml | 10 ++++ squarefree/src/main.rs | 106 +++++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 squarefree/Cargo.toml create mode 100644 squarefree/src/main.rs diff --git a/non_squarefree/src/main.rs b/non_squarefree/src/main.rs index 04e6810..0c2725c 100644 --- a/non_squarefree/src/main.rs +++ b/non_squarefree/src/main.rs @@ -90,12 +90,14 @@ fn is_squarefree(n: u64, square_free: &mut HashMap) -> bool { match square_free.get(&n) { Some(val) => *val, None => { - let n = n as usize; - for prime in primal::Primes::all().take(n) { - if n % (prime * prime) == 0 { + let n2 = n as usize; + for prime in primal::Primes::all().take(n2) { + if n2 % (prime * prime) == 0 { + square_free.insert(n, false); return false; } } + square_free.insert(n, true); true } } diff --git a/squarefree/Cargo.toml b/squarefree/Cargo.toml new file mode 100644 index 0000000..3482c62 --- /dev/null +++ b/squarefree/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "non_squarefree" +version = "0.1.0" +authors = ["William Ball "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +primal = "0.3.0" diff --git a/squarefree/src/main.rs b/squarefree/src/main.rs new file mode 100644 index 0000000..d6b7639 --- /dev/null +++ b/squarefree/src/main.rs @@ -0,0 +1,106 @@ +use std::collections::HashMap; + +#[derive(Debug)] +struct Tree { + value: u64, + children: Vec, +} + +impl Tree { + fn new(value: u64, children: Vec) -> Tree { + let mut tree_children = Vec::with_capacity(children.len()); + for child in children { + tree_children.push(Tree::new(child, Vec::new())); + } + Tree { + value, + children: tree_children, + } + } + + fn step(&mut self, square_free: &mut HashMap) { + if self.children.is_empty() { + let xs = step_end(self.value, square_free); + for val in xs { + self.children.push(Tree::new(val, Vec::new())); + } + return; + } + for child in &mut self.children { + child.step(square_free); + } + } + + fn longest_path(&self) -> Vec { + if self.children.is_empty() { + return vec![self.value]; + } + let mut max_path = vec![]; + let mut max_length = 0; + for child in &self.children { + let temp = child.longest_path(); + if temp.len() > max_length { + max_length = temp.len(); + max_path = temp; + } + } + let mut retval = vec![self.value]; + retval.append(&mut max_path); + return retval; + } + + fn to_string(&self) -> String { + let mut retval = format!("[{}: ", self.value); + for child in &self.children { + retval.push_str(&child.to_string()[..]); + } + retval.push(']'); + retval + } + + fn count(&self) -> usize { + if self.children.is_empty() { + return 1; + } + return self.children.iter().fold(0, |mut sum, x| { sum += x.count(); sum }); + } +} + +fn step_end(x: u64, square_free: &mut HashMap) -> Vec { + let mut new_xs = Vec::new(); + for d in 0..10 { + let temp = x * 10 + d; + if is_squarefree(temp, square_free) { + new_xs.push(temp); + } + } + return new_xs; +} + +fn is_squarefree(n: u64, square_free: &mut HashMap) -> bool { + match square_free.get(&n) { + Some(val) => *val, + None => { + let n2 = n as usize; + for prime in primal::Primes::all().take(n2) { + if n2 % (prime * prime) == 0 { + square_free.insert(n, false); + return false; + } + } + square_free.insert(n, true); + true + } + } +} + +fn main() { + let mut tree = Tree::new(0, vec![1, 2, 3, 5, 6, 7]); + let mut square_free: HashMap = HashMap::new(); + for _ in 0..10 { + tree.step(&mut square_free); + println!("{:?}", tree.longest_path()); + println!("{}", tree.count()); + } + println!("{:?}", tree.to_string()); +}