diff --git a/.idea/misc.xml b/.idea/misc.xml
index c8116fe..fc4f7d3 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -46,6 +46,7 @@
+
diff --git a/.idea/rust.iml b/.idea/rust.iml
index e6bb3c9..42a672f 100644
--- a/.idea/rust.iml
+++ b/.idea/rust.iml
@@ -185,6 +185,10 @@
+
+
+
+
@@ -198,6 +202,7 @@
+
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 64ff647..a07822a 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -2,7 +2,9 @@
-
+
+
+
@@ -13,19 +15,10 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -33,35 +26,35 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -98,8 +91,6 @@
@@ -158,11 +151,11 @@
false
false
-
-
-
-
-
+
+
+
+
+
@@ -172,6 +165,7 @@
+
@@ -194,7 +188,6 @@
-
@@ -205,13 +198,18 @@
-
+
+
+
+
+
+
+
-
@@ -254,7 +252,7 @@
-
+
@@ -288,7 +286,7 @@
-
+
@@ -307,13 +305,13 @@
-
+
-
+
-
+
@@ -366,11 +364,11 @@
+
-
@@ -407,11 +405,11 @@
-
+
-
-
+
+
@@ -419,7 +417,7 @@
-
+
@@ -427,7 +425,7 @@
-
+
@@ -441,24 +439,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -819,13 +799,6 @@
-
-
-
-
-
-
-
@@ -833,13 +806,6 @@
-
-
-
-
-
-
-
@@ -847,17 +813,45 @@
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
diff --git a/factorial/Cargo.toml b/factorial/Cargo.toml
new file mode 100644
index 0000000..bc4c207
--- /dev/null
+++ b/factorial/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "factorial"
+version = "0.1.0"
+authors = ["Timothy Warren "]
+edition = "2018"
+
+[dependencies]
+separator = "0.4.0"
diff --git a/factorial/src/main.rs b/factorial/src/main.rs
new file mode 100644
index 0000000..9fc80b3
--- /dev/null
+++ b/factorial/src/main.rs
@@ -0,0 +1,73 @@
+extern crate separator;
+
+use separator::Separatable;
+
+use std::io;
+use std::u128;
+
+///! Calculate a number in the fibonnacci sequence,
+///! using a lookup table for better worst-case performance.
+///
+/// Can calculate up to 34! using native unsigned 128 bit integers.
+/// If the result overflows, an error message will be displayed.
+fn factorial (n: usize, table: &mut Vec) -> Option {
+ match table.get(n) {
+ Some(x) => {
+ // Vec.get returns a Option with a reference to the value, so deref
+ // Wrap in Some() for proper return type
+ Some(*x)
+ },
+ None => {
+ // If a previous base overflowed, just
+ // pass on the overflow. The overflow will
+ // be caught later. Using the max value of u128
+ // for convenience.
+ let prev = factorial(n - 1, table)
+ .unwrap_or(u128::MAX);
+
+ // Do an overflow-checked multiply
+ let attempt = (n as u128).checked_mul(prev);
+
+ // If there isn't an overflow, add the result
+ // to the calculation table
+ if let Some(current) = attempt {
+ table.insert(n, current);
+ }
+
+ attempt // Some(x) if no overflow
+ }
+ }
+}
+
+fn main() {
+ // The lookup table for previously calculated values
+ let mut table: Vec = vec![1, 1, 2];
+
+ println!("Factorial calculator.");
+ println!("Any non-number will exit.");
+
+ loop {
+ println!("\nWhich factorial to calculate?");
+
+ let mut index = String::new();
+
+ io::stdin().read_line(&mut index)
+ .expect("Failed to read line");
+
+ let index = match index.trim().parse() {
+ Ok(num) => num,
+ Err(_) => break, // Exit on non-number
+ };
+
+ println!("Calculating factorial of: {}", index);
+
+ match factorial(index, &mut table) {
+ Some(calculated) => {
+ println!("{}! is {}", index, calculated.separated_string())
+ },
+ None => {
+ println!("Calculation overflow. The factorial base was too large.");
+ }
+ }
+ }
+}