This commit is contained in:
jacekpoz 2024-03-22 11:43:47 +01:00
parent ab5bee5594
commit 89a4d917e2
Signed by: poz
SSH key fingerprint: SHA256:JyLeVWE4bF3tDnFeUpUaJsPsNlJyBldDGV/dIKSLyN8
4 changed files with 198 additions and 0 deletions

7
zad3/Cargo.lock generated Normal file
View file

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "zad3"
version = "0.1.0"

4
zad3/Cargo.toml Normal file
View file

@ -0,0 +1,4 @@
[package]
name = "zad3"
version = "0.1.0"
edition = "2021"

37
zad3/src/main.rs Normal file
View file

@ -0,0 +1,37 @@
mod module;
use std::{env, process::exit};
use crate::module::{Module, ModuleIter, ModuleRec};
fn main() {
let args = env::args().collect::<Vec<_>>();
if args.len() != 2 {
eprintln!("usage: {} <impl>" /*<a> <b> <c>"*/, args[0]);
exit(1);
}
let r#impl = &args[1];
// let a = args[2].parse::<i64>().expect("failed to parse a");
// let b = args[3].parse::<i64>().expect("failed to parse b");
// let c = args[4].parse::<i64>().expect("failed to parse c");
let module: Box<dyn Module> =
if r#impl == "iter" {
Box::new(ModuleIter {})
} else if r#impl == "rec" {
Box::new(ModuleRec {})
} else {
eprintln!("unknown module type");
exit(1);
};
println!("gcd(a, b): {}", module.gcd(10, 5));
println!("factorial(a): {}", module.factorial(5));
let r = module.diophantine(1027, 712, 1);
if r.is_none() {
println!("dupa");
} else {
println!("diophantine(a, b, c): {}, {}", r.unwrap().0, r.unwrap().1);
}
}

150
zad3/src/module.rs Normal file
View file

@ -0,0 +1,150 @@
pub trait Module {
fn factorial(&self, n: u64) -> u64;
fn gcd(&self, a: u64, b: u64) -> u64;
fn diophantine(&self, a: i64, b: i64, c: i64) -> Option<(i64, i64)>;
}
pub struct ModuleIter {}
impl ModuleIter {
fn extended_gcd(&self, a: i64, b: i64, x: &mut i64, y: &mut i64) -> i64 {
*x = 1;
*y = 0;
let mut x1 = 0i64;
let mut y1 = 1i64;
let mut q: i64;
let mut temp_x: i64;
let mut temp_y: i64;
let mut temp_b: i64;
let mut _a = a;
let mut _b = b;
while _b != 0 {
q = _a / _b;
temp_x = *x - q * x1;
temp_y = *y - q * y1;
*x = x1;
*y = y1;
x1 = temp_x;
y1 = temp_y;
temp_b = _a - q * _b;
_a = _b;
_b = temp_b;
}
_a
}
}
impl Module for ModuleIter {
fn factorial(&self, n: u64) -> u64 {
let mut result = 1u64;
for i in 1..=n {
result *= i;
}
result
}
fn gcd(&self, a: u64, b: u64) -> u64 {
if a == 0 {
return b;
}
let mut _a = a;
let mut _b = b;
let mut r: u64;
while _b > 0 {
r = _a % _b;
_a = _b;
_b = r;
}
_a
}
fn diophantine(&self, a: i64, b: i64, c: i64) -> Option<(i64, i64)> {
if a == 0 && b == 0 {
return None;
}
let mut x0 = 0i64;
let mut y0 = 0i64;
let g = self.extended_gcd(a.abs(), b.abs(), &mut x0, &mut y0);
if c % g != 0 {
return None;
}
x0 *= c / g;
y0 *= c / g;
if a < 0 { x0 = -x0; }
if b < 0 { y0 = -y0; }
Some((x0, y0))
}
}
pub struct ModuleRec {}
impl ModuleRec {
fn extended_gcd(&self, a: i64, b: i64, x: &mut i64, y: &mut i64) -> i64 {
if b == 0 {
*x = 1;
*y = 0;
return a;
}
let mut x1 = 0i64;
let mut y1 = 0i64;
let d = self.extended_gcd(b, a % b, &mut x1, &mut y1);
*x = y1;
*y = x1 - y1 * (a / b);
d
}
}
impl Module for ModuleRec {
fn factorial(&self, n: u64) -> u64 {
if n == 0 || n == 1 {
return 1;
}
n * self.factorial(n - 1)
}
fn gcd(&self, a: u64, b: u64) -> u64 {
if b == 0 {
return a;
}
self.gcd(b, a % b)
}
fn diophantine(&self, a: i64, b: i64, c: i64) -> Option<(i64, i64)> {
if a == 0 && b == 0 {
return None;
}
let mut x0 = 0i64;
let mut y0 = 0i64;
let g = self.extended_gcd(a.abs(), b.abs(), &mut x0, &mut y0);
if c % g != 0 {
return None;
}
x0 *= c / g;
y0 *= c / g;
if a < 0 { x0 = -x0; }
if b < 0 { y0 = -y0; }
Some((x0, y0))
}
}