鍋あり谷あり

テーマを決めずに適当に書いています。

初めての Haskell の続きその2

二分探索を書いてみた。

import System
import Numeric

bisearch f e (x,y) | 0 == f x     = (x,x)
                   | 0 == f y     = (y,y)
                   | delta < e    = (x,y)
                   | sf x == sf y = error $ "sign . f x == sign . f y" ++ (show (x,y))
                   | sf x /= sf c = bisearch f e (x,c)
                   | sf y /= sf c = bisearch f e (c,y)
                   | True         = error $ "fail:" ++ show (x,y)
                   where 
                     delta = abs ( y - x )
                     c = (x+y)/2
                     sf = sign . f
                     sign x | x < 0 = -1
                            | 0 < x = 1
                            | True  = 0

bis f a = bisearch f (a!!0) ( (a!!1), (a!!2) )

main = test $ ( bis (\x -> 4**x-32) )
 where 
    test f = getArgs >>= putStr . show . f . argToNum
    argToNum = map  $ fst . head . readDec

ずいぶん長くなってしまった。日記のソースは大量の &nbsp; のために、もっともっと大変なことになっている。
それはともかく。
この程度なら、C言語ruby で書いているのと大差ない。違いは、スタックオーバーフローを気にせずに再帰呼び出しができるという点だけだ。

それと。おとといの続き。
http://d.hatena.ne.jp/KimuraShinichi/20050327/1111919561
からトラックバックを受けたので(ありがとうございます>id:KimuraShinichi さん)、既約分数クイズの素朴なバージョンも書いてみた:

import System
import Numeric

irrs x | x==0 = []
       | True = irrs (x-1) ++ [ (n,x) | n<-[0..x], not $ isRed (n,x) ]
       where
         isRed(n,x) = any (f (n,x)) $ irrs (x-1)
         f (n0,d0) (n1,d1) = n0*d1 == n1*d0
showFrac (n,d) = show n ++ "/" ++ show d
main = test $ \x -> map showFrac $ irrs.head $ x
  where 
    test f = getArgs >>= putStr . show . f . argToNum
    argToNum = map  $ fst . head . readDec

id:KimuraShinichi さんに合わせて、"1/2" のように出力するようにした。
それはともかく。gcd を使わないで素朴に書くとこんな感じだと思う。

それと。さんざん書いておいてこんなことを言うのも何だが。
「$」って何だろう??