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

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

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

Резултати

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

Код

pub fn decimal(input:&str) -> Option<u32> {
let char_vec: Vec<char> = input.chars().collect();
let mut sum=0;
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,
}
}
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()
}

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

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 коментара)

Петър качи първо решение на 02.11.2019 15:02 (преди почти 6 години)

Петър качи решение на 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,
}
}
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