Skip to content

Instantly share code, notes, and snippets.

@mhgp
Last active November 23, 2016 09:46
Show Gist options
  • Save mhgp/5416250ac3ed024a6c72965b34a4846c to your computer and use it in GitHub Desktop.
Save mhgp/5416250ac3ed024a6c72965b34a4846c to your computer and use it in GitHub Desktop.
Rust で解く 1 から max までのすべての自然数の最小公倍数 ref: http://qiita.com/mhgp/items/711a7bb8e00bff607660
///a と b の最大公約数を求める
fn gcd(a: usize, b: usize) -> usize {
if a % b == 0 {
b
} else {
gcd(b, a % b)
}
}
///ループ処理
fn solve(max: usize) -> usize {
(2..max + 1).fold(1, |lcm, n| {
(n * lcm) / gcd(n, lcm)
})
}
///1 から max までのすべての自然数の最小公倍数を求める
pub fn get_lcm(max: usize) -> usize {
assert!(max > 2);
solve(max)
}
mod stack {
///a と b の最大公約数を求める
fn gcd(a: usize, b: usize) -> usize {
if a % b == 0 {
b
} else {
gcd(b, a % b)
}
}
///ループ処理
fn solve(n: usize, lcm: usize, max: usize) -> usize {
if n <= max {
solve(n + 1, (n * lcm) / gcd(n, lcm), max)
} else {
lcm
}
}
///1 から max までのすべての自然数の最小公倍数を求める
pub fn get_lcm(max: usize) -> usize {
assert!(max > 2);
solve(2, 1, max)
}
}
mod fold {
///a と b の最大公約数を求める
fn gcd(a: usize, b: usize) -> usize {
if a % b == 0 {
b
} else {
gcd(b, a % b)
}
}
///ループ処理
fn solve(max: usize) -> usize {
(2..max + 1).fold(1, |lcm, n| {
(n * lcm) / gcd(n, lcm)
})
}
///1 から max までのすべての自然数の最小公倍数を求める
pub fn get_lcm(max: usize) -> usize {
assert!(max > 2);
solve(max)
}
}
mod procedural {
///a と b の最大公約数を求める
fn gcd(a: usize, b: usize) -> usize {
let (mut a, mut b) = if a < b {
(b, a)
} else {
(a, b)
};
while b > 0 {
let r = a % b;
a = b;
b = r;
}
a
}
///ループ処理
fn solve(max: usize) -> usize {
let mut lcm = 1;
for n in 2..max + 1 {
lcm = (n * lcm) / gcd(n, lcm);
}
lcm
}
///1 から max までのすべての自然数の最小公倍数を求める
pub fn get_lcm(max: usize) -> usize {
assert!(max > 2);
solve(max)
}
}
mod mix {
///a と b の最大公約数を求める
fn gcd(a: usize, b: usize) -> usize {
let (mut a, mut b) = if a < b {
(b, a)
} else {
(a, b)
};
while b > 0 {
let r = a % b;
a = b;
b = r;
}
a
}
///ループ処理
fn solve(max: usize) -> usize {
(2..max + 1).fold(1, |lcm, n| {
(n * lcm) / gcd(n, lcm)
})
}
///1 から max までのすべての自然数の最小公倍数を求める
pub fn get_lcm(max: usize) -> usize {
assert!(max > 2);
solve(max)
}
}
fn main() {
assert_eq!(stack::get_lcm(10) , 2520);
assert_eq!(stack::get_lcm(20) , 232792560);
assert_eq!(stack::get_lcm(11) , 27720);
assert_eq!(fold::get_lcm(10) , 2520);
assert_eq!(fold::get_lcm(20) , 232792560);
assert_eq!(fold::get_lcm(11) , 27720);
assert_eq!(procedural::get_lcm(10) , 2520);
assert_eq!(procedural::get_lcm(20) , 232792560);
assert_eq!(procedural::get_lcm(11) , 27720);
assert_eq!(mix::get_lcm(10) , 2520);
assert_eq!(mix::get_lcm(20) , 232792560);
assert_eq!(mix::get_lcm(11) , 27720);
println!("All Ok!");
}
///a と b の最大公約数を求める
fn gcd(a: usize, b: usize) -> usize {
let (mut a, mut b) = if a < b {
(b, a)
} else {
(a, b)
};
while b > 0 {
let r = a % b;
a = b;
b = r;
}
a
}
///ループ処理
fn solve(max: usize) -> usize {
(2..max + 1).fold(1, |lcm, n| {
(n * lcm) / gcd(n, lcm)
})
}
///1 から max までのすべての自然数の最小公倍数を求める
pub fn get_lcm(max: usize) -> usize {
assert!(max > 2);
solve(max)
}
///a と b の最大公約数を求める
fn gcd(a: usize, b: usize) -> usize {
let (mut a, mut b) = if a < b {
(b, a)
} else {
(a, b)
};
while b > 0 {
let r = a % b;
a = b;
b = r;
}
a
}
///ループ処理
fn solve(max: usize) -> usize {
let mut lcm = 1;
for n in 2..max + 1 {
lcm = (n * lcm) / gcd(n, lcm);
}
lcm
}
///1 から max までのすべての自然数の最小公倍数を求める
pub fn get_lcm(max: usize) -> usize {
assert!(max > 2);
solve(max)
}
///a と b の最大公約数を求める
fn gcd(a: usize, b: usize) -> usize {
if a % b == 0 {
b
} else {
gcd(b, a % b)
}
}
///ループ処理
fn solve(n: usize, lcm: usize, max: usize) -> usize {
if n <= max {
solve(n + 1, (n * lcm) / gcd(n, lcm), max)
} else {
lcm
}
}
///1 から max までのすべての自然数の最小公倍数を求める
pub fn get_lcm(max: usize) -> usize {
assert!(max > 2);
solve(2, 1, max)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment