Решение на Bigint от Кристиян Стоянов

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

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

Резултати

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

Код

use std::str::FromStr;
use std::cmp::Ordering;
#[derive(Debug, PartialEq, Eq)]
pub struct Bigint {
sign: i8,
digits: Vec<u8>,
}
impl Bigint {
pub fn new() -> Self {
let mut temp=Vec::<u8>::new();
temp.push(0);
Bigint {
sign: 1,
digits:temp,
}
}
pub fn is_positive(&self) -> bool
{
return self.sign != 0
}
pub fn is_negative(&self) -> bool
{
return self.sign == 0
}
}
#[derive(Debug)]
pub struct ParseError;
impl FromStr for Bigint
{
type Err = ParseError;
fn from_str(s: &str) -> Result<Self, Self::Err>
{
if s.is_empty()
{
let mut temp=Vec::<u8>::new();
temp.push(0);
let t = 0 as i8;
return Ok(Bigint{ sign: t,digits: temp });
}
let mut chars: Vec<char> = s.chars().collect();
let mut is_positive=false;
if chars[0]=='-'
{
chars=(&chars[1..]).to_vec();
}else if chars[0]=='+'
{
chars=(&chars[1..]).to_vec();
is_positive=true;
}
else if chars[0]>='0' && chars[0]<='9'
{
is_positive=true;
}
else
{
return Err(ParseError);
}
let mut is_positives;
if is_positive
{
is_positives=1 as i8;
}
else{
is_positives=0 as i8;
}
if chars.is_empty()
{
return Err(ParseError);
}
let mut tempnumber=0;
while tempnumber<chars.iter().count()
{
if chars[tempnumber]<'0' || chars[tempnumber]>'9'
{
return Err(ParseError);
}
tempnumber=tempnumber+1;
}
while chars[0]=='0'
{
if chars.iter().count()!=1
{
chars=(&chars[1..]).to_vec();
}
else
{
is_positives=1;
break;
}
}
let mut number=0;
let mut tempdigits: Vec<u8>=Vec::new();
while number<chars.iter().count()
{
let x=chars[number];
tempdigits.push(x as u8 -48);
number=number+1;
}
return Ok(Bigint{ sign: is_positives,digits: tempdigits });
}
}
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.is_positive() && other.is_negative()
{
return Ordering::Greater;
}
else if self.is_negative() && other.is_positive()
{
return Ordering::Less;
}
else if self.is_positive() && other.is_positive()
{
if self.digits.iter().count()>other.digits.iter().count()
{
return Ordering::Greater;
}
else if self.digits.iter().count()<other.digits.iter().count()
{
return Ordering::Less;
}
else//equal number of digits
{
let mut tempdigitcounter=0;
while tempdigitcounter<self.digits.iter().count()
{
if self.digits[tempdigitcounter]>other.digits[tempdigitcounter]
{
return Ordering::Greater;
}else if self.digits[tempdigitcounter]<other.digits[tempdigitcounter]
{
return Ordering::Less;
}
tempdigitcounter=tempdigitcounter+1;
}
return Ordering::Equal;
}
}
else //both are negative
{
if self.digits.iter().count()>other.digits.iter().count()
{
return Ordering::Less;
}
else if self.digits.iter().count()<other.digits.iter().count()
{
return Ordering::Greater;
}
else//equal number of digits
{
let mut tempdigitcounter=0;
while tempdigitcounter<self.digits.iter().count()
{
if self.digits[tempdigitcounter]>other.digits[tempdigitcounter]
{
return Ordering::Less;
}else if self.digits[tempdigitcounter]<other.digits[tempdigitcounter]
{
return Ordering::Greater;
}
tempdigitcounter=tempdigitcounter+1;
}
return Ordering::Equal;
}
}
}
}
use std::ops::{Add, Sub};
impl Add for Bigint {
type Output = Bigint;
fn add(self, other: Self) -> Self {
if self.sign==1 && other.sign==1 || self.sign==0 && other.sign==0
{
let mut p=self.digits;
let mut s=other.digits;
let mut tempdigits: Vec<u8>=Vec::new();
let mut numbers_in_lesser_number;
if p.iter().count()<s.iter().count()
{
numbers_in_lesser_number=p.iter().count();
}
else{
numbers_in_lesser_number=s.iter().count();
}
let mut tempnumber=0;
let mut decimals=0;
while tempnumber<numbers_in_lesser_number
{
let mut t=p[tempnumber]+s[tempnumber];
t=t+decimals;
decimals=0;
if t>=10
{
t=t-10;
decimals=1;
}
tempdigits.push(t);
tempnumber=tempnumber+1;
}
if tempdigits.iter().count()<p.iter().count()
{
tempdigits.push(p[tempnumber] + decimals);
decimals=0;
let mut k=tempdigits.iter().count();
while k<p.iter().count()
{
tempdigits.push(p[k]);
k=k+1;
}
}else if tempdigits.iter().count()<s.iter().count()
{
tempdigits.push(s[tempnumber] + decimals);
decimals=0;
let mut k=tempdigits.iter().count();
while k<s.iter().count()
{
tempdigits.push(s[k]);
k=k+1;
}
} else
{
if decimals==1
{
tempdigits.push(decimals);
}
}
return Bigint{sign: self.sign, digits:tempdigits};
}
else
{
if self.sign==0
{
return other - self;
}
else
{
return self - other;
}
}
}
}
impl Sub for Bigint {
type Output = Bigint;
fn sub(self, other: Self) -> Self {
return self;
}
}
fn bigint(s: &str) -> Bigint {
Bigint::from_str(s).unwrap()
}
fn main()
{
assert_eq!(Bigint::new(), bigint("0"));
assert!(Bigint::from_str("foobar").is_err());
assert!(bigint("1").is_positive());
assert!(bigint("-1").is_negative());
assert!(bigint("123") < bigint("1223"));
println!("{:?}",bigint("123") + bigint("456"));
assert_eq!(bigint("123") + bigint("456"), bigint("579"));
}

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

Compiling solution v0.1.0 (/tmp/d20201127-2274206-1el6fp6/solution)
warning: value assigned to `decimals` is never read
   --> src/lib.rs:229:17
    |
229 |                 decimals=0;
    |                 ^^^^^^^^
    |
    = note: `#[warn(unused_assignments)]` on by default
    = help: maybe it is overwritten before being read?

warning: value assigned to `decimals` is never read
   --> src/lib.rs:239:17
    |
239 |                 decimals=0;
    |                 ^^^^^^^^
    |
    = help: maybe it is overwritten before being read?

warning: unused variable: `other`
   --> src/lib.rs:272:18
    |
272 |     fn sub(self, other: Self) -> Self {
    |                  ^^^^^ help: if this is intentional, prefix it with an underscore: `_other`
    |
    = note: `#[warn(unused_variables)]` on by default

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

warning: variable does not need to be mutable
   --> src/lib.rs:200:12
    |
200 |        let mut s=other.digits;
    |            ----^
    |            |
    |            help: remove this `mut`

warning: variable does not need to be mutable
   --> src/lib.rs:202:12
    |
202 |        let mut numbers_in_lesser_number;
    |            ----^^^^^^^^^^^^^^^^^^^^^^^^
    |            |
    |            help: remove this `mut`

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

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

warning: 8 warnings emitted

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

running 15 tests
test solution_test::test_bigint_construction ... FAILED
test solution_test::test_bigint_nonzero_sign ... ok
test solution_test::test_bigint_zero_sign ... FAILED
test solution_test::test_comparison ... ok
test solution_test::test_invalid_string ... ok
test solution_test::test_neutralization ... FAILED
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 ... FAILED
test solution_test::test_sub_2_diferent_lengths ... FAILED
test solution_test::test_sub_3_carry ... FAILED
test solution_test::test_sum_1_basic ... ok
test solution_test::test_sum_2_different_lengths ... FAILED
test solution_test::test_sum_3_overflow ... FAILED
test solution_test::test_sum_4_negative ... FAILED

failures:

---- solution_test::test_bigint_construction stdout ----
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `Bigint { sign: 1, digits: [0] }`,
 right: `Bigint { sign: 0, digits: [0] }`', tests/solution_test.rs:15:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

---- solution_test::test_bigint_zero_sign stdout ----
thread 'main' panicked at 'assertion failed: !zero.is_positive()', tests/solution_test.rs:21:5

---- solution_test::test_neutralization stdout ----
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `Bigint { sign: 1, digits: [1, 2, 3] }`,
 right: `Bigint { sign: 1, digits: [0] }`', tests/solution_test.rs:126:5

---- solution_test::test_sub_1_basic stdout ----
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `Bigint { sign: 1, digits: [5, 6, 7] }`,
 right: `Bigint { sign: 1, digits: [4, 4, 4] }`', tests/solution_test.rs:139:5

---- solution_test::test_sub_2_diferent_lengths stdout ----
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `Bigint { sign: 1, digits: [1, 1, 0, 0] }`,
 right: `Bigint { sign: 1, digits: [1, 0, 0, 0] }`', tests/solution_test.rs:151:5

---- solution_test::test_sub_3_carry stdout ----
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `Bigint { sign: 1, digits: [1, 0, 0, 0] }`,
 right: `Bigint { sign: 1, digits: [9, 9, 9] }`', tests/solution_test.rs:157:5

---- solution_test::test_sum_2_different_lengths stdout ----
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `Bigint { sign: 1, digits: [2, 4, 0, 0, 0] }`,
 right: `Bigint { sign: 1, digits: [1, 2, 0, 1, 2] }`', tests/solution_test.rs:88:5

---- solution_test::test_sum_3_overflow stdout ----
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `Bigint { sign: 1, digits: [0, 10, 9] }`,
 right: `Bigint { sign: 1, digits: [1, 0, 0, 0] }`', tests/solution_test.rs:97:5

---- solution_test::test_sum_4_negative stdout ----
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `Bigint { sign: 0, digits: [2, 4, 0, 0, 0] }`,
 right: `Bigint { sign: 0, digits: [1, 2, 0, 1, 2] }`', tests/solution_test.rs:113:5


failures:
    solution_test::test_bigint_construction
    solution_test::test_bigint_zero_sign
    solution_test::test_neutralization
    solution_test::test_sub_1_basic
    solution_test::test_sub_2_diferent_lengths
    solution_test::test_sub_3_carry
    solution_test::test_sum_2_different_lengths
    solution_test::test_sum_3_overflow
    solution_test::test_sum_4_negative

test result: FAILED. 6 passed; 9 failed; 0 ignored; 0 measured; 0 filtered out

error: test failed, to rerun pass '--test solution_test'

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

Кристиян качи първо решение на 27.11.2020 16:33 (преди почти 5 години)