Language detail: Haskell
Coverage: 99.32%
|
number of '+' ratings |
contribution for coverage |
Unsolved challenges
codes
π
(Nested
Flatten)
> 昔のメモにのこっていたコード。出典がわからないのだがなにかのpaperにあったコードだと思う。 コードの出典はわかりませんが計算方法は多分 「円周率の公式集(そのた・不明)」のページ http://www.pluto.ai.kyutech.ac.jp/plt/matumoto/pi_small/node14.html の下の方にある t[n] = n(2n-1)((5n+3)+t[n+1])/((3n+1)(3n+2)3) π[n] = 3 + t[1] π = lim π[n] というやつですね。 > 各桁の数のリストで出力 収束の関係上いつかは誤差で間違った数がでてくるんでしょうね (後の桁で10以上の数がでてきて全体としては正しい値に調整されると思いますが) その桁にたどりつく前に計算機資源が足りなくなるか。
疑似並行処理
(Nested
Flatten)
1 2 3 4 5 6 | import Data.Char
import Control.Concurrent
main = forkIO f >> g
where f = mapM_ (\x -> threadDelay 100000 >> putStr (show x)) [1..10]
g = mapM_ (\x -> threadDelay 100000 >> putChar x) ['A'..'J']
|
世界時計
(Nested
Flatten)
Time Zone の情報を取るのがすこしまわりくどいです MacOS X 10.5、ghc-6.10.1 ではうまくいっているようにみえますが、 summer timeの扱いがうまくいくかどうかは未確認です。 実行例 *Main> :main 現在の時刻は、2008年11月07日 18時03分09秒です。 グリニッジ標準時刻は、2008年11月07日 09時03分09秒です。 アメリカ・ロサンジェルスの時刻は、2008年11月07日 01時03分09秒です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | module Main where
import Data.Time
import System.Locale
import System.Posix.Env
import qualified System.IO.UTF8 as U
main :: IO ()
main = do hereTZ <- getCurrentTimeZone
tzenv <- getEnv "TZ"
setEnv "TZ" "America/Los_Angeles" True
laTZ <- getCurrentTimeZone
case tzenv of { Nothing -> unsetEnv "TZ"; Just tz -> setEnv "TZ" tz True }
ct <- getCurrentTime
mapM_ U.putStrLn
$ zipWith (formatTime defaultTimeLocale) [herefmt,utcfmt,lafmt]
$ flip map [hereTZ,utc,laTZ]
$ flip utcToLocalTime ct
herefmt = "現在の時刻は、%Y年%m月%d日 %H時%M分%S秒です。"
utcfmt = "グリニッジ標準時刻は、%Y年%m月%d日 %H時%M分%S秒です。"
lafmt = "アメリカ・ロサンジェルスの時刻は、%Y年%m月%d日 %H時%M分%S秒です。"
|
'('と')'の対応
(Nested
Flatten)
$ と where があれば括弧要らない感じです. タプル使えないのがちょっと嫌ですが.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import qualified Data.Char
openP = Data.Char.chr 40
closeP = Data.Char.chr 41
pNext = dropWhile $ \c -> c/=openP && c/=closeP
pHead = head . pNext
pTail = pNext . tail . pNext
parse :: String -> String
parse str = show result ++ "\n"
where
result = flip parse' 0 $ pNext str
parse' "" n = n == 0
parse' s n | hd == openP = parse' tl $ succ n
| n > 0 = parse' tl $ pred n
| otherwise = False
where
hd = pHead s
tl = pTail s
main = interact parse
|
漢数字で九九の表
(Nested
Flatten)
基本的な数字を作ってから・・・なので、目新しさはありません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | k = ["一","二","三","四","五","六","七","八","九"]
ku = " ":k
kl = "〇":k
main = putStrLn $ concat [str (x*y) | x <- [one..nine] ,y <- [one-one..nine]]
where
one = ten - nine
nine = length k
ten = length ku
str n
| n < one = "\n"
| otherwise = " " ++ ku!!u ++ kl!!l
where
(u,l) = divMod n ten
|
タブ区切りデータの処理
(Nested
Flatten)
あまり美しくないですが、基本に忠実に。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import System.Environment
import Data.List
q1 (x:xs) = x:sortBy (\a b -> compare (toNum a) (toNum b)) xs
where
toNum n = read (head n)::Int
q2 = map (\[i,l,f,a] -> [i,f,l,a])
q3 (x:xs) = x:map (\[i,l,f,a] -> [i,l,f,show $ 1+read a]) xs
main = do
args <- getArgs
contents <- if (not.null) args
then readFile $ head args
else getContents
let rec = map words $ lines contents
putStrLn $ shows $ q1 rec
putStrLn $ shows $ q2 rec
putStrLn $ shows $ q3 rec
where
shows list = unlines $ map (concat.intersperse "\t") list
|
π
(Nested
Flatten)
単純に円周率の数字がほしいだけならHaskellには最初から用意されています。
1 | main = print pi
|
すみません再投稿します
1 2 3 4 | import System.Environment
main = print . flip take (g (1,180,60,2)) . read . head =<< getArgs
g (q,r,t,i) = y : g (10*q*i*(2*i-1),10*u*(q*(5*i-2)+r-y*t),t*u,i+1)
where (u,y) = (3*(3*i+1)*(3*i+2),div (q*(27*i-12)+5*r) (5*t))
|
言語指定しわすれた Haskell です
タブ区切りデータの処理
(Nested
Flatten)
効率すこし改善版
1 2 3 4 5 6 7 8 9 10 11 12 | import Control.Arrow
import Data.Function
import Data.List
main :: IO ()
main = mapM_ (putStrLn . concat . intersperse "\t") . uncurry (++)
. (map (swap23 . words) *** sortBy (compare `on` readInt . head) . map (swap23inccol4 . words))
. splitAt 1 . filter (not . null) . lines =<< getContents
where swap23 (x:y:z:ws) = x:z:y:ws
swap23inccol4 (x:y:z:[w]) = x:z:y:[show (readInt w+1)]
readInt :: String -> Int
readInt = read
|
標準入力から標準出力へ $ runghc tsv.hs < tsv.data ID Forename Surname Age 0 Taro Suzuki 19 1 Hanako Sato 18
1 2 3 4 5 6 7 8 9 10 11 12 13 | import Control.Arrow
import Data.Function
import Data.List
main :: IO ()
main = putStr . unlines . map (concat . intersperse "\t") . uncurry (++)
. second (map inccol4 . sortBy (compare `on` readInt . head))
. splitAt 1 . map (swap23 . words)
. filter (not . null) . lines =<< getContents
where swap23 (x:y:z:ws) = x:z:y:ws
inccol4 (x:y:z:[w]) = x:y:z:[show (readInt w+1)]
readInt :: String -> Int
readInt = read
|
数値リストの圧縮
(Nested
Flatten)
1 2 3 4 5 6 7 8 9 10 | import List
compactNumberList xs = unfoldr f xs
f xs@(x:y:z:_) | x+z==2*y = Just (g (y-x) $ map fst as, map fst bs) where
(as,bs) = span (uncurry (==)) $ zip xs [x,y..]
f (x:xs) = Just ([x], xs)
f [] = Nothing
g step xs = [head xs, last xs] ++ if step == 1 then [] else [step]
|
1 2 3 4 5 6 7 8 9 10 | main = print $ f [1, 3, 4, 5, 6, 12, 13, 15, 20, 25, 26, 27]
f s@(a:b:c:xs) = let step = b-a in
if b+step == c then fAux (a,c,step) xs
else [a] : f (b:c:xs)
f s = map (:[]) s
fAux (start,stop,step) s@(x:xs)
| stop + step == x = fAux (start,x,step) xs
| otherwise = (if step == 1 then [start,stop] else [start,stop,step]) : f s
fAux _ s = f s
|
LL Golf Hole 9 - トラックバックを打つ
(Nested
Flatten)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | module Main where
import Data.Maybe
import Network.URI
import Network.HTTP
uriStr :: String
uriStr = "http://d.hatena.ne.jp/takano32/20080905"
bodyStr = urlEncodeVars
[("title","LL Golf Hole 9")
,("blog_name", "LL Golf Hole 9")
,("url","http://ja.doukaku.org/207/")
,("excerpt","trackback from LL Golf Hole 9 with Haskell.")]
req :: Request
req = Request
{ rqURI = fromJust $ parseURI uriStr
, rqMethod = POST
, rqHeaders = [Header HdrContentType "application/x-www-form-urlencoded"]
, rqBody = bodyStr
}
main :: IO ()
main = simpleHTTP req >>= print
|
lessの実装
(Nested
Flatten)
IOまみれですが、なんとか実装しました。 ライブラリを使えば楽勝と思いきや、必要な機能が無かったり、 画面サイズを超えるとエラーになったりと、意外と手間取り、 検索機能を入れる前に、力尽きてしまいました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | {-# LANGUAGE ForeignFunctionInterface #-}
--
-- ghc --make hless.hs -lncurses
--
-- need : hscurses-1.3
import System.IO
import Control.Exception
import System.Environment
import qualified UI.HSCurses.Curses as Curses
import qualified UI.HSCurses.CursesHelper as CursesH
import Foreign
import Foreign.C.Types
--
foreign import ccall unsafe "ncurses.h winsdelln"
winsdelln :: Curses.Window -> CInt -> IO CInt
deleteln :: Int -> IO CInt
deleteln n = winsdelln Curses.stdScr $ fromIntegral (-n)
insertln :: Int -> IO CInt
insertln n = winsdelln Curses.stdScr $ fromIntegral n
--
data File = File {
fhandle :: Handle,
list :: [Integer]
} deriving (Show)
data Info = Info {
file :: File,
top :: Int
} deriving (Show)
--
scanFile :: Handle -> IO [Integer]
scanFile fp = do
eof <- hIsEOF fp
if eof
then return []
else do
p <- hTell fp
l <- hGetLine fp
flist <- scanFile fp
return (p : flist)
showLine :: File -> Int -> IO String
showLine f n
| n >= (length $ list f) = do return "~"
| otherwise = do
hSeek (fhandle f) AbsoluteSeek $ (list f)!!n
line <- hGetLine $ fhandle f
return line
--
getW = do
(_,w) <- Curses.scrSize
return w
getH = do
(h,_) <- Curses.scrSize
return h
drawLine :: Info -> Int -> IO ()
drawLine info n = do
str <- showLine (file info) (n + (top info))
ss <- trim str
Curses.mvWAddStr Curses.stdScr n 0 ss
where
trim s = do
w <- getW
if (length s) >= w
then
return ((take (w-2) s) ++ "$") -- (x_x)
else
return s
redraw :: Info -> IO ()
redraw info = do
h <- getH
redraw' h
Curses.refresh
where
redraw' 0 = return ()
redraw' n = do
m <- getH
drawLine info (m-n)
redraw' (n-1)
--
moveDown :: Info -> IO Info
moveDown info
| (top info) >= len = return info
| otherwise = scrollUp
where
len = length $ list $ file info
next = info { top = (top info) + 1 }
scrollUp = do
h <- getH
CursesH.gotoTop
deleteln 1
Curses.move (h-1) 0
drawLine next (h-1)
Curses.refresh
return next
moveUp :: Info -> IO Info
moveUp info
| (top info) == 0 = return info
| otherwise = scrollDown
where
next = info { top = (top info) - 1 }
scrollDown = do
CursesH.gotoTop
insertln 1
drawLine next 0
Curses.refresh
return next
eventLoop :: Info -> IO Info
eventLoop info =
do
key <- Curses.getCh
case key of
Curses.KeyChar 'l' -> process $ return info
Curses.KeyChar 'q' -> return info
Curses.KeyChar 'n' -> process $ moveDown info
Curses.KeyChar 'p' -> process $ moveUp info
Curses.KeyUp -> process $ moveUp info
Curses.KeyDown -> process $ moveDown info
_ -> eventLoop info
where
process f = do
r <- f
eventLoop r
--
main = do
(fileName:_) <- getArgs
fp <- openFile fileName ReadMode
flist <- scanFile fp
let info = Info { file = File { fhandle = fp, list = flist}, top = 0}
runMain info `finally` CursesH.end
where
runMain info = do
CursesH.start
redraw info
eventLoop info
|
2^i * 3^j * 5^k なる整数
(Nested
Flatten)
next >>
有名なエラトステネスのふるいを変形して。Haskellはあんまりやったことがないから勝手が分かりませんが。
1 2 3 4 5 | sieve (x:xs) | divide235 x = x:sieve xs
| otherwise = sieve [a | a <- xs, a `mod` x /= 0]
where divide235 x = x `mod` 2 == 0 || x `mod` 3 == 0 || x `mod` 5 == 0
take 100 $ [1..6] ++ sieve [7..]
|
もりっとArrowで
1 2 3 4 5 6 7 8 9 10 11 12 13 | module Main where
import Control.Arrow
f = Left >>> f' 2 >>> f' 3 >>> f' 5 >>> const False ||| const True
where f' n = g n ||| Right
g n = loop ((snd &&& fst >>> app) &&& (snd >>> g'))
where g' f m | n > m = Right ()
| True = case m `divMod` n of (x,0) -> f x; _ -> Left m
main = runKleisli func [1..]
where func = arr (filter f) >>> arr (take 100) >>> Kleisli (mapM_ print)
|
Haskellらしく素直に無限リストで :)
1 2 3 4 5 6 7 8 9 10 | main :: IO ()
main = print $ take 100 hamming
hamming :: [Integer]
hamming = 1 : foldr1 (#) (zipWith map (map (*) [2,3,5]) (repeat hamming))
(#) :: Ord a => [a] -> [a] -> [a]
xxs@(x:xs) # yys@(y:ys) | x < y = x : xs # yys
| y < x = y : xxs # ys
| otherwise = x : xs # ys
|
ハミング数ですね。 anarchy golf の Hamming Numbers問題 http://golf.shinh.org/p.rb?Hamming+Numbers のときに投稿した golf用の富豪コードです。 30のx乗 ≡ 0 (mod x) となる x がハミング数に なることを使っています。(30 は 2,3,5 の最小公倍数) 富豪だから、け、計算量なんて気にしてないんだからね!
1 2 3 4 5 6 7 8 9 | main = do
n <- readLn
mapM_ print $ take n [x| x <- [1..], mod (30^x) x == 0]
{- anarchy golf に投稿したコードはこちら
main=readLn>>=mapM print.(`take`[x|x<-[1..],mod(30^x)x<1])
-}
|






nobsun
#8062()
[
Haskell
]
Rating0/0=0.00
Rating0/0=0.00-0+
[ reply ]