2008年05月12日

[Haskell] もう一つの数学パズル

  
問題
4桁の数値を順序を逆転させた数値(例えば、5432の場合は2345が逆転させた数値)で割ったときに、割り切れる4桁の数を求めよ。
(つまり、5432 / 2345 が割り切れればよい)
ただし、商が1のものや、割る数が4桁でないものは除外する。

この問題をHaskellで解いてみる。

import System
import Data.List

main = do print $ workout [1000..9999]

workout :: [Integer] -> [(Integer,Integer)]
workout nums = filter (\(a,b) -> (a /= b) && (b >= 1000) && (a `mod` b == 0)) maketuplelist
where
maketuplelist = zip nums ( map revnum nums )
revnum = (read :: String -> Integer) . reverse . show


別の方法も考えてみる。
今度は、タプルを使わないようにしてみた。

main = mapM_ print [n | n <- [1000..9999], cond n]

cond n = (n `mod` r == 0) && (n /= r) && (r >= 1000)
where
r = read $ reverse $ show n

ただ、ここで疑問。
r は、condの条件式の中で、3回も出てくるが、3回計算されるのだろうか?


この記事へのコメント
解いてみますた。

main = mapM_ print [n | n <- [1000..9999], cond n]

cond x | y < 1000 = False
    | x == y  = False
    | otherwise = x `mod` y == 0
 where
  y = read . reverse . show $ x

> r は、condの条件式の中で、3回も出てくるが、3回計算されるのだろうか?

処理系次第だと思いますが、まともなものなら、2回目以降はキャッシュされた値が使われると期待していいと思います。
Posted by nsharp at 2008年05月13日 08:35
nsharp さん。
いつもありがとうございます。
そうか、ガードを使えるんだ。

まともな処理系なら、2回目以降はキャッシュされるんですね。
安心しました(笑).


Posted by Gushwell at 2008年05月13日 21:29
 

この記事へのトラックバックURL

http://trackback.blogsys.jp/livedoor/gushwell/51508876
この記事へのトラックバック
問題 4桁の数値を順序を逆転させた数値(例えば、5432の場合は2345が逆転させた数値)で割ったときに、割り切れる4桁の数を求めよ。 (つまり、5432 / 2345 が割り切れればよい) ただし、商が1のものや、割る数が4桁でないものは除外する。 窓際プログラマーの独り言 -C#の
[コーディング]またまた、パズルが面白そうだったのでC#で書いてみた【NAL-6295の舌先三寸】at 2008年06月13日 11:50