-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathlib.rs
More file actions
65 lines (64 loc) · 1.83 KB
/
lib.rs
File metadata and controls
65 lines (64 loc) · 1.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#[derive(Debug, PartialEq, Eq)]
pub enum Error {
InvalidInputBase,
InvalidOutputBase,
InvalidDigit(u32),
}
///
/// Convert a number between two bases.
///
/// A number is any slice of digits.
/// A digit is any unsigned integer (e.g. u8, u16, u32, u64, or usize).
/// Bases are specified as unsigned integers.
///
/// Return an `Err(.)` if the conversion is impossible.
/// The tests do not test for specific values inside the `Err(.)`.
///
///
/// You are allowed to change the function signature as long as all test still pass.
///
///
/// Example:
/// Input
/// number: &[4, 2]
/// from_base: 10
/// to_base: 2
/// Result
/// Ok(vec![1, 0, 1, 0, 1, 0])
///
/// The example corresponds to converting the number 42 from decimal
/// which is equivalent to 101010 in binary.
///
///
/// Notes:
/// * The empty slice ( "[]" ) is equal to the number 0.
/// * Never output leading 0 digits, unless the input number is 0, in which the output must be `[0]`.
/// However, your function must be able to process input with leading 0 digits.
///
pub fn convert(number: &[u32], from_base: u32, to_base: u32) -> Result<Vec<u32>, Error> {
if from_base < 2 {
Err(Error::InvalidInputBase)
} else if to_base < 2 {
Err(Error::InvalidOutputBase)
} else {
// Intermediate decimal representation
let mut decimal = number.iter().try_fold(0, |acc, &d| {
if d >= from_base {
Err(Error::InvalidDigit(d))
} else {
Ok(acc * from_base + d)
}
})?;
if decimal == 0 {
Ok(vec![0])
} else {
let mut digits = vec![];
while decimal > 0 {
digits.push(decimal % to_base);
decimal /= to_base;
}
digits.reverse();
Ok(digits)
}
}
}