Je pensais que la réécriture "puzzles mathématiques qui entraînent davantage le cerveau du programmeur" avec Rust pourrait être juste pour éviter le flou.
Ruby
Je pense que pre2_1.rb à la p.018 du livre ne donne pas la bonne réponse. Par définition, le code de la séquence est
r.upto(n) do |i|
Ce n'est pas ... Donc, le code qui donne la bonne réponse.
ex2.rb
require "test/unit"
def nPr(n, r)
result = 1
(n-r+1).upto(n) do |i|
result *= i
end
result
end
def nCr(n,r)
result = 1
1.upto(r) do |i|
result = result * (n - i + 1) / i
end
result
end
class NPrTest < Test::Unit::TestCase
def test_nPr
assert_equal 1, nPr(1,1), "1P1 should return 1."
assert_equal 720, nPr(6,6), "6P6 should return 720."
assert_equal 20, nPr(5,2), "5P2 should return 20."
end
def test_nCr
assert_equal 1, nCr(1,1), "1C1 should return 1."
assert_equal 1, nCr(6,6), "6C6 should return 1."
assert_equal 10, nCr(5,2), "5C2 should return 10."
end
end
Rust
main.rs
fn main() {
println!("{n}P{r} = {x}", n = 5, r = 2, x = permutation(5, 2));
println!("{n}C{r} = {x}", n = 5, r = 2, x = combination(5, 2));
}
pub fn permutation(n: i64, r: i64) -> i64 {
let mut result = 1;
for i in (n - r + 1)..=n {
result *= i;
}
return result;
}
pub fn combination(n: i64, r: i64) -> i64 {
let mut result = 1;
for i in 1..=r {
result = result * (n - i + 1) / i;
}
return result;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_permutation() {
assert_eq!(permutation(1, 1), 1);
assert_eq!(permutation(6, 6), 720);
assert_eq!(permutation(5, 2), 20);
}
#[test]
fn test_combination() {
assert_eq!(combination(1, 1), 1);
assert_eq!(combination(6, 6), 1);
assert_eq!(combination(5, 2), 10);
}
}
Greffe solide. au fait,
result = result * (n - i + 1) / i;
Et écris
result *= (n - i + 1) / i;
Est-ce différent d'écrire? Je suis content d'avoir continué en écrivant le test.
Je me demande, "Pourquoi ne pas utiliser mut
tout le temps?", Mais tant qu'il est fermé dans une fonction, je ne pense pas que ce soit trop de bruit.
J'ai un exemple de code concis. Expérimenté comme «permutation2 ()» et «combinaison2 ()».
main.rs
fn main() {
println!("{n}P{r} = {x}", n = 5, r = 2, x = permutation(5, 2));
println!("{n}C{r} = {x}", n = 5, r = 2, x = combination(5, 2));
}
pub fn permutation(n: i64, r: i64) -> i64 {
let mut result = 1;
for i in (n - r + 1)..=n {
result *= i;
}
return result;
}
pub fn combination(n: i64, r: i64) -> i64 {
let mut result = 1;
for i in 1..=r {
result = result * (n - i + 1) / i;
}
return result;
}
pub fn permutation2(n: i64, r: i64) -> i64 {
(n - r + 1..=n).product()
}
pub fn combination2(n: i64, r: i64) -> i64 {
(1..=r).fold(1, |p, i| p * (n - i + 1) / i)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_permutation() {
assert_eq!(permutation(1, 1), 1);
assert_eq!(permutation(6, 6), 720);
assert_eq!(permutation(5, 2), 20);
assert_eq!(permutation(1,1), permutation2(1,1));
assert_eq!(permutation(6,6), permutation2(6,6));
assert_eq!(permutation(5,2), permutation2(5,2));
}
#[test]
fn test_combination() {
assert_eq!(combination(1, 1), 1);
assert_eq!(combination(6, 6), 1);
assert_eq!(combination(5, 2), 10);
assert_eq!(combination(1, 1), combination2(1,1));
assert_eq!(combination(6, 6), combination2(6,6));
assert_eq!(combination(5, 2), combination2(5,2));
}
}
Certainement le même résultat. Le code est également facile à comprendre.