定义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语言完全解决链式调用前,还不适合用来解决数学问题。

相关文章
相关标签/搜索