定義P(n)爲正整數n的全部非0數字的乘積,計算P(1),P(2)...P(999)的和

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

相關文章
相關標籤/搜索