All Your Base

1. Readme

你的所有基本

将一个数字,表示为一个基数中的数字序列,并转为其他基本

实施通用基本转换。给出一个a参数,表示为数字序列,将其转换为基数b

笔记

  • 尝试自己实现转换。请勿使用其他内容为您执行转换.

关于位置表示法

在位置表示法中,以数字表示b可以被理解为权力的线性组合b.

数字 42,基本为 10,意思是:

(4 * 10^1) + (2 * 10^0)

数字 101010,基本为 2,意思是:

(1 * 2^5) + (0 * 2^4) + (1 * 2^3) + (0 * 2^2) + (1 * 2^1) + (0 * 2^0)

号码 1120,基本为 3,意思是:

(1 * 3^3) + (1 * 3^2) + (2 * 3^1) + (0 * 3^0)

我想你明白了!

是。上面这三个数字完全一样。恭喜!

2. 开始你的表演

#[derive(Debug, PartialEq)]
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. 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> {
   unimplemented!(
       "Convert {:?} from base {} to base {}",
       number,
       from_base,
       to_base
   )
}

3. 测试代码查看


# #![allow(unused_variables)]
#fn main() {
#[test]
fn single_bit_one_to_decimal() {
   let input_base = 2;
   let input_digits = &[1];
   let output_base = 10;
   let output_digits = vec![1];
   assert_eq!(
       convert(input_digits, input_base, output_base),
       Ok(output_digits)
   );
}

#[test]
//#[ignore]
fn binary_to_single_decimal() {
   let input_base = 2;
   let input_digits = &[1, 0, 1];
   let output_base = 10;
   let output_digits = vec![5];
   assert_eq!(
       convert(input_digits, input_base, output_base),
       Ok(output_digits)
   );
}

#[test]
//#[ignore]
fn single_decimal_to_binary() {
   let input_base = 10;
   let input_digits = &[5];
   let output_base = 2;
   let output_digits = vec![1, 0, 1];
   assert_eq!(
       convert(input_digits, input_base, output_base),
       Ok(output_digits)
   );
}

#[test]
//#[ignore]
fn binary_to_multiple_decimal() {
   let input_base = 2;
   let input_digits = &[1, 0, 1, 0, 1, 0];
   let output_base = 10;
   let output_digits = vec![4, 2];
   assert_eq!(
       convert(input_digits, input_base, output_base),
       Ok(output_digits)
   );
}

#[test]
//#[ignore]
fn decimal_to_binary() {
   let input_base = 10;
   let input_digits = &[4, 2];
   let output_base = 2;
   let output_digits = vec![1, 0, 1, 0, 1, 0];
   assert_eq!(
       convert(input_digits, input_base, output_base),
       Ok(output_digits)
   );
}

#[test]
//#[ignore]
fn trinary_to_hexadecimal() {
   let input_base = 3;
   let input_digits = &[1, 1, 2, 0];
   let output_base = 16;
   let output_digits = vec![2, 10];
   assert_eq!(
       convert(input_digits, input_base, output_base),
       Ok(output_digits)
   );
}

#[test]
//#[ignore]
fn hexadecimal_to_trinary() {
   let input_base = 16;
   let input_digits = &[2, 10];
   let output_base = 3;
   let output_digits = vec![1, 1, 2, 0];
   assert_eq!(
       convert(input_digits, input_base, output_base),
       Ok(output_digits)
   );
}

#[test]
//#[ignore]
fn fifteen_bit_integer() {
   let input_base = 97;
   let input_digits = &[3, 46, 60];
   let output_base = 73;
   let output_digits = vec![6, 10, 45];
   assert_eq!(
       convert(input_digits, input_base, output_base),
       Ok(output_digits)
   );
}

#[test]
//#[ignore]
fn empty_list() {
   let input_base = 2;
   let input_digits = &[];
   let output_base = 10;
   let output_digits = vec![];
   assert_eq!(
       convert(input_digits, input_base, output_base),
       Ok(output_digits)
   );
}

#[test]
//#[ignore]
fn single_zero() {
   let input_base = 10;
   let input_digits = &[0];
   let output_base = 2;
   let output_digits = vec![];
   assert_eq!(
       convert(input_digits, input_base, output_base),
       Ok(output_digits)
   );
}

#[test]
//#[ignore]
fn multiple_zeros() {
   let input_base = 10;
   let input_digits = &[0, 0, 0];
   let output_base = 2;
   let output_digits = vec![];
   assert_eq!(
       convert(input_digits, input_base, output_base),
       Ok(output_digits)
   );
}

#[test]
//#[ignore]
fn leading_zeros() {
   let input_base = 7;
   let input_digits = &[0, 6, 0];
   let output_base = 10;
   let output_digits = vec![4, 2];
   assert_eq!(
       convert(input_digits, input_base, output_base),
       Ok(output_digits)
   );
}

#[test]
//#[ignore]
fn invalid_positive_digit() {
   let input_base = 2;
   let input_digits = &[1, 2, 1, 0, 1, 0];
   let output_base = 10;
   assert_eq!(
       convert(input_digits, input_base, output_base),
       Err(Error::InvalidDigit(2))
   );
}

#[test]
//#[ignore]
fn input_base_is_one() {
   let input_base = 1;
   let input_digits = &[];
   let output_base = 10;
   assert_eq!(
       convert(input_digits, input_base, output_base),
       Err(Error::InvalidInputBase)
   );
}

#[test]
//#[ignore]
fn output_base_is_one() {
   let input_base = 2;
   let input_digits = &[1, 0, 1, 0, 1, 0];
   let output_base = 1;
   assert_eq!(
       convert(input_digits, input_base, output_base),
       Err(Error::InvalidOutputBase)
   );
}

#[test]
//#[ignore]
fn input_base_is_zero() {
   let input_base = 0;
   let input_digits = &[];
   let output_base = 10;
   assert_eq!(
       convert(input_digits, input_base, output_base),
       Err(Error::InvalidInputBase)
   );
}

#[test]
//#[ignore]
fn output_base_is_zero() {
   let input_base = 10;
   let input_digits = &[7];
   let output_base = 0;
   assert_eq!(
       convert(input_digits, input_base, output_base),
       Err(Error::InvalidOutputBase)
   );
}

#}

4. 答案


# #![allow(unused_variables)]
#fn main() {
pub type Digit = u32;

#[derive(Debug, PartialEq)]
pub enum Error {
   InvalidInputBase,
   InvalidOutputBase,
   InvalidDigit(Digit),
}

///
/// 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. However, your function must be able to
///     process input with leading 0 digits.
///
pub fn convert<P: AsRef<[Digit]>>(
   digits: P,
   from_base: Digit,
   to_base: Digit,
) -> Result<Vec<Digit>, Error> {
   // check that both bases are in the correct range
   if from_base < 2 {
       return Err(Error::InvalidInputBase);
   }
   if to_base < 2 {
       return Err(Error::InvalidOutputBase);
   }

   // check that all digits are in the correct range specified by the base
   if let Some(&invalid) = digits.as_ref().iter().find(|&num| *num >= from_base) {
       return Err(Error::InvalidDigit(invalid));
   }

   // convert all digits into a single large number
   let mut immediate = digits
       .as_ref()
       .iter()
       .rev()
       .enumerate()
       .map(|(i, &num)| num * from_base.pow(i as u32))
       .fold(0, |accu, num| accu + num);

   // convert number into digits
   let mut res = Vec::new();
   while immediate > 0 {
       res.push(immediate % to_base);
       immediate /= to_base;
   }
   // fix order of digits
   res.reverse();
   Ok(res)
}

#}



填充/相关