Решение на Дигитален корен от Иван Велков

Обратно към всички решения

Към профила на Иван Велков

Резултати

  • 20 точки от тестове
  • 1 бонус точка
  • 21 точки общо
  • 6 успешни тест(а)
  • 0 неуспешни тест(а)

Код

use std::u32;
/// Десетична бройна система: 0-9
pub fn decimal(input: &str) -> Option<u32> {
match to_digit(input, 10) {
Some(n) => Some(digital_root(n, 10)),
_ => None
}
}

Оператора ? работи за Option, така че вероятно това можеше да е digital_root(to_digit(input, 10)?, 10). Друг начин да се посъкрати е с map, нещо като to_digit(input, 10).map(|n| digital_root(n, 10)), което може би е малко по-pipeline-ско такова.

/// Шестнадесетична бройна система: 0-9, последвано от a-f
pub fn hex(input: &str) -> Option<u32> {
match to_digit(input, 16) {
Some(n) => Some(digital_root(n, 16)),
_ => None
}
}
/// Осмична бройна система: 0-7
pub fn octal(input: &str) -> Option<u32> {
match to_digit(input, 8) {
Some(n) => Some(digital_root(n, 8)),
_ => None
}
}
/// Двоична бройна система: 0-1
pub fn binary(input: &str) -> Option<u32> {
match to_digit(input, 2) {
Some(n) => Some(digital_root(n, 2)),
_ => None
}
}
/// Calculates the sum of the digits of the given number in the provided radix
fn digital_sum(value: u32, radix: u32) -> u32 {
let mut result = 0;
let mut cur_value = value;
while cur_value > 0 {
result += cur_value % radix;
cur_value /= radix;
}
result
}
/// Function that evaluates the digital root of a value in the given radix
fn digital_root(value: u32, radix: u32) -> u32 {
let mut cur_value = value;
while cur_value >= radix {
cur_value = digital_sum(cur_value, radix);
}
cur_value
}
/// Converts a `char` to a digit in the given radix.
fn to_digit(expr: &str, radix: u32) -> Option<u32> {
match u32::from_str_radix(expr, radix) {
Ok(n) => Some(n),
_ => None
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_zero() {
let x = "0";
assert_eq!(to_digit(x, 2), Some(0));
assert_eq!(to_digit(x, 8), Some(0));
assert_eq!(to_digit(x, 10), Some(0));
assert_eq!(to_digit(x, 16), Some(0));
}
#[test]
fn test_hex() {
let x = "f";
assert_eq!(to_digit(x, 16), Some(15));
}
#[test]
fn test_octal() {
let x = "11";
assert_eq!(to_digit(x, 8), Some(9));
}
#[test]
fn test_octal_invalid_symbol() {
let x = "9";
assert_eq!(to_digit(x, 8), None);
}
#[test]
fn test_hex_double_digit() {
let x = "10";
assert_eq!(to_digit(x, 16), Some(16));
}
#[test]
fn test_invalid_string() {
let x = "kek";
assert_eq!(to_digit(x, 16), None);
}
#[test]
fn test_digital_root() {
assert_eq!(digital_root(345, 10), 3);
assert_eq!(digital_root(0x7b, 16), 0x3);
}
}

Лог от изпълнението

Compiling solution v0.1.0 (/tmp/d20200111-2173579-1fminyz/solution)
    Finished test [unoptimized + debuginfo] target(s) in 4.19s
     Running target/debug/deps/solution-a73e64ec87929bd0

running 7 tests
test tests::test_digital_root ... ok
test tests::test_hex ... ok
test tests::test_hex_double_digit ... ok
test tests::test_invalid_string ... ok
test tests::test_octal ... ok
test tests::test_octal_invalid_symbol ... ok
test tests::test_zero ... ok

test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

     Running target/debug/deps/solution_test-38971695424b36d5

running 6 tests
test solution_test::test_binary ... ok
test solution_test::test_decimal_basic ... ok
test solution_test::test_hex_basic ... ok
test solution_test::test_invalid ... ok
test solution_test::test_octal_basic ... ok
test solution_test::test_zeroes ... ok

test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

   Doc-tests solution

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

История (1 версия и 4 коментара)

Иван качи първо решение на 05.11.2019 14:41 (преди почти 6 години)

Добро решение. Очаквах итерация по символи, но и така става. Добре си се сетил в тестовете да провериш за 0, макар че ми се ще да беше написал още няколко теста за по-големи числа. Получаваш бонус точка за тях все пак.