Решение на Дигитален корен от Парашкев Катерски

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

Към профила на Парашкев Катерски

Резултати

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

Код

fn from_digit(digit: u8, base: u8) -> Option<char> {
let abc = [
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
];
if base > 36 {
None
} else if digit < base {
Some(abc[digit as usize])
} else {
None
}
}
fn converter(num: &str, base_from: u32, base_to: u32) -> Option<String> {
let mut digit_chars: Vec<char> = num.chars().collect();
digit_chars.reverse();
let digit_chars = digit_chars; // so its umutable now
let mut acc = 0;
let mut counter = 0;
let mut new_digits = Vec::<char>::new();
for digit in digit_chars {
let digit = match digit.to_digit(base_from) {
Some(i) => i,
None => {
println!(
"-> converter: {} can't be converted from base {}",
digit, base_from
);
return None;
}
};
acc += digit * base_from.pow(counter);
counter += 1;
}
loop {
let digit = acc % base_to;
acc -= digit;
acc /= base_to;
new_digits.push(match from_digit(digit as u8, base_to as u8) {
Some(i) => i,
None => {
println!(
"-> converter: {} can't be converted to digit in base {}",
digit, base_to
);
return None;
}
});
if acc == 0 {
break;
}
}
new_digits.reverse();
let new_digits: String = new_digits.into_iter().collect();
Some(new_digits)
}
fn sum_digits(digits: Vec<char>, base: u32) -> Option<Vec<char>> {
let mut sum = 0;
for digit in digits {
sum += match digit.to_digit(base) {
Some(i) => i,
None => {
println!(
"-> sum_digits: {} isn't a valid valid digit in base {}",
digit, base
);

Тези print-ове са малко... шумни. Разбираемо е да ги използваш докато си тестваш кода, за да дебъгнеш нещо, но иначе заемат доста място и се викат по средата на функция, която иначе няма други side effects.

За практически цели, обикновено такава функция би върнала такова съобщение като грешка, използвайки Result, но не го бяхме преподали все още :).

return None;
}
};
}
let sum = match converter(&sum.to_string(), 10, base) {
Some(s) => s,
None => return None,
};
Some(sum.chars().collect())
}
fn sum_digits_rec(digits: Vec<char>, base: u32) -> Option<char> {
if digits.len() == 0 {
None
} else if digits.len() == 1 {
Some(digits[0])
} else {
sum_digits_rec(
match sum_digits(digits, base) {
Some(d) => d,
None => return None,
},
base,
)
}
}
pub fn decimal(input: &str) -> Option<u32> {
match sum_digits_rec(input.chars().collect(), 10) {
Some(i) => i.to_digit(10),
None => None,
}
}
pub fn hex(input: &str) -> Option<u32> {
match sum_digits_rec(input.chars().collect(), 16) {
Some(i) => i.to_digit(16),
None => None,
}
}
pub fn octal(input: &str) -> Option<u32> {
match sum_digits_rec(input.chars().collect(), 8) {
Some(i) => i.to_digit(8),
None => None,
}
}
pub fn binary(input: &str) -> Option<u32> {
match sum_digits_rec(input.chars().collect(), 2) {
Some(i) => i.to_digit(2),
None => None,
}
}

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

Compiling solution v0.1.0 (/tmp/d20200111-2173579-5kbzbp/solution)
    Finished test [unoptimized + debuginfo] target(s) in 2.69s
     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

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