Largest Series Product

1. Readme

最大系列乘积

给定一个数字串,计算长度为 n 的连续子串的最大乘积.

例如,对于输入'1027839564' , 3 位数系列的最大乘积是 270 (9 * 5 * 6), 5 位数系列的最大乘积为 7560 (7 * 8 * 3 * 9 * 5).

注意这些系列数字字符,在输入中,只要求相邻位置,不需要连续数值(123456..).

对于输入'73167176531330624919225119674426574742355349194934'一系列 6 位数的最大乘积是 23520.

Rust 的最大系列乘积

这些迭代器可能是有用的,取决于您的方法.

资源

欧拉工程的问题 8 的一个变种http://projecteuler.net/problem=8

2. 开始你的表演

#[derive(Debug, PartialEq)]
pub enum Error {
   SpanTooLong,
   InvalidDigit(char),
}

pub fn lsp(string_digits: &str, span: usize) -> Result<u64, Error> {
   unimplemented!(
       "largest series product of a span of {} digits in {}",
       span,
       string_digits
   );
}

3. 测试代码查看


# #![allow(unused_variables)]
#fn main() {
#[test]
fn return_is_a_result() {
   assert!(lsp("29", 2).is_ok());
}

#[test]
//#[ignore]
fn find_the_largest_product_when_span_equals_length() {
   assert_eq!(Ok(18), lsp("29", 2));
}

#[test]
//#[ignore]
fn find_the_largest_product_of_two_with_numbers_in_order() {
   assert_eq!(Ok(72), lsp("0123456789", 2));
}

#[test]
//#[ignore]
fn find_the_largest_product_of_two_with_numbers_not_in_order() {
   assert_eq!(Ok(48), lsp("576802143", 2));
}

#[test]
//#[ignore]
fn find_the_largest_product_of_three_with_numbers_in_order() {
   assert_eq!(Ok(504), lsp("0123456789", 3));
}

#[test]
//#[ignore]
fn find_the_largest_product_of_three_with_numbers_not_in_order() {
   assert_eq!(Ok(270), lsp("1027839564", 3));
}

#[test]
//#[ignore]
fn find_the_largest_product_of_five_with_numbers_in_order() {
   assert_eq!(Ok(15120), lsp("0123456789", 5));
}

#[test]
//#[ignore]
fn span_of_six_in_a_large_number() {
   assert_eq!(
       Ok(23520),
       lsp("73167176531330624919225119674426574742355349194934", 6)
   );
}

#[test]
//#[ignore]
fn returns_zero_if_number_is_zeros() {
   assert_eq!(Ok(0), lsp("0000", 2));
}

#[test]
//#[ignore]
fn returns_zero_if_all_products_are_zero() {
   assert_eq!(Ok(0), lsp("99099", 3));
}

#[test]
//#[ignore]
fn a_span_is_longer_than_number_is_an_error() {
   assert_eq!(Err(Error::SpanTooLong), lsp("123", 4));
}

// There may be some confusion about whether this should be 1 or error.
// The reasoning for it being 1 is this:
// There is one 0-character string contained in the empty string.
// That's the empty string itself.
// The empty product is 1 (the identity for multiplication).
// Therefore LSP('', 0) is 1.
// It's NOT the case that LSP('', 0) takes max of an empty list.
// So there is no error.
// Compare against LSP('123', 4):
// There are zero 4-character strings in '123'.
// So LSP('123', 4) really DOES take the max of an empty list.
// So LSP('123', 4) errors and LSP('', 0) does NOT.
#[test]
//#[ignore]
fn an_empty_string_and_no_span_returns_one() {
   assert_eq!(Ok(1), lsp("", 0));
}

#[test]
//#[ignore]
fn a_non_empty_string_and_no_span_returns_one() {
   assert_eq!(Ok(1), lsp("123", 0));
}

#[test]
//#[ignore]
fn empty_string_and_non_zero_span_is_an_error() {
   assert_eq!(Err(Error::SpanTooLong), lsp("", 1));
}

#[test]
//#[ignore]
fn a_string_with_non_digits_is_an_error() {
   assert_eq!(Err(Error::InvalidDigit('a')), lsp("1234a5", 2));
}

#}

4. 答案


# #![allow(unused_variables)]
#fn main() {
#[derive(Debug, PartialEq)]
pub enum Error {
   SpanTooLong,
   InvalidDigit(char),
}

pub fn lsp(string_digits: &str, span: usize) -> Result<u64, Error> {
   if span == 0 {
       return Ok(1);
   }

   if let Some(invalid) = string_digits.chars().find(|c| !c.is_digit(10)) {
       return Err(Error::InvalidDigit(invalid));
   }

   let products: Vec<u64> = string_digits
       .chars()
       .map(|c| c.to_digit(10).unwrap() as u64)
       .collect::<Vec<u64>>()
       .windows(span)
       .map(|w| w.into_iter().product())
       .collect();

   if let Some(&x) = products.iter().max() {
       Ok(x)
   } else {
       Err(Error::SpanTooLong)
   }
}

#}



填充/相关