Решение на Дигитален корен от Петър Петров
Резултати
- 20 точки от тестове
- 0 бонус точки
- 20 точки общо
- 6 успешни тест(а)
- 0 неуспешни тест(а)
Код
Лог от изпълнението
Compiling solution v0.1.0 (/tmp/d20200111-2173579-f2dv56/solution) warning: unused variable: `ParseIntError` --> src/lib.rs:47:21 | 47 | Err(ParseIntError) => return None, | ^^^^^^^^^^^^^ help: consider prefixing with an underscore: `_ParseIntError` | = note: `#[warn(unused_variables)]` on by default warning: unused variable: `ParseIntError` --> src/lib.rs:76:21 | 76 | Err(ParseIntError) => return None, | ^^^^^^^^^^^^^ help: consider prefixing with an underscore: `_ParseIntError` warning: unused variable: `z` --> src/lib.rs:101:13 | 101 | let z = u32::from_str_radix(&binary_num, 2); | ^ help: consider prefixing with an underscore: `_z` warning: variable does not need to be mutable --> src/lib.rs:160:9 | 160 | let mut digits=number_to_digits_vector(n); | ----^^^^^^ | | | help: remove this `mut` | = note: `#[warn(unused_mut)]` on by default warning: variable `ParseIntError` should have a snake case name --> src/lib.rs:47:21 | 47 | Err(ParseIntError) => return None, | ^^^^^^^^^^^^^ help: convert the identifier to snake case: `parse_int_error` | = note: `#[warn(non_snake_case)]` on by default warning: variable `ParseIntError` should have a snake case name --> src/lib.rs:76:21 | 76 | Err(ParseIntError) => return None, | ^^^^^^^^^^^^^ help: convert the identifier to snake case: `parse_int_error` warning: unused variable: `ParseIntError` --> src/lib.rs:47:21 | 47 | Err(ParseIntError) => return None, | ^^^^^^^^^^^^^ help: consider prefixing with an underscore: `_ParseIntError` | = note: `#[warn(unused_variables)]` on by default warning: unused variable: `ParseIntError` --> src/lib.rs:76:21 | 76 | Err(ParseIntError) => return None, | ^^^^^^^^^^^^^ help: consider prefixing with an underscore: `_ParseIntError` warning: unused variable: `z` --> src/lib.rs:101:13 | 101 | let z = u32::from_str_radix(&binary_num, 2); | ^ help: consider prefixing with an underscore: `_z` warning: variable does not need to be mutable --> src/lib.rs:160:9 | 160 | let mut digits=number_to_digits_vector(n); | ----^^^^^^ | | | help: remove this `mut` | = note: `#[warn(unused_mut)]` on by default warning: variable `ParseIntError` should have a snake case name --> src/lib.rs:47:21 | 47 | Err(ParseIntError) => return None, | ^^^^^^^^^^^^^ help: convert the identifier to snake case: `parse_int_error` | = note: `#[warn(non_snake_case)]` on by default warning: variable `ParseIntError` should have a snake case name --> src/lib.rs:76:21 | 76 | Err(ParseIntError) => return None, | ^^^^^^^^^^^^^ help: convert the identifier to snake case: `parse_int_error` Finished test [unoptimized + debuginfo] target(s) in 4.26s 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 версии и 3 коментара)
Петър качи решение на 03.11.2019 18:35 (преди почти 6 години)
pub fn decimal(input:&str) -> Option<u32> {
+
let char_vec: Vec<char> = input.chars().collect();
let mut sum=0;
- let zero_const:&char=&'0';
- if first(&char_vec).unwrap() == zero_const && char_vec.len() > 1{
+ if input.len() == 0{
return None
}
for c in char_vec{
if c >= '0' && c <= '9'{
sum=sum+c.to_digit(10).unwrap();
}
else {
return None
}
Проверката за това дали цифрата е валидна я има вече в самия метод to_digit
-- да направиш проверката ръчно и след това да викнеш .unwrap
е ненужно, защото спокойно можеш да валидираш и да вземеш конвертираната стойност наведнъж. Примерно:
sum += match c.to_digit(10) {
Some(n) => n,
None => return None,
};
Този израз може и да се съкрати доста драстично с ?
оператора, който работи също както при Result
:
sum += match c.to_digit(10)?;
}
loop{
sum=sum_of_digits(sum);
if sum < 10 {
return Some(sum)
}
}
}
+
+
pub fn hex(input:&str) -> Option<u32> {
let mut sum=0;
let char_vec: Vec<char> = input.chars().collect();
+ if input.len() == 0{
+ return None
+ }
for c in char_vec{
if c>='0' && c<='9'|| c>='a' && c<='f'{
sum=sum+c.to_digit(16).unwrap();
}
else{
return None
}
}
loop{
let hex_num=format!("{:x}",sum);
let z = u32::from_str_radix(&hex_num, 16);
if hex_num.len() == 1 {
match z{
Ok(num) => return Some(num),
Err(ParseIntError) => return None,
}
Този match statement може да се съкрати с употребата на метода .ok()
върху Result
. Би станало нещо такова:
if hex_num.len() == 1 {
return u32::from_str_radix(&hex_num, 16).ok();
}
}
sum=sum_of_hex_digits(&hex_num);
}
}
pub fn octal(input:&str) -> Option<u32>{
let mut sum=0;
+ if input.len() == 0{
+ return None
+ }
+
let char_vec: Vec<char> =input.chars().collect();
for c in char_vec{
if c>='0' && c <='7'{
sum=sum+c.to_digit(8).unwrap();
}
else{
return None
}
}
loop{
let octa_num=format!("{:o}",sum);
let z = u32::from_str_radix(&octa_num, 8);
if octa_num.len() == 1 {
match z{
Ok(num) => return Some(num),
Err(ParseIntError) => return None,
}
}
sum=sum_of_octa_digits(&octa_num);
}
}
pub fn binary(input:&str) -> Option<u32> {
let mut sum=0;
+ if input.len() == 0{
+ return None
+ }
+
let char_vec: Vec<char> =input.chars().collect();
for c in char_vec{
if c=='0' || c =='1'{
sum=sum+c.to_digit(10).unwrap();
}
else{
return None
}
}
loop{
let binary_num=format!("{:b}",sum);
let z = u32::from_str_radix(&binary_num, 2);
if binary_num.len() == 1 {
if binary_num == "0"{
return Some(0)
}
else if binary_num == "1"{
return Some(1)
}
else{
return None
}
}
sum=sum_of_binary_digits(&binary_num);
}
}
pub fn sum_of_hex_digits(input:&str) -> u32 {
let char_vec: Vec<char> = input.chars().collect();
let mut sum=0;
for c in char_vec{
if c>='0' && c<='9'|| c>='a' && c<='f'{
sum=sum+c.to_digit(16).unwrap();
}
}
sum
}
pub fn sum_of_octa_digits(input:&str) -> u32 {
let char_vec: Vec<char> = input.chars().collect();
let mut sum=0;
for c in char_vec{
if c>='0' && c<='7'{
sum=sum+c.to_digit(8).unwrap();
}
}
sum
}
pub fn sum_of_binary_digits(input:&str) -> u32 {
let char_vec: Vec<char> = input.chars().collect();
let mut sum=0;
for c in char_vec{
if c=='0' || c=='1'{
sum=sum+c.to_digit(10).unwrap();
}
}
sum
}
pub fn number_to_digits_vector(n: u32) -> Vec<u32> {
let mut digits = Vec::new();
let mut n = n;
while n > 9 {
digits.push(n % 10);
n = n / 10;
}
digits.push(n);
// digits.reverse();
digits
}
pub fn sum_of_digits(n:u32) -> u32 {
let mut digits=number_to_digits_vector(n);
let mut sum=0;
for num in digits{
sum=sum+num;
}
sum
}
pub fn first<T>(v: &Vec<T>) -> Option<&T> {
v.first()
}
Можеше да споделиш още код в помощни функции, параметризирани по различаващите се неща -- не е задължително, но функциите са доста подобни и би съкратило кода. Може да разгледаш моето решение за един такъв пример: https://fmi.rust-lang.bg/tasks/1/solutions/1
Проверката за това дали цифрата е валидна я има вече в самия метод
to_digit
-- да направиш проверката ръчно и след това да викнеш.unwrap
е ненужно, защото спокойно можеш да валидираш и да вземеш конвертираната стойност наведнъж. Примерно:Този израз може и да се съкрати доста драстично с
?
оператора, който работи също както приResult
:Този match statement може да се съкрати с употребата на метода
.ok()
върхуResult
. Би станало нещо такова: