二分探索を書いてみた。
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
ずいぶん長くなってしまった。日記のソースは大量の のために、もっともっと大変なことになっている。
それはともかく。
この程度なら、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 を使わないで素朴に書くとこんな感じだと思う。
それと。さんざん書いておいてこんなことを言うのも何だが。
「$」って何だろう??