haskell.g.hatena.ne.jp/horaguchi

2008-09-20

夏目漱石の「こころ」を行単位でシャッフルしたい 02:49 はてなブックマーク - 夏目漱石の「こころ」を行単位でシャッフルしたい - haskell.g.hatena.ne.jp/horaguchi

検索すると 乱数/シャッフル - isobeの技術日誌 という記事が見つかりました。

ほとんどこれで動きそうです。

import Data.List
import Random

shuffle :: StdGen -> [a] -> [a]
shuffle g list = snd $ unzip $ sortBy compareFst $ zip (randoms g :: [Int]) list
  where
    compareFst x y = compare (fst x) (fst y)

というコードがあり、

(追々記)import Data.Ordすると (comparing fst) と書けてさらにお手軽。

を参考にすると、

import Data.List
import Data.Ord
import Random

shuffle :: StdGen -> [a] -> [a]
shuffle g list = snd $ unzip $ sortBy (comparing fst) $ zip (randoms g :: [Int]) list

で動きました。これを関数合成

(.) :: (b -> c) -> (a -> b) -> a -> c

を使って弄ると、

import Data.List
import Data.Ord
import Random

shuffle g = snd . unzip . sortBy (comparing fst) . zip (randoms g :: [Int])

変数が減りました。これをファイルに保存(shuffle.hs)してから、コマンドラインで

ghci shuffle.hs

として GHCi を起動するか、GHCi を起動した後に

Prelude>:l shuffle.hs

のように、:load (:l は短縮記法)でロードすると GHCi でテストができるようです。

GHCi は :quit(:q)で終了することができて、:type(:t)で型を見ることもできるようです。

また、GHCi のコマンドの一覧は :help(:?)で確認できます。


どんな関数があるかは、no title を見ると分かりそうです。


shuffle 関数の実行は、同じ記事を参考に

*Main> g <- newStdGen
*Main> shuffle g [1..10]

で動きました。同じ記事の上の方にある、>>= (bind)を使って書くと、

*Main> newStdGen >>= return . flip shuffle [1..10]

でも動きました。

(>>=) :: (Monad m) => m a -> (a -> m b) -> m b

return :: (Monad m) => a -> m a

flip :: (a -> b -> c) -> b -> a -> c

二項演算子 >>= の右側が (a -> m b) にあたるようなので、

return と flip を使って、引数を1つ取って m a を返す関数(a -> m a)にしたので動いたんだと思います。


次に、図書カード:こころ にある 773_ruby_5968.zip をダウンロードして解凍し、kokoro.txt を shuffle.hs と同じところに置いておきます。

標準入力から食わすのが簡単そうなので、さっきの shuffle.hs に putShuffleLines と main 部分を追加します。

import Data.List
import Data.Ord
import Random

shuffle g = snd . unzip . sortBy (comparing fst) . zip (randoms g :: [Int])

putShuffleLines g = putStr . unlines . shuffle g . lines

main = do g <- newStdGen
          s <- getContents
          putShuffleLines g s

この main も bind >>= を使って一行で書こうとしましたが、どうするのかまだよくわかりません。

とりあえず GHC でコンパイルをして、パイプで食わすとイケます。

ghc shuffle.hs
type kokoro.txt | main

Windows なら type、Unix なら cat を使うようです。

JeanJean2012/01/08 14:05At last! Someitnhg clear I can understand. Thanks!

jabnkbnujabnkbnu2012/01/09 03:13RCvJIg <a href="http://pppxvpcvpbav.com/">pppxvpcvpbav</a>

lziowzglzxlziowzglzx2012/01/11 01:22rqhDWP <a href="http://sluaxacqklfy.com/">sluaxacqklfy</a>

iiokfdziiokfdz2012/01/14 02:47IzLoj1 , [url=http://gcrfdqmsqqka.com/]gcrfdqmsqqka[/url], [link=http://jpgrevmxrgsf.com/]jpgrevmxrgsf[/link], http://icjqoiuemhbe.com/

トラックバック - http://haskell.g.hatena.ne.jp/horaguchi/20080920