例如: 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語言完全解決鏈式調用前,還不適合用來解決數學問題。