Решение на Bigint от Ралица Добрева

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

Към профила на Ралица Добрева

Резултати

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

Код

#[derive(Debug, PartialEq, Eq)]
pub struct Bigint {
sign: i8,
digits: Vec<u8>,
}
impl Bigint {
pub fn new() -> Self {
return Bigint {
sign: 1i8,
digits: Vec::new(),
};
}
fn from_components(digits: Vec<u8>, sign: i8) -> Self {
let mut final_digit = digits;
let mut deleteNumber = 0;
for digit in final_digit.iter() {
if digit == &0u8 {
deleteNumber += 1;
} else {
break;
}
}
for _ in 0..deleteNumber {
final_digit.remove(0);
}
if final_digit.is_empty() {
return Bigint::new();
}
return Bigint {
sign: sign,
digits: final_digit,
};
}
pub fn to_string(&self) -> String {
let mut res = String::new();
for ch in &self.digits {
res.push_str(&ch.to_string());
}
return res;
}
pub fn is_positive(&self) -> bool {
if self.digits.is_empty() {
return false;
}
return self.sign == 1i8;
}
pub fn is_negative(&self) -> bool {
if self.digits.is_empty() {
return false;
}
return self.sign == -1i8;
}
}
use std::str::FromStr;
#[derive(Debug)]
pub struct ParseError;
impl FromStr for Bigint {
type Err = ParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut digits: Vec<u8> = Vec::new();
let mut sign = 1i8;
for (i, c) in s.chars().enumerate() {
if c == '-' && i == 0 {
sign = -1i8;
continue;
} else if c == '+' && i == 0 {
continue;
}
if c.is_numeric() {
digits.push(c.to_string().parse::<u8>().unwrap());
} else {
return Err(ParseError);
}
}
return Ok(Bigint::from_components(digits, sign));
}
}
use std::cmp::Ordering;
impl PartialOrd for Bigint {
fn partial_cmp(&self, other: &Bigint) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Bigint {
fn cmp(&self, other: &Bigint) -> Ordering {
if self.sign != other.sign {
return (self.sign).cmp(&other.sign);
} else if self.to_string() == other.to_string() {
return Ordering::Equal;
}
if self.sign == 1i8 {
if isSmaller(&self.to_string(), &other.to_string()) {
return Ordering::Less;
} else {
return Ordering::Greater;
}
} else if isSmaller(&self.to_string(), &other.to_string()) {
return Ordering::Greater;
} else {
return Ordering::Less;
}
}
}
use std::ops::{Add, Sub};
impl Add for Bigint {
type Output = Bigint;
fn add(self, other: Self) -> Self {
let mut sign = 1i8;
if self.sign == other.sign && self.sign == -1i8 {
sign = -1i8;
} else if self.sign != other.sign {
if self.sign == 1i8 {
let n = Bigint {
sign: 1i8,
digits: other.digits,
};
return self - n;
} else {
return self - other;
}
}
let mut num1 = self.to_string();
let mut num2 = other.to_string();
if num1.len() > num2.len() {
num1 = num2;
num2 = self.to_string();
}
let mut res = String::new();
let mut n1 = num1.len();
let mut n2 = num2.len();
num1 = num1.chars().rev().collect::<String>();
num2 = num2.chars().rev().collect::<String>();
let mut carry = 0;
for i in 0..n1 {
let mut sum = num1.chars().nth(i).unwrap_or('0').to_digit(10).unwrap_or(0)
+ num2.chars().nth(i).unwrap_or('0').to_digit(10).unwrap_or(0)
+ carry;
res.push_str(&(sum % 10).to_string());
carry = sum / 10;
}
for i in n1..n2 {
let mut sum = num2.chars().nth(i).unwrap_or('0').to_digit(10).unwrap_or(0) + carry;
res.push_str(&(sum % 10).to_string());
carry = sum / 10;
}
if carry != 0u32 {
res.push_str(&carry.to_string());
}
res = res.chars().rev().collect::<String>();
let mut sign_string = String::new();
if sign == 1i8 {
sign_string = "+".to_string();
} else {
sign_string = "-".to_string();
}
sign_string.push_str(&res);
res = sign_string;
return Bigint::from_str(&res).unwrap();
}
}
impl Sub for Bigint {
type Output = Bigint;
fn sub(self, other: Self) -> Self {
let mut sign = 1i8;
let mut num1 = self.to_string();
let mut num2 = other.to_string();
if self.sign == other.sign && self.sign == -1i8 {
let n = Bigint {
sign: 1i8,
digits: other.digits,
};
return self + n;
} else if self.sign != other.sign {
if self.sign == 1i8 {
let n = Bigint {
sign: 1i8,
digits: other.digits,
};
return self + n;
} else {
let n = Bigint {
sign: -1i8,
digits: self.digits,
};
return other + n;
}
}
if isSmaller(&num1, &num2) {
sign = -1i8;
num1 = num2;
num2 = self.to_string();
}
let mut res = String::new();
let mut n1 = num1.len();
let mut n2 = num2.len();
num1 = num1.chars().rev().collect::<String>();
num2 = num2.chars().rev().collect::<String>();
let mut carry = 0;
for i in 0..n2 {
let mut sub = num1.chars().nth(i).unwrap_or('0').to_digit(10).unwrap_or(0) as i32
- num2.chars().nth(i).unwrap_or('0').to_digit(10).unwrap_or(0) as i32
- carry as i32;
if sub < 0 {
sub = sub + 10;
carry = 1;
} else {
carry = 0;
}
res.push_str(&sub.to_string());
}
for i in n2..n1 {
let mut sub =
num1.chars().nth(i).unwrap_or('0').to_digit(10).unwrap_or(0) as i32 - carry as i32;
if sub < 0 {
sub = sub + 10;
carry = 1;
} else {
carry = 0;
}
res.push_str(&sub.to_string());
}
res = res.chars().rev().collect::<String>();
let mut sign_string = String::new();
if sign == 1i8 {
sign_string = "+".to_string();
} else {
sign_string = "-".to_string();
}
sign_string.push_str(&res);
res = sign_string;
return Bigint::from_str(&res).unwrap();
}
}
fn isSmaller(num1: &str, num2: &str) -> bool {
let l1 = num1.len();
let l2 = num2.len();
if l1 < l2 {
return true;
}
if l2 < l1 {
return false;
}
return num1 < num2;
}
fn bigint(s: &str) -> Bigint {
Bigint::from_str(s).unwrap()
}
fn main() {}

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

Compiling solution v0.1.0 (/tmp/d20201127-2274206-77iujz/solution)
warning: value assigned to `sign_string` is never read
   --> src/lib.rs:187:13
    |
187 |         let mut sign_string = String::new();
    |             ^^^^^^^^^^^^^^^
    |
    = note: `#[warn(unused_assignments)]` on by default
    = help: maybe it is overwritten before being read?

warning: value assigned to `sign_string` is never read
   --> src/lib.rs:277:13
    |
277 |         let mut sign_string = String::new();
    |             ^^^^^^^^^^^^^^^
    |
    = help: maybe it is overwritten before being read?

warning: variable does not need to be mutable
   --> src/lib.rs:157:13
    |
157 |         let mut n1 = num1.len();
    |             ----^^
    |             |
    |             help: remove this `mut`
    |
    = note: `#[warn(unused_mut)]` on by default

warning: variable does not need to be mutable
   --> src/lib.rs:158:13
    |
158 |         let mut n2 = num2.len();
    |             ----^^
    |             |
    |             help: remove this `mut`

warning: variable does not need to be mutable
   --> src/lib.rs:166:17
    |
166 |             let mut sum = num1.chars().nth(i).unwrap_or('0').to_digit(10).unwrap_or(0)
    |                 ----^^^
    |                 |
    |                 help: remove this `mut`

warning: variable does not need to be mutable
   --> src/lib.rs:175:17
    |
175 |             let mut sum = num2.chars().nth(i).unwrap_or('0').to_digit(10).unwrap_or(0) + carry;
    |                 ----^^^
    |                 |
    |                 help: remove this `mut`

warning: variable does not need to be mutable
   --> src/lib.rs:239:13
    |
239 |         let mut n1 = num1.len();
    |             ----^^
    |             |
    |             help: remove this `mut`

warning: variable does not need to be mutable
   --> src/lib.rs:240:13
    |
240 |         let mut n2 = num2.len();
    |             ----^^
    |             |
    |             help: remove this `mut`

warning: function is never used: `bigint`
   --> src/lib.rs:306:4
    |
306 | fn bigint(s: &str) -> Bigint {
    |    ^^^^^^
    |
    = note: `#[warn(dead_code)]` on by default

warning: function is never used: `main`
   --> src/lib.rs:310:4
    |
310 | fn main() {}
    |    ^^^^

warning: variable `deleteNumber` should have a snake case name
  --> src/lib.rs:17:17
   |
17 |         let mut deleteNumber = 0;
   |                 ^^^^^^^^^^^^ help: convert the identifier to snake case: `delete_number`
   |
   = note: `#[warn(non_snake_case)]` on by default

warning: function `isSmaller` should have a snake case name
   --> src/lib.rs:291:4
    |
291 | fn isSmaller(num1: &str, num2: &str) -> bool {
    |    ^^^^^^^^^ help: convert the identifier to snake case: `is_smaller`

warning: 12 warnings emitted

    Finished test [unoptimized + debuginfo] target(s) in 1.74s
     Running target/debug/deps/solution_test-589a43f0f4b10ca3

running 15 tests
test solution_test::test_bigint_construction ... ok
test solution_test::test_bigint_nonzero_sign ... ok
test solution_test::test_bigint_zero_sign ... ok
test solution_test::test_comparison ... ok
test solution_test::test_invalid_string ... ok
test solution_test::test_neutralization ... ok
test solution_test::test_parsing_with_and_without_sign ... ok
test solution_test::test_parsing_with_leading_zeroes ... ok
test solution_test::test_sub_1_basic ... ok
test solution_test::test_sub_2_diferent_lengths ... ok
test solution_test::test_sub_3_carry ... ok
test solution_test::test_sum_1_basic ... ok
test solution_test::test_sum_2_different_lengths ... ok
test solution_test::test_sum_3_overflow ... ok
test solution_test::test_sum_4_negative ... ok

test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

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

Ралица качи първо решение на 27.11.2020 16:15 (преди почти 5 години)