Решение на Дигитален корен от Димитър Иринков
Към профила на Димитър Иринков
Резултати
- 20 точки от тестове
- 1 бонус точка
- 21 точки общо
- 6 успешни тест(а)
- 0 неуспешни тест(а)
Код
/// Десетична бройна система: 0-9
pub fn decimal(input: &str) -> Option<u32> {
let input = format_str(input)?;
digital_root(input, 10)
}
/// Шестнадесетична бройна система: 0-9, последвано от a-f
pub fn hex(input: &str) -> Option<u32> {
let input = format_str(input)?;
digital_root(input, 16)
}
/// Осмична бройна система: 0-7
pub fn octal(input: &str) -> Option<u32> {
let input = format_str(input)?;
digital_root(input, 8)
}
/// Двоична бройна система: 0-1
pub fn binary(input: &str) -> Option<u32> {
let input = format_str(input)?;
digital_root(input, 2)
}
fn digital_root(input: &str, radix: u32) -> Option<u32> {
let sum = sum_digits(input, radix)?;
if sum < radix {
Some(sum)
} else {
digital_root(&number_to_string(sum, radix), radix)
}
}
fn number_to_string(number: u32, radix: u32) -> String {
match radix {
2 => format!("{:b}", number),
8 => format!("{:o}", number),
10 => format!("{}", number),
16 => format!("{:x}", number),
_ => unimplemented!(),
}
}
fn sum_digits(number: &str, radix: u32) -> Option<u32> {
let mut sum = 0;
for c in number.chars() {
let digit = c.to_digit(radix)?;
sum += digit;
}
Some(sum)
}
fn format_str(input: &str) -> Option<&str> {
let mut input = input.trim();
if input.starts_with('+') {
input = &input[1..];
}
if input.is_empty() {
None
} else {
Some(input)
}
}
Лог от изпълнението
Compiling solution v0.1.0 (/tmp/d20200111-2173579-1quoqa7/solution) Finished test [unoptimized + debuginfo] target(s) in 1.92s Running target/debug/deps/solution-a73e64ec87929bd0 running 0 tests test result: ok. 0 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
История (2 версии и 1 коментар)
Димитър качи решение на 01.11.2019 13:32 (преди почти 6 години)
/// Десетична бройна система: 0-9
pub fn decimal(input: &str) -> Option<u32> {
let input = format_str(input)?;
digital_root(input, 10)
}
/// Шестнадесетична бройна система: 0-9, последвано от a-f
pub fn hex(input: &str) -> Option<u32> {
let input = format_str(input)?;
digital_root(input, 16)
}
/// Осмична бройна система: 0-7
pub fn octal(input: &str) -> Option<u32> {
let input = format_str(input)?;
digital_root(input, 8)
}
/// Двоична бройна система: 0-1
pub fn binary(input: &str) -> Option<u32> {
let input = format_str(input)?;
digital_root(input, 2)
}
fn digital_root(input: &str, radix: u32) -> Option<u32> {
-
let sum = sum_digits(input, radix)?;
- let sum = number_to_string(sum, radix);
-
- if sum.len() == 1 {
- sum.chars().next().unwrap().to_digit(radix)
+ if sum < radix {
+ Some(sum)
} else {
- digital_root(&sum, radix)
+ digital_root(&number_to_string(sum, radix), radix)
}
}
fn number_to_string(number: u32, radix: u32) -> String {
match radix {
2 => format!("{:b}", number),
8 => format!("{:o}", number),
10 => format!("{}", number),
16 => format!("{:x}", number),
_ => unimplemented!(),
}
}
fn sum_digits(number: &str, radix: u32) -> Option<u32> {
let mut sum = 0;
for c in number.chars() {
let digit = c.to_digit(radix)?;
sum += digit;
}
Some(sum)
}
fn format_str(input: &str) -> Option<&str> {
let mut input = input.trim();
if input.starts_with('+') {
input = &input[1..];
}
if input.is_empty() {
None
} else {
Some(input)
}
}
Добра работа -- добра употреба на ?
оператора за предаване на грешки нататък, смислена проверка за sum < radix
(аз май проверявах броя на символите във форматирания низ, твоето е по-просто).
Давам ти и 1 бонус точка като първи предал с чисто решение.