研究室のメンバーが Haskell でリストをワンパスで2分割するプログラムを書いていたので便乗.
halfSplit l = let (len, ret) = halfSplit' (div len 2) l in ret where halfSplit' _ [] = (0, ([],[])) halfSplit' n (x:xs)= let (len, ps) = halfSplit' (n-1) xs in (len + 1, if n > 0 then (x:fst ps, snd ps) else (fst ps, x:snd ps)) halfSplit2 l = let (len, ret) = halfSplit' (div len 2) l in ret where halfSplit' _ [] = (0, ([],[])) halfSplit' n (xxs@(x:xs))= let (len, ps) = halfSplit' (n-1) xs in (len + 1, if n > 0 then (x:fst ps, snd ps) else ([], xxs))
halfSplit だとリストの後ろ半分も再構成しているが,halfSplit2 のようにすると後ろ半分の再構成がない分簡約ステップ数が減る.実際,Hugs で :set +s して簡約数とかを見てみると,
Main> halfSplit [1..100] (4619 reductions, 8790 cells) Main> halfSplit2 [1..100] (3832 reductions, 7950 cells)
のようにそれなりに差が出る.
- Newer: ことはじめ