Решение на Bigint от Деян Горанов

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

Към профила на Деян Горанов

Резултати

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

Код

#[derive(Debug, PartialEq, Eq)]
pub struct Bigint {
sign: i8,
digits: Vec<u8>,
}
impl Bigint {
const ZERO_SIGN: i8 = 0;
const POSITIVE_SIGN: i8 = 1;
const NEGATIVE_SIGN: i8 = -1;
/// Конструира нов Bigint със стойност "0" и положителен знак.
/// Това може да означава празен вектор с цифри или масив с една цифра `0` -- ваш избор.
///
pub fn new() -> Self {
Bigint { sign: Self::ZERO_SIGN, digits: Vec::new() }
}
/// Конструира нов Bigint с подадените цифри и знак.
///
/// Тук е добро място където можете да вкарате малко валидация и нормализиране на входа -- да
/// премахнете допълнителни нули или да се погрижите, че нулата винаги има консистентен знак.
/// Стига да се погрижите винаги да използвате функцията при конструириане на нови Bigint-ове.
///
/// Тази функция НЕ Е публична, така че НЕ Е задължителна -- ако не ви трябва, може смело да я
/// изтриете.
///
fn from_components(input_sign: i8, input_digits: Vec<u8>) -> Self {
let digits =
input_digits.into_iter()
.skip_while(|&d| d == 0)
.collect::<Vec<u8>>();
let sign =
if digits.is_empty() {
Self::ZERO_SIGN
} else {
input_sign
};
Bigint { sign, digits }
}
/// Връща `true` ако числото е положително. Нулата не е положителна.
pub fn is_positive(&self) -> bool {
self.sign == Self::POSITIVE_SIGN
}
/// Връща `true` ако числото е отрицателно. Нулата не е отрицателна.
pub fn is_negative(&self) -> bool {
self.sign == Self::NEGATIVE_SIGN
}
}
use std::str::FromStr;
#[derive(Debug)]
pub struct ParseError;
impl FromStr for Bigint {
type Err = ParseError;
/// Очакваме низа да е във формат десетично цяло число с опционален знак, тоест всички тези
/// неща би трябвало да върнат `Ok` резултат с конструиран Bigint:
///
/// Това включва нулата, като имате предвид че, както казахме, +0 и -0 трябва да са
/// еквивалентни.
///
/// Ако подадения низ е празен, това връща същото като да сме подали "0". Ако подадения низ е
/// само "+" или "-", ваше решение е дали да е нула или да е грешка, няма да го тестваме.
///
/// Ако подадения низ започва с нули, това няма значение -- игнорират се. Тоест, конструиране с
/// "00123" ще е същото като конструиране с "123".
///
/// Ако сме подали низ, който включва каквито и да е други символи освен цифрите 0-9 (и
/// опционален начален знак), очакваме да върнете `ParseError`.
///
fn from_str(s: &str) -> Result<Self, Self::Err> {
let sign =
if s.chars().nth(0) == Some('-') {
Self::NEGATIVE_SIGN
} else {
Self::POSITIVE_SIGN
};
s.strip_prefix(|c| c == '+' || c == '-')
.unwrap_or(s)
.chars()
.map(|c| c.to_digit(10).map(|x| x as u8))
.collect::<Option<Vec<u8>>>()
.map(|digits| Bigint::from_components(sign, digits))
.ok_or(ParseError)
}
}
use std::cmp::Ordering;
impl PartialOrd for Bigint {
/// Две цели числа винаги могат да се сравнят, така че "частичното" равенство е същото като
/// пълното.
///
fn partial_cmp(&self, other: &Bigint) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Bigint {
/// Ако едното от числата е положително, а другото -- отрицателно, положителното е по-голямо.
///
/// Ако едното от числата има по-голям брой цифри, то ще бъде по-голямото. (Стига да не са нули
/// -- вероятно е добра идея да се погрижите да няма започващи нули при конструкция.)
///
/// Ако двете числа имат еднакъв брой цифри, лексикографско сравнение на числата ще ви даде
/// правилен резултат -- от по-значимите цифри към по-малко значимите. Внимавайте в какъв ред
/// си държите цифритe и дали не трябва да ги обърнете.
///
/// Ако двете числа са отрицателни, сравнението по абсолютна стойност ще е обърнато (-1 е
/// по-голямо от -2) -- погледнете документацията на `Ordering` за това как лесно можете да
/// обърнете резултата.
///
fn cmp(&self, other: &Bigint) -> Ordering {
if self.sign == other.sign {
let l1 = self.digits.len() as u8;
let l2 = other.digits.len() as u8;
let n = std::cmp::max(l1, l2);
let d1 = (0 .. n - l1).collect::<Vec<u8>>();
let d2 = (0 .. n - l2).collect::<Vec<u8>>();
d1.iter().chain(self.digits.iter())
.cmp(d2.iter().chain(other.digits.iter()))
} else {
self.sign.cmp(&other.sign)
}
}
}

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

Compiling solution v0.1.0 (/tmp/d20201127-2274206-qabsqi/solution)
error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
  --> tests/solution_test.rs:76:30
   |
76 |     assert_eq!(bigint("1")   + bigint("2"),   bigint("3"));
   |                -----------   ^ ----------- solution::Bigint
   |                |
   |                solution::Bigint

error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
  --> tests/solution_test.rs:77:30
   |
77 |     assert_eq!(bigint("111") + bigint("222"), bigint("333"));
   |                ------------- ^ ------------- solution::Bigint
   |                |
   |                solution::Bigint

error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
  --> tests/solution_test.rs:80:40
   |
80 |         bigint("11111111111111111111") +
   |         ------------------------------ ^
   |         |
   |         solution::Bigint
81 |         bigint("22222222222222222222"),
   |         ------------------------------ solution::Bigint

error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
  --> tests/solution_test.rs:88:31
   |
88 |     assert_eq!(bigint("12")   + bigint("12000"), bigint("12012"));
   |                ------------   ^ --------------- solution::Bigint
   |                |
   |                solution::Bigint

error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
  --> tests/solution_test.rs:89:31
   |
89 |     assert_eq!(bigint("1")    + bigint("123"),   bigint("124"));
   |                -----------    ^ ------------- solution::Bigint
   |                |
   |                solution::Bigint

error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
  --> tests/solution_test.rs:90:31
   |
90 |     assert_eq!(bigint("111")  + bigint("0"),     bigint("111"));
   |                -------------  ^ ----------- solution::Bigint
   |                |
   |                solution::Bigint

error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
  --> tests/solution_test.rs:91:31
   |
91 |     assert_eq!(bigint("0")    + bigint("444"),   bigint("444"));
   |                -----------    ^ ------------- solution::Bigint
   |                |
   |                solution::Bigint

error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
  --> tests/solution_test.rs:92:31
   |
92 |     assert_eq!(bigint("+123") + bigint("+456"),  bigint("579"));
   |                -------------- ^ -------------- solution::Bigint
   |                |
   |                solution::Bigint

error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
  --> tests/solution_test.rs:97:30
   |
97 |     assert_eq!(bigint("999") + bigint("1"),   bigint("1000"));
   |                ------------- ^ ----------- solution::Bigint
   |                |
   |                solution::Bigint

error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
  --> tests/solution_test.rs:98:30
   |
98 |     assert_eq!(bigint("511") + bigint("599"), bigint("1110"));
   |                ------------- ^ ------------- solution::Bigint
   |                |
   |                solution::Bigint

error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
   --> tests/solution_test.rs:100:31
    |
100 |     assert_eq!(bigint("-999") + bigint("-1"),   bigint("-1000"));
    |                -------------- ^ ------------ solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
   --> tests/solution_test.rs:101:31
    |
101 |     assert_eq!(bigint("-511") + bigint("-599"), bigint("-1110"));
    |                -------------- ^ -------------- solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
   --> tests/solution_test.rs:104:40
    |
104 |         bigint("99999999999999999999") +
    |         ------------------------------ ^
    |         |
    |         solution::Bigint
105 |         bigint("1"),
    |         ----------- solution::Bigint

error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
   --> tests/solution_test.rs:112:31
    |
112 |     assert_eq!(bigint("-123") + bigint("-456"),   bigint("-579"));
    |                -------------- ^ -------------- solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
   --> tests/solution_test.rs:113:31
    |
113 |     assert_eq!(bigint("-12")  + bigint("-12000"), bigint("-12012"));
    |                -------------  ^ ---------------- solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
   --> tests/solution_test.rs:114:31
    |
114 |     assert_eq!(bigint("-1")   + bigint("-123"),   bigint("-124"));
    |                ------------   ^ -------------- solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
   --> tests/solution_test.rs:115:31
    |
115 |     assert_eq!(bigint("-111") + bigint("-0"),     bigint("-111"));
    |                -------------- ^ ------------ solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
   --> tests/solution_test.rs:116:31
    |
116 |     assert_eq!(bigint("-0")   + bigint("-444"),   bigint("-444"));
    |                ------------   ^ -------------- solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
   --> tests/solution_test.rs:118:31
    |
118 |     assert_eq!(bigint("-123") + bigint("456"), bigint("333"));
    |                -------------- ^ ------------- solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
   --> tests/solution_test.rs:119:31
    |
119 |     assert_eq!(bigint("123")  + bigint("-456"), bigint("-333"));
    |                -------------  ^ -------------- solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
   --> tests/solution_test.rs:120:31
    |
120 |     assert_eq!(bigint("456")  + bigint("-123"), bigint("333"));
    |                -------------  ^ -------------- solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
   --> tests/solution_test.rs:121:31
    |
121 |     assert_eq!(bigint("-456") + bigint("123"), bigint("-333"));
    |                -------------- ^ ------------- solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
   --> tests/solution_test.rs:126:31
    |
126 |     assert_eq!(bigint("-123") + bigint("123"), bigint("0"));
    |                -------------- ^ ------------- solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
   --> tests/solution_test.rs:127:30
    |
127 |     assert_eq!(bigint("123") + bigint("-123"), bigint("0"));
    |                ------------- ^ -------------- solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
   --> tests/solution_test.rs:128:29
    |
128 |     assert_eq!(bigint("-0") + bigint("+0"), bigint("0"));
    |                ------------ ^ ------------ solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot add `solution::Bigint` to `solution::Bigint`
   --> tests/solution_test.rs:129:29
    |
129 |     assert_eq!(bigint("+0") + bigint("-0"), bigint("0"));
    |                ------------ ^ ------------ solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot subtract `solution::Bigint` from `solution::Bigint`
   --> tests/solution_test.rs:131:31
    |
131 |     assert_eq!(bigint("123")  - bigint("123"),  bigint("0"));
    |                -------------  ^ ------------- solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot subtract `solution::Bigint` from `solution::Bigint`
   --> tests/solution_test.rs:132:31
    |
132 |     assert_eq!(bigint("-123") - bigint("-123"), bigint("0"));
    |                -------------- ^ -------------- solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot subtract `solution::Bigint` from `solution::Bigint`
   --> tests/solution_test.rs:133:31
    |
133 |     assert_eq!(bigint("-0")   - bigint("-0"),   bigint("0"));
    |                ------------   ^ ------------ solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot subtract `solution::Bigint` from `solution::Bigint`
   --> tests/solution_test.rs:134:31
    |
134 |     assert_eq!(bigint("+0")   - bigint("+0"),   bigint("0"));
    |                ------------   ^ ------------ solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot subtract `solution::Bigint` from `solution::Bigint`
   --> tests/solution_test.rs:139:30
    |
139 |     assert_eq!(bigint("567") - bigint("123"), bigint("444"));
    |                ------------- ^ ------------- solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot subtract `solution::Bigint` from `solution::Bigint`
   --> tests/solution_test.rs:140:30
    |
140 |     assert_eq!(bigint("123") - bigint("567"), bigint("-444"));
    |                ------------- ^ ------------- solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot subtract `solution::Bigint` from `solution::Bigint`
   --> tests/solution_test.rs:143:40
    |
143 |         bigint("33333333333333333333") -
    |         ------------------------------ ^
    |         |
    |         solution::Bigint
144 |         bigint("22222222222222222222"),
    |         ------------------------------ solution::Bigint

error[E0369]: cannot subtract `solution::Bigint` from `solution::Bigint`
   --> tests/solution_test.rs:151:31
    |
151 |     assert_eq!(bigint("1100") - bigint("100"), bigint("1000"));
    |                -------------- ^ ------------- solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot subtract `solution::Bigint` from `solution::Bigint`
   --> tests/solution_test.rs:152:31
    |
152 |     assert_eq!(bigint("1567") - bigint("123"), bigint("1444"));
    |                -------------- ^ ------------- solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot subtract `solution::Bigint` from `solution::Bigint`
   --> tests/solution_test.rs:157:31
    |
157 |     assert_eq!(bigint("1000") - bigint("1"),    bigint("999"));
    |                -------------- ^ ----------- solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot subtract `solution::Bigint` from `solution::Bigint`
   --> tests/solution_test.rs:158:31
    |
158 |     assert_eq!(bigint("1110") - bigint("599"),  bigint("511"));
    |                -------------- ^ ------------- solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot subtract `solution::Bigint` from `solution::Bigint`
   --> tests/solution_test.rs:159:31
    |
159 |     assert_eq!(bigint("123")  - bigint("1567"), bigint("-1444"));
    |                -------------  ^ -------------- solution::Bigint
    |                |
    |                solution::Bigint

error[E0369]: cannot subtract `solution::Bigint` from `solution::Bigint`
   --> tests/solution_test.rs:162:41
    |
162 |         bigint("100000000000000000000") -
    |         ------------------------------- ^
    |         |
    |         solution::Bigint
163 |         bigint("1"),
    |         ----------- solution::Bigint

error: aborting due to 39 previous errors

For more information about this error, try `rustc --explain E0369`.
error: could not compile `solution`

To learn more, run the command again with --verbose.

История (2 версии и 3 коментара)

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

Деян качи решение на 27.11.2020 16:55 (преди почти 5 години)

#[derive(Debug, PartialEq, Eq)]
pub struct Bigint {
sign: i8,
digits: Vec<u8>,
}
impl Bigint {
const ZERO_SIGN: i8 = 0;
const POSITIVE_SIGN: i8 = 1;
const NEGATIVE_SIGN: i8 = -1;
/// Конструира нов Bigint със стойност "0" и положителен знак.
/// Това може да означава празен вектор с цифри или масив с една цифра `0` -- ваш избор.
///
pub fn new() -> Self {
Bigint { sign: Self::ZERO_SIGN, digits: Vec::new() }
}
/// Конструира нов Bigint с подадените цифри и знак.
///
/// Тук е добро място където можете да вкарате малко валидация и нормализиране на входа -- да
/// премахнете допълнителни нули или да се погрижите, че нулата винаги има консистентен знак.
/// Стига да се погрижите винаги да използвате функцията при конструириане на нови Bigint-ове.
///
/// Тази функция НЕ Е публична, така че НЕ Е задължителна -- ако не ви трябва, може смело да я
/// изтриете.
///
fn from_components(input_sign: i8, input_digits: Vec<u8>) -> Self {
let digits =
input_digits.into_iter()
.skip_while(|&d| d == 0)
.collect::<Vec<u8>>();
let sign =
if digits.is_empty() {
Self::ZERO_SIGN
} else {
input_sign
};
Bigint { sign, digits }
}
/// Връща `true` ако числото е положително. Нулата не е положителна.
pub fn is_positive(&self) -> bool {
self.sign == Self::POSITIVE_SIGN
}
/// Връща `true` ако числото е отрицателно. Нулата не е отрицателна.
pub fn is_negative(&self) -> bool {
self.sign == Self::NEGATIVE_SIGN
}
}
use std::str::FromStr;
#[derive(Debug)]
pub struct ParseError;
impl FromStr for Bigint {
type Err = ParseError;
/// Очакваме низа да е във формат десетично цяло число с опционален знак, тоест всички тези
/// неща би трябвало да върнат `Ok` резултат с конструиран Bigint:
///
- /// Bigint::from_str("123") // => положителен знак по подразбиране
- /// Bigint::from_str("+123")
- /// Bigint::from_str("-123")
- ///
/// Това включва нулата, като имате предвид че, както казахме, +0 и -0 трябва да са
/// еквивалентни.
///
/// Ако подадения низ е празен, това връща същото като да сме подали "0". Ако подадения низ е
/// само "+" или "-", ваше решение е дали да е нула или да е грешка, няма да го тестваме.
///
/// Ако подадения низ започва с нули, това няма значение -- игнорират се. Тоест, конструиране с
/// "00123" ще е същото като конструиране с "123".
///
/// Ако сме подали низ, който включва каквито и да е други символи освен цифрите 0-9 (и
/// опционален начален знак), очакваме да върнете `ParseError`.
///
fn from_str(s: &str) -> Result<Self, Self::Err> {
let sign =
if s.chars().nth(0) == Some('-') {
Self::NEGATIVE_SIGN
} else {
Self::POSITIVE_SIGN
};
s.strip_prefix(|c| c == '+' || c == '-')
.unwrap_or(s)
.chars()
.map(|c| c.to_digit(10).map(|x| x as u8))
.collect::<Option<Vec<u8>>>()
.map(|digits| Bigint::from_components(sign, digits))
.ok_or(ParseError)
}
}
use std::cmp::Ordering;
impl PartialOrd for Bigint {
/// Две цели числа винаги могат да се сравнят, така че "частичното" равенство е същото като
/// пълното.
///
fn partial_cmp(&self, other: &Bigint) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Bigint {
/// Ако едното от числата е положително, а другото -- отрицателно, положителното е по-голямо.
///
/// Ако едното от числата има по-голям брой цифри, то ще бъде по-голямото. (Стига да не са нули
/// -- вероятно е добра идея да се погрижите да няма започващи нули при конструкция.)
///
/// Ако двете числа имат еднакъв брой цифри, лексикографско сравнение на числата ще ви даде
/// правилен резултат -- от по-значимите цифри към по-малко значимите. Внимавайте в какъв ред
/// си държите цифритe и дали не трябва да ги обърнете.
///
/// Ако двете числа са отрицателни, сравнението по абсолютна стойност ще е обърнато (-1 е
/// по-голямо от -2) -- погледнете документацията на `Ordering` за това как лесно можете да
/// обърнете резултата.
///
fn cmp(&self, other: &Bigint) -> Ordering {
if self.sign == other.sign {
let l1 = self.digits.len() as u8;
let l2 = other.digits.len() as u8;
let n = std::cmp::max(l1, l2);
let d1 = (0 .. n - l1).collect::<Vec<u8>>();
let d2 = (0 .. n - l2).collect::<Vec<u8>>();
d1.iter().chain(self.digits.iter())
.cmp(d2.iter().chain(other.digits.iter()))
} else {
self.sign.cmp(&other.sign)
}
}
}

Кода ти не се компилира, защото нямаш имплементации на Add и Sub, така че няма как да получиш точки. Казахме го в общия guide: https://fmi.rust-lang.bg/tasks/guide. Конкретно:

Изпълнете примерния тест. Ако кода ви не се компилира на примерния тест, ще получите 0 точки. Проверете, че типовете на функциите и структурите ви са същите, които сме описали в условието. Ако решите да върнете тип Foo вместо описания тип &Foo, нашите тестове просто няма да се компилират и ще получите 0 точки.

Ако беше предал по-рано, щях да те предупредя поне.