Skip to content

Instantly share code, notes, and snippets.

@AnthonyMikh
Last active February 28, 2018 11:12
Show Gist options
  • Save AnthonyMikh/112bde32bd7b4f9962108e69cc10065b to your computer and use it in GitHub Desktop.
Save AnthonyMikh/112bde32bd7b4f9962108e69cc10065b to your computer and use it in GitHub Desktop.
Решение задачи №74 от UniLecs
//Тип входных данных
type Base = u32;
//Возвращает НОД аргументов.
//Если один аргумент нулевой, возвращает другой
fn gcd(a: Base, b: Base) -> Base {
if a < b { gcd(b, a) }
else if b == 0 { a }
else { gcd(b, a % b) }
}
//Константа, ограничивающая сверху входные данные
#[deny(overflowing_literals)]
const UPPER_BOUND: Base = 1_000_000;
//Тип ошибок при решении задачи
#[derive(Debug, PartialEq)]
enum FractionError {
ZeroDivisor,
OutOfBound,
}
//Возвращает число несократимых дробей вида x/n, где 0 < x < n
fn proper_fractions(n: Base) -> Result<usize, FractionError> {
use FractionError::*;
if n == 0 {
return Err(ZeroDivisor);
}
if n >= UPPER_BOUND {
return Err(OutOfBound);
}
//Считаем количество чисел от 1 до n-1, взаимно простых с n
let res = (1..n)
.map(|x| gcd(x, n))
.filter(|&res| res == 1)
.count();
Ok(res)
}
//Тесты
#[test]
fn do_tests() {
use FractionError::*;
assert_eq!(proper_fractions(11), Ok(10));
assert_eq!(proper_fractions(12), Ok(4));
assert_eq!(proper_fractions(17), Ok(16));
assert_eq!(proper_fractions(999_999), Ok(466560));
assert_eq!(proper_fractions(0), Err(ZeroDivisor));
assert_eq!(proper_fractions(UPPER_BOUND), Err(OutOfBound));
}
@AnthonyMikh
Copy link
Author

@AnthonyMikh
Copy link
Author

Аннотация deny(warn_lint) превращает предупреждение warn_lint в ошибку компиляции. В данном случае ошибкой становится переполнение числового литерала (overflowing_literals). Таким образом, мы всегда можем быть уверены, что UPPER_BOUND хранит корректное значение верхней границы входных данных, т. е. значение верхней границы укладывается в типе входных данных.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment