エンジニアのソフトウェア的愛情

または私は如何にして心配するのを止めてプログラムを・愛する・ようになったか

「40 - 32 / 2 = 4!」Haskell篇

前回のつづき。どうにか動くものが書けました。

前回同様、ここのコードはGitHubにも登録してあります

ぢゃ、Haskellでは?

前回の最後で「書いているうちに、わけわかんなくなりました。Haskell篇は後日ということで…」と書きましたが、こんなコードではわけわかんなくなるのもさもありなんという感じです。


だれか整理してくれるひといませんか?(爆)


同じく、コマンドラインaの最大値を指定するようになっています。

import Text.Printf
import System

factorials  = scanl (*) 1 [1..]
factorial n = factorials !! n

values = filter (\(a, b, c, n) -> (((a - c) `mod` c) == 0) && (((a - b) `div` c) == n))
                [ (a, b, c, n) | a         <- [1..],
                                 (n, b, c) <- [ (n, b, c) | n      <- takeWhile (\x -> factorial x < a) [0..],
                                                            (b, c) <- takeWhile (\(x, _) -> x < a) [ ((a - factorial n) * c, c) | c <- [2..]]
                                              ]
                ]

print_abcn (a, b, c, n) = printf "(%d - %d) / %d = %d\n %d - %d  / %d = %d! = %d\n\n" a b c n a b c n (factorial n)

main = do
  args <- getArgs
  let max  = (read $ head args)::Int
  sequence_ $ map print_abcn $ takeWhile (\(a, _, _, _) -> a <= max) values

集計

計測条件は前回と一緒、aが1000以下のばあいの探索の結果です。

1回目 2回目 3回目 平均 高速化
1 40.255 40.254 40.242 40.250 1
2 34.817 34.801 34.803 34.807 1.15
3 8.570 8.661 8.667 8.633 4.66
4 4.502 4.518 4.545 4.188 9.61
5 0.022 0.022 0.022 0.022 1830
Haskell 0.036 0.036 0.037 0.036 1118