例如: P(3) = 3, P(123) = 123 = 6, P(204) = 2*4 = 8 计算:P(1)+P(2)+P(3)+...+P(999)git
Rust:ruby
fn digits_multiply(mut n: u64) -> u64 { match n { 0 => 1, _ => { let mut m = 1; while n > 9 { //let b = n % 10; //m *= if b == 0 { 1 } else { b }; m *= std::cmp::max(1, n % 10); n /= 10; } m * n }, } } fn main() { let sum = (1..999+1).fold(0, |sum, i| sum + digits_multiply(i)); println!("result = {}", sum); }
Haskell函数
-- 求出整数的全部数字组成List 而后过滤,而后乘积 digitsMultiply n = product $ filter (>0) $ digits n where digits m = if m < 10 then [m] else m `mod` 10 : (digits $ m `div` 10) -- 另一种写法,直接用递归法,计算出一个整数的全部数字乘积 max 1 (n `mod` 10)排除0计算 digitsMultiply n = if n == 0 then 1 else if n < 10 then n else (max 1 $ n `mod` 10) * digitsMultiply (n `div` 10) -- 调用代码 main = do print $ sum $ map digitsMultiply [1..999] -- 第三种写法,一句代码: [Prelude] > sum . map ( product . filter (>0) . map (\x -> read [x] :: Int) . show ) $ [1..999] -- 97335 -- 左边为 curry 函数,右边 传入最终参数调用。 -- 第一步,先写出一个将数字转换成整数List的函数: Prelude> map (\x -> read [x] :: Int) . show $ 123 -- [1,2,3] -- 函数为: digits = map (\x -> read [x] :: Int) . show -- 或者2: digits :: Integer -> [Int] digits = map (read . return) . show -- 或者3: digits :: Integer -> [Int] digits = map (read . (:[])) . show -- 二、3两种写法须要声明函数原型,由于read须要声明转换类型。 -- 有了digits函数,就能够 在左边继续增长 filter 函数过滤掉0,而后是求乘积。 -- 增长map 求[1..999] 列表中每一项的数字乘积。 -- 最后一步增长sum求和便可。 -- List comprehension 写法: Prelude > sum [ y | n <- [1..999], y <- [product . filter (>0) . map (\x -> read [x] :: Int) . show $ n] ]
Rubycode
puts (1..999).map{|i| i.to_s.chars.map(&:to_i).select{|v| v>0}.inject(&:*) }.inject(&:+) 97335 => nil
或者用 reject(&:zero?)
来替换 select{|v| v>0}
更加简洁递归
2.2.2 :002 > (1..999).map{|i| i.to_s.chars.map(&:to_i).reject(&:zero?).inject(&:*) }.inject(&:+) => 97335
结果是97335,ruby和haskell解决数学问题很清晰。ip
julia语言,专为计算而生,看起来不比lisp容易,虽然julia自己语法并不复杂,但由于原生没有链式调用,因此阅读起来是很是吃力的。原型
julia> sum(map(y->prod(filter(x->x!=0, digits(y))), 1:999)) 97335
使用Lazy包:数学
julia> using Lazy INFO: Precompiling module Lazy... julia> @>> 1:999 map(x-> prod(filter(y->y!=0, digits(x)))) sum 97335
外部简化了一层,内部仍是跟包裹同样难读。 使用 |>
语法it
1:999 |> a -> map( b -> digits(b) |> c -> filter(d -> d > 0, c) |> prod, a) |> sum
稍微简化了一些,但由于缺乏Scala的默认下划线变量,致使lambda函数不断须要申明变量,看起来也很杂乱,若是后续Julia能够提供 _
变量占用符,那么会变得清晰不少: 下面这段不能运行。io
1:999 |> map( digits(_) |> filter( _ > 0, _) |> prod, _) |> sum
在julia语言完全解决链式调用前,还不适合用来解决数学问题。