Created
July 7, 2015 04:35
-
-
Save mather/d52259c7afe7a140b4f7 to your computer and use it in GitHub Desktop.
CodeIQ問題のHaskell解答 ref: http://qiita.com/mather314/items/8a9b2ff8b3b143950320
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Data.List | |
main = do | |
l <- fmap toInt $ getLine -- 標準入力からLを読み込む | |
n <- fmap toInt $ getLine -- 標準入力からNを読み込む(使わない | |
bars <- fmap (fmap toInt . lines) $ getContents -- 残りのリストを取得 | |
print (sum $ fmap (findTripleSum l) $ tails bars) -- tails で部分リストを順番に調べる | |
-- Int化 | |
toInt :: [Char] -> Int | |
toInt xs = read xs :: Int | |
-- リストの先頭をピックアップして、 和がL-xになる組み合わせを後方のリストから探す | |
findTripleSum :: Int -> [Int] -> Int | |
findTripleSum _ [] = 0 | |
findTripleSum _ (_:[]) = 0 | |
findTripleSum i (x:xs) = sum $ fmap (findDoubleSum (i-x)) $ tails xs | |
-- リストの先頭をピックアップして、L-x-yに等しい物を探す | |
findDoubleSum :: Int -> [Int] -> Int | |
findDoubleSum _ [] = 0 | |
findDoubleSum i (x:xs) = if elem (i-x) xs then 1 else 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Prelude> import Data.List | |
Prelude Data.List> tails [1,2,3] | |
[[1,2,3],[2,3],[3],[]] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Data.List | |
main :: IO () | |
main = do | |
l <- fmap toInt $ getLine | |
n <- fmap toInt $ getLine | |
sortedBars <- fmap (sort . fmap toInt . lines) $ getContents -- ソートしておく | |
print (countFixedLengthTripleBars l sortedBars) | |
toInt :: [Char] -> Int | |
toInt xs = read xs :: Int | |
-- tailsで部分リストを作って処理して、結果をsum | |
countFixedLengthTripleBars :: Int -> [Int] -> Int | |
countFixedLengthTripleBars length = sum . fmap (countTripleSum length) . tails | |
-- 先頭の値 x を使って、残りのリストを(L-x)/2を基準に分割して走査する | |
countTripleSum :: Int -> [Int] -> Int | |
countTripleSum _ [] = 0 | |
countTripleSum l (x:xs) = countDoubleSum 0 s (filter (< h) xs) (reverse $ filter (>= h) xs) -- 大きい方のリストは reverse しておく | |
where s = l - x | |
h = ceiling ((fromIntegral s)/2) | |
-- s (= L-x) に一致するペアを大小のリストを走査しながら探す | |
-- countで見つけた数を更新して末尾再帰にする | |
countDoubleSum :: Int -> Int -> [Int] -> [Int] -> Int | |
countDoubleSum count _ [] _ = count | |
countDoubleSum count _ _ [] = count | |
countDoubleSum count s (low:lows) (high:highs) | |
| sum == s = countDoubleSum (count+1) s lows highs | |
| sum < s = countDoubleSum count s lows (high:highs) | |
| sum > s = countDoubleSum count s (low:lows) highs | |
where sum = low + high |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
inputs = STDIN.read.lines.map{|l| l.chomp.to_i } | |
L = inputs.shift | |
N = inputs.shift | |
D = inputs.sort # ソートしておく | |
count = 0 | |
(0..(N-2)).each do |i| | |
remain = L - D[i] | |
# カーソルの初期位置 | |
low_cursor = i + 1 | |
high_cursor = N - 1 | |
# カーソルが中央で合流するまで | |
while low_cursor < high_cursor do | |
s = D[low_cursor] + D[high_cursor] | |
if remain == s | |
count += 1 | |
low_cursor += 1 | |
high_cursor -= 1 | |
elsif remain > s | |
low_cursor += 1 | |
else | |
high_cursor -= 1 | |
end | |
end | |
end | |
puts count |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment