↑Programmieren in Rust
// Klassischer euklidischer Algorithmus, rekursiv
fn gcd(a: u32, b: u32) -> u32 {
if b == 0 {a}
else if a == 0 {b}
else if b < a {gcd(a - b, b)}
else {gcd(a, b - a)}
}
// Klassischer euklidischer Algorithmus, iterativ
fn gcd(mut a: u32, mut b: u32) -> u32 {
if a == 0 {b}
else {
while b != 0 {
if b < a {a = a - b;} else {b = b - a;}
}
a
}
}
// Moderner euklidischer Algorithmus, rekursiv
fn gcd(a: u32, b: u32) -> u32 {
if b == 0 {a} else {gcd(b, a%b)}
}
// Moderner euklidischer Algorithmus, iterativ
// ("Turbo-Euklid")
fn gcd(mut a: u32, mut b: u32) -> u32 {
while b != 0 {
let h = a%b;
a = b; b = h;
}
a
}
fn lcm(a: u32, b: u32) -> u32 {
a*b/gcd(a, b)
}
fn lcm_slice(a: &[u32]) -> u32 {
a.iter().fold(1, |a, &b| {a*b/gcd(a, b)})
}
fn pow_mod(mut x: u32, mut n: u32, m: u32) -> u32 {
let mut y: u32 = 1;
while n > 1 {
if n%2 == 1 {y = (y*x)%m;}
n /= 2; x = (x*x)%m;
}
if n == 1 {y = (y*x)%m;}
y
}
fn pow_mod(mut x: u32, mut n: u32, m: u32) -> Option<u32> {
let mut y: u32 = 1;
while n > 1 {
if n%2 == 1 {y = y.checked_mul(x)?%m;}
n /= 2; x = x.checked_mul(x)?%m;
}
if n == 1 {y = y.checked_mul(x)?%m;}
Some(y)
}
fn is_prime(n: u64) -> bool {
(1..n+1).filter(|i| n%i == 0).count() == 2
}
fn is_prime(n: u64) -> bool {
for i in 2..n {
if n%i == 0 {return false;}
}
true
}
fn is_prime(n: u64) -> bool {
let mut i: u64 = 2;
while i*i <= n {
if n%i == 0 {return false;}
i += 1;
}
true
}
fn is_prime_trial_div(n: u32) -> bool {
if n < 4 {return n > 1;}
if n%2 == 0 || n%3 == 0 {return false;}
let mut i = 5;
let mut w = 2;
while i*i <= n {
if n%i == 0 {return false;}
i += w;
w = 6 - w;
}
true
}
fn pow_mod(a: u32, mut n: u32, m: u32) -> u64 {
let mut p: u64 = 1;
let mut a: u64 = u64::from(a%m);
while n > 1 {
if n&1 == 1 {p = (p*a)%u64::from(m);}
n >>= 1; a = (a*a)%u64::from(m);
}
if n == 1 {p = (p*a)%u64::from(m);}
p
}
fn witness(a: u32, d: u32, n: u32, mut r: u32) -> bool {
let mut p = pow_mod(a, d, n);
if p == 1 {
true
} else {
while r != 0 {
if p == u64::from(n-1) {return true;}
p = (p*p)%u64::from(n);
r -= 1;
}
false
}
}
pub fn is_prime(n: u32) -> bool {
if n < 13000000 {
return is_prime_trial_div(n);
} else if n&1 == 0 {
return false;
}
// let (2^r)*d = n - 1;
let mut r = 0;
let mut d = n - 1;
while d&1 == 0 {r += 1; d >>= 1;}
// Miller-Rabin-Test
[2, 7, 61].iter().all(|&a| witness(a, d, n, r))
}
fn factor(mut n: u64) -> Vec<(u64, u8)> {
let mut acc: Vec<(u64, u8)> = vec![];
let mut p = 2;
while p <= n {
let mut k = 0;
while n%p == 0 {n = n/p; k += 1;}
if k != 0 {acc.push((p, k));}
p += 1;
}
acc
}
// Teilerliste
fn divisors(n: u64) -> Vec<u64> {
(1..n+1).filter(|i| n%i == 0).collect()
}
// Teileranzahlfunktion
fn sigma0(n: u64) -> usize {
(1..n+1).filter(|i| n%i == 0).count()
}
// Teilerfunktion
fn sigma(x: u32, n: u64) -> u64 {
(1..n+1).filter(|i| n%i == 0).map(|i| i.pow(x)).sum()
}
fn phi(mut n: u32) -> u32 {
if n == 0 {return 0;}
let mut y: u32 = 1;
let mut p = 2;
while p <= n {
let mut k = 0;
while n%p == 0 {n = n/p; k += 1;}
if k != 0 {y *= p.pow(k-1)*(p-1);}
p += 1;
}
y
}