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

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

Към профила на Христина Христова

Резултати

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

Код

///is the vector of digits a number in the wanted number sistem?
fn isnum(char_vec :& Vec<char>,radix: u32) -> bool
{
for c in char_vec {
let boolval=c.is_digit(radix);
if !boolval { return boolval;}
}
true
}

Няма нужда от стойността boolval. Този код може доста по-просто да се напише така:

for c in char_vec {
    if !c.is_digit(radix) {
        return false;
    }
}

Съхраняването на стойността в променлива не подобрява четимостта, понеже самата променлива няма интересна стойност, която използваме за нещо или която съхраняваме. Дори и в if-клаузата не си заслужава да върнем boolval -- ако сме влезли в if-клаузата, то със сигурност boolval ще е false, така че return false по-ясно указва какво искаме да изразим с този код.

///provide us with a vector of 'digits'
fn cvec_to_uvec(char_vec :& Vec<char>,radix: u32) -> Vec<u32>{
let mut u_vec: Vec<u32> = Vec::new();
for c in char_vec {
let somed=c.to_digit(radix);
if let Some(x)=somed{u_vec.push(x);};
}
u_vec
}

Този коментар би могъл да се преведе до по-ясно име на функцията: digit_vector или даже просто digits, понеже сигнатурата на функцията си връща Vec<u32>. Името "char vector to u32 vector" вече е изразено в типовете на функцията -- приема Vec<char>, връща Vec<u32>. Няма нужда функцията да го повтаря. Това, че връща цифри е нова и интересна информация за това как превежда тези char-ове до u32-та.

///the decimal sum of the digits
fn to_dec(u_vec :&Vec<u32>)->u32{
let mut num=0;
for c in u_vec {
num=num+c;
}
num
}

Пак -- to_dec не е съвсем очевидно какво прави. Конвертира вектора от числа в едно число, но как? Като цифри? Не, като "decimal sum of the digits", така че може би имаше повече смисъл да се нарече digit_sum или sum_of_digits или sum_digits (като глагол). Защо не "dec" в името? Реално тази функция не ти дава десетична сума, тя просто сумира входните числа, така че dec може би дори е малко подвеждащо име.

///the dec sum in its number sistem
fn to_radix(num :u32,radix: u32)->Vec<u32>{
let mut n=num;
let mut rem;
let mut u_vec: Vec<u32> = Vec::new();
while n>0 {
rem=n%radix;
u_vec.push(rem);
n=n/radix;
}
u_vec.reverse();
u_vec
}

Коментара е подвеждащ -- входа "сума" ли е? Може би в контекста където е извикана функцията, но не в контекста на самата функция. Тя просто приема число и връща цифрите му в дадената бройна система -- няма нужда да мислим за "сума" като четем тази функция.

///finds digital root in number sistem radix
fn calc(input: &str,radix: u32) -> Option<u32>{
let char_vec = input.chars().collect();
let b =isnum(&char_vec,radix);
if b
{
let mut u_vec : Vec<u32> = cvec_to_uvec(&char_vec,radix);
let mut num=to_dec(&u_vec);
while num>=radix{
u_vec.clear();
u_vec=to_radix(num,radix);
num=to_dec(&u_vec);
}
return Some(num)
}
None
}
pub fn decimal(input: &str) -> Option<u32> {
let res=calc(&input,10);
res
}
/// Шестнадесетична бройна система: 0-9, последвано от a-f
pub fn hex(input: &str) -> Option<u32> {
let res=calc(&input,16);
res
}
/// Осмична бройна система: 0-7
pub fn octal(input: &str) -> Option<u32> {
let res=calc(&input,8);
res
}
/// Двоична бройна система: 0-1
pub fn binary(input: &str) -> Option<u32> {
let res=calc(&input,2);
res
}

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

Compiling solution v0.1.0 (/tmp/d20200111-2173579-62dy1w/solution)
    Finished test [unoptimized + debuginfo] target(s) in 2.14s
     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 версия и 6 коментара)

Христина качи първо решение на 04.11.2019 18:57 (преди почти 6 години)

Добро решение, но е добре след като го напишеш и се подсигуриш че работи, да минеш 1-2 пъти през него и да помислиш дали има начини да го направиш по-ясно и дали има излишен код, който можеш да премахнеш. Примерно, имаш немалко ненужни променливи -- понякога е напълно ок да присвоиш някакъв израз на променлива с цел яснота, но в случая не мисля, че това се получава.

Избора на имена на функции и променливи е учудващо труден и включва опит и интуиция -- експериментирай и си задавай въпроси. Разгледай и решения на колеги за вдъхновение.