Haskell

メモリを節約しない力業

格子点の列挙です。候補となる格子点の一覧を作成してから、各格子点の距離を求めて距離の小さい順にソートしています。 import Data.List import Text.Printf -- x = sqrt(1000)/2 -- pointMax = sqrt(x^2 + x^2) -- = sqrt(500) -- ≒ 22.36 pointMax = 22 …

九九

九九の表示です。printfでフォーマット。 import Text.Printf main = do putStrLn $ unlines $ kuku kuku = concatMap (\n->ku n) [1..9] ku :: Int -> [String] ku n = map (\m->printf "%d * %d = %2d" n m (n * m)) [1..9]

基数変換

逆転したビット列です。2進数にしてreverseして10進数に戻しています。 import Data.Char import Numeric main = do print $ rbits 4 print $ rbits 5 rbits :: Int -> [Int] rbits n = map (\m -> readBin $ reverse $ padding0 n (toBin m)) $ take (2 ^ n…

重複削除

ずいぶんとサボってしまいました。重複する要素を取り除くです。 main = print $ onlyList [3, 1, 4, 1, 5, 9, 2, 6, 5] onlyList :: [Int] -> [Int] onlyList [] = [] onlyList (x:xs) = (if elem x xs then [] else [x]) ++ onlyList (filter (/= x) xs)

ピラミッド

与えられた文字列でピラミッドです。id:MAS3:20080210#p1の続編。 import Data.List main = do putStrLn $ pyramid "hoge" putStrLn $ pyramid "abracadabra" pyramid :: String -> String pyramid xs = pyramid' 0 xs pyramid' :: Int -> String -> String …

先頭から順番に処理

隣り合う二項の差です。 main = do print $ diff [3, 1, 4, 1, 5, 9, 2, 6, 5] diff :: [Int] -> [Int] diff [] = [] diff (_:[]) = [] diff (x:xs) = (head xs - x) : (diff xs)

printfは便利

ビンゴの結果を整形表示です。乱数の扱いは難しいで書いた重複無し乱数の続き。 import Data.List import System.Random import Text.Printf line = 10 main = bingo(30) >>= putStrLn >> bingo(35) >>= putStrLn bingo :: Int -> IO String bingo n = do xs …

乱数の扱いは難しい

重複無し乱数です。乱数に大苦戦。与えられたリストからランダムに一つ選んで、選んだもの以外のリストからさらにランダムに一つ選んで……、というやり方です。 import System.Random main = bingo(10) >>= print bingo :: Int -> IO [Int] bingo n = do g <-…

直積

全ての組み合わせです。私が書いたのはこれ。 list = [[1, 2, 3, 4], [7, 8, 9]] list2 = [[0, 1], [2, 3], [4, 5]] main = do print $ crossProduct list print $ crossProduct list2 crossProduct :: [[a]] -> [[a]] crossProduct [] = [] crossProduct (x…

変数名1文字というのに慣れない

与えられた数字のケタ数です。割と簡単。 nums = [2469, 600, 1] main = do print $ map keta nums keta :: Int -> (Int, Int) keta n = let s = show n l = length s in (l, 10 ^ (l - 1)) タイトルに書いた通りなのですが、変数名を1文字にするというのに…

関数を返す関数

n日後を返す関数を返す関数です。日付操作があんまり分かっていません。 import Data.Time time = UTCTime (fromGregorian 2007 7 20) (timeOfDayToTime $ TimeOfDay 20 11 42) main = do putStrLn $ show $ time putStrLn $ show $ fiveDaysLater time five…

逆順

リストを逆順に表示です。 main = do putStr $ unlines $ map show $ reverse [1, 2, 3, 4, 5] reverseを使わないのであればこれ。 main = do putStr $ unlines $ map show $ rev [1, 2, 3, 4, 5] rev :: [a] -> [a] rev [] = [] rev (x:xs) = rev(xs) ++ [x]

上手く書けなかった

議席数をドント方式で動くには動くというだけ。 import List type PartyNumber = Int numberOfSeat = 100 numberOfVotes = [123, 4, 56, 78] main = do print $ result $ numberOfWinners $ (winners numberOfSeat) $ concat $ markedDhondtTable $ dhondtTa…

日付処理サンプル

練習がてらいくつか書いてみました。 -- 現在時刻の取得(UTC) import Data.Time main = do t <- getCurrentTime putStr $ show t -- 現在時刻の取得 import Data.Time main = do t <- getCurrentTime tz <- getCurrentTimeZone putStr $ show $ utcToLocalTi…

モジュールのインポートで苦戦

日付処理を試そうとこんなプログラムを書きました。 import Data.Time main = do putStr $ show $ fromGregorian 2008 1 2 コンパイルしたらこんな結果。 >ghc -W fromGregorian.hs fromGregorian.o(.text+0xbe):fake: undefined reference to `timezm1zi1zi…

リスト内包表記で書きました

ダブル完全数です。この前はリスト内包表記のことをすっかり忘れていましたが、今回は覚えていましたよ。 main = do print $ [x | x <- [1..10000], (x * 2) == sumOfAliquots(x)] sumOfAliquots :: Int -> Int sumOfAliquots n = sum $ aliquots n where al…

最初の一歩

社内発表用に作成したものに少し手を入れたものを公開しました。Haskell最初の一歩。書いてある内容は少なくて、型もモナドも参照透過性も出てきません。再帰とリストと遅延評価についてそれぞれちょっとだけ出てくるだけです。何らかの言語でプログラムを書…

iterate

アルファベットの繰り上がりです。ZZ→AAAに対応したかったのですが良い方法が考えられませんでした。 import Char import List main = putStr $ concat $ List.intersperse ", " $ take 100 $ map toAlphaStr [1..] toAlphaStr :: Int -> String toAlphaStr …

型で失敗

アレイのuniqです。 ar = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9] main = print $ uniq ar uniq :: [Int] -> [Int] uniq [] = [] uniq (x:xs) = x : (uniq $ filter (/= x) xs) 先頭から一つ取り出して、取り出したものと同じ数字を外すというやりか…

リスト内包表記を忘れていた

倍数になる13進数に挑戦。最初に書いたのはこれです。 main = print $ head $ filter (\n -> (radix_13_10 n `mod` n) == 0) [10..] radix_13_10 :: Int -> Int radix_13_10 0 = 0 radix_13_10 n = (radix_13_10 (n `div` 10)) * 13 + (n `mod` 10) できた、…

条件を満たす行を取り除く

今回は条件を満たす行を取り除くに挑戦。最初に書いたのはこれでした。 main = do cs <- getContents putStr $ unlines $ filter match $ lines cs where match :: String -> Bool match [] = True match s = if head s == '#' then False else True 投稿さ…

サンプルで練習

ふつうのHaskellプログラミングは最後の方は眺めただけで一旦終了。いくつかサンプルのプログラムを書いて練習しようと思います。今回の題材はピラミッドを作る。こんなのを書きました。 import System defaultLevel = 4 main = do args <- getArgs do let l…

全体の流れを追うだけ

12.3章からはソースコードを見ながら処理全体の流れを追っていきます。12.4章まで読んで、何となく処理の流れを見てみましたというところ。

第3部に突入

第3部は「実戦Haskellプログラミング」というタイトルで、Webアプリケーションの作成を扱っています。作るのはWiki。まずはWikiの説明、CGIの説明とありましたが、どちらも知っていることなのでこの部分は一通り目を通すだけ。

IOモナド

難しいと言われているIOモナドです。確かに説明の「まだ入出力を実行していない現実世界」とか「入出力を実行した後の世界」なんて言われてもよく分かりません。実行順序を指定したい時と、副作用を扱いたい時に使うものという理解で、それ以上は深追いしな…

リストモナド

リストの各要素に関数fを適用するというのが>>=で書けるようになります。中身ははconcatMap。

モナド

名前は聞いたことがあるけどどんなものかがまったく分からないモナドです。モナドの条件として(>>=)とreturnの二つを実装する必要があり、これがモナド則を満たしている必要があるとのこと。具体的に三つのモナド則が書いてあるのですが、いきなり見せられて…

モジュールのインポート

importでモジュールをインポートできます。 import Text.Regex 特定のエンティティだけをインポートすることもできます。 import Text.Regex(mkRegex, matchRegex) 反対に特定のエンティティを除いてインポートすることもできます。この場合はhidingを付けま…

モジュール

moduleでモジュールを定義することができます。というのは分かったのですけど、具体的にどう書けば良いのかや、モジュールを定義したファイルをどこに配置するのかというのが分かっていないので、自分でモジュールを書くというのはできないです。12章がWiki…

演習問題

9章の演習問題。自力でできました。 import List data Line = Line { number ::Int, string :: String } deriving Show ln1 = Line 10 "L10" ln2 = Line {number = 20, string = "L20"} lns = [ln1, ln2, Line {number = 15, string = "puts"}] main = do pr…