Created
January 21, 2019 19:01
-
-
Save kevinmartinjos/c8ca7949e06c85a04076ac7183f27cf9 to your computer and use it in GitHub Desktop.
PIM book polynomials - 1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate rand; | |
use std::io; | |
use rand::Rng; | |
fn main() { | |
let mut secret_passcode_str = String::new(); | |
println!("What's the secret passcode?"); | |
io::stdin().read_line(&mut secret_passcode_str).expect("Failed to read line"); | |
let secret_passcode = secret_passcode_str.trim().parse::<i32>().expect("Wanted a number"); | |
println!("This is the secret: {}", secret_passcode); | |
println!("How many parts?"); | |
let mut parts_str = String::new(); | |
io::stdin().read_line(&mut parts_str).expect("Failed to read line"); | |
let required_parts: i32 = parts_str.trim().parse().expect("not a number"); | |
let required_degree = required_parts - 1; | |
let coeffs: Vec<i32> = create_polynomical_of_degree(required_degree, secret_passcode); | |
let parts: Vec<(i32, i32)> = create_parts(coeffs, required_parts); | |
print_parts(&parts); | |
println!("Time to put things to test. Please enter your secret codes"); | |
let input_parts: Vec<i32> = ask_everyone_their_secret_codes(required_parts); | |
let secret_code: i32 = decipher_secret_code(input_parts); | |
println!("The deciphered secret code is: {}", secret_code); | |
} | |
fn decipher_secret_code(input_parts: Vec<i32>) -> i32 { | |
let mut polynomial_value: i32 = 0; | |
let n = input_parts.len(); | |
for (i, yi) in input_parts.iter().enumerate() { | |
let xi = i as i32 + 1; | |
let mut product = 1.0; | |
for j in 1..n+1 { | |
let xj = j as i32; | |
if xj == xi { | |
continue; | |
} | |
product *= (-1 * xj) as f64/(xi - xj) as f64; | |
} | |
let term = yi * product as i32; | |
polynomial_value += term; | |
} | |
return polynomial_value; | |
} | |
fn ask_everyone_their_secret_codes(required_parts: i32) -> Vec<i32> { | |
let mut parts: Vec<i32> = Vec::new(); | |
for _i in 0..required_parts { | |
let mut input_str = String::new(); | |
io::stdin().read_line(&mut input_str).expect("Failed to read line"); | |
let secret_code_part: i32 = input_str.trim().parse().expect("not a number"); | |
parts.push(secret_code_part); | |
} | |
return parts; | |
} | |
fn print_parts(parts: &Vec<(i32, i32)>) { | |
println!("The parts are:"); | |
for (i, code_part) in parts.iter() { | |
println!("({}, {})", i, code_part); | |
} | |
} | |
fn create_parts(coeffs: Vec<i32>, required_parts: i32) -> Vec<(i32, i32)> { | |
let mut parts: Vec<(i32, i32)> = Vec::new(); | |
for _i in 1..required_parts+1 { | |
let value = value_of_polynomial_at(&coeffs, _i); | |
parts.push((_i, value)); | |
} | |
return parts; | |
} | |
fn value_of_polynomial_at(coeffs: &Vec<i32>, value: i32) -> i32 { | |
let mut sum: i32 = 0; | |
for(i, coeff) in coeffs.iter().enumerate() { | |
sum += coeff * i32::pow(value, i as u32); | |
} | |
return sum; | |
} | |
fn create_polynomical_of_degree(required_degree: i32, secret_passcode: i32) -> Vec<i32> { | |
let mut coeffs : Vec<i32> = Vec::new(); | |
let zero_coeff: i32 = secret_passcode; | |
coeffs.push(zero_coeff); | |
for _i in 1..required_degree+1 { | |
let coeff = rand::thread_rng().gen_range(0, 100); | |
coeffs.push(coeff) | |
} | |
return coeffs; | |
} | |
fn print_polynomial(coeffs: &Vec<i32>) { | |
for (i, coeff) in coeffs.iter().enumerate() { | |
print!("{}x^{} + ", coeff, i); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment