diff --git a/rust/pset1/credit/Cargo.lock b/rust/pset1/credit/Cargo.lock new file mode 100644 index 0000000..2fb05f2 --- /dev/null +++ b/rust/pset1/credit/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "credit" +version = "0.1.0" diff --git a/rust/pset1/credit/Cargo.toml b/rust/pset1/credit/Cargo.toml new file mode 100644 index 0000000..f626b43 --- /dev/null +++ b/rust/pset1/credit/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "credit" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/rust/pset1/credit/README.md b/rust/pset1/credit/README.md new file mode 120000 index 0000000..bad0678 --- /dev/null +++ b/rust/pset1/credit/README.md @@ -0,0 +1 @@ +../../../pset1/credit/README.md \ No newline at end of file diff --git a/rust/pset1/credit/src/lib.rs b/rust/pset1/credit/src/lib.rs new file mode 100644 index 0000000..5a4cfd1 --- /dev/null +++ b/rust/pset1/credit/src/lib.rs @@ -0,0 +1,17 @@ +use std::io::{self, Write}; + +pub fn get_long(prompt: &str) -> u64 { + loop { + print!("{prompt}"); + io::stdout().flush().unwrap(); + + let mut input_text = String::new(); + match io::stdin().read_line(&mut input_text) { + Ok(_) => match input_text.trim().parse() { + Ok(input_long) => return input_long, + Err(_) => continue, + }, + Err(_) => continue, + } + } +} diff --git a/rust/pset1/credit/src/main.rs b/rust/pset1/credit/src/main.rs new file mode 100644 index 0000000..02ec712 --- /dev/null +++ b/rust/pset1/credit/src/main.rs @@ -0,0 +1,55 @@ +use credit::get_long; + +fn main() { + let cc_number = get_long("Number: "); + let cc_num_digits = cc_number.to_string().len() as u64; + + if luhn(cc_number) { + let leading_digits = cc_number / 10_u64.pow((cc_num_digits - 2) as u32); + if cc_num_digits == 15 { + if leading_digits == 34 || leading_digits == 37 { + println!("AMEX"); + return; + } + } + if cc_num_digits == 16 { + if leading_digits >= 51 && leading_digits <= 55 { + println!("MASTERCARD"); + return; + } + } + if cc_num_digits == 13 || cc_num_digits == 16 { + let leading_digits = cc_number / 10_u64.pow((cc_num_digits - 1) as u32); + if leading_digits == 4 { + println!("VISA"); + return; + } + } + } + println!("INVALID"); +} + +fn luhn(cc_number: u64) -> bool { + let cc_string = cc_number.to_string(); + let mut cumsum_one = 0; + let mut cumsum_two = 0; + + for (i, val) in cc_string + .chars() + .rev() + .enumerate() + .map(|(i, x)| (i, x.to_digit(10).unwrap_or(0))) + { + if i % 2 != 0 { + let mut sum = 2 * val; + if sum >= 10 { + cumsum_one += sum % 10; + sum /= 10; + } + cumsum_one += sum; + } else { + cumsum_two += val; + } + } + (cumsum_one + cumsum_two) % 10 == 0 +}