Skip to content

Instantly share code, notes, and snippets.

@na2hiro
Last active August 29, 2015 14:01
Show Gist options
  • Save na2hiro/48de6bf7d07a1c519090 to your computer and use it in GitHub Desktop.
Save na2hiro/48de6bf7d07a1c519090 to your computer and use it in GitHub Desktop.
チケットゴブル問題 当選しました https://codeiq.jp/ace/yuki_hiroshi/q863 DPしていません,分割したら総当りで終わりました.
import Data.List.Split(splitOn)
import Data.List(sort, tails, maximumBy)
type Date = (Int, Int)
type Ticket = (Date, Date, String)
parse :: String->Ticket
parse s = ((m1,d1), (m2,d2), name)
where [name, dates] = words s
[[m1,d1], [m2,d2]] = map(map read.splitOn "/")$ splitOn "-" dates
main = do
file <- readFile "tickets.txt"
let tickets = sort$ map (parse.init)$ lines file
let res = map solve$ groupRange tickets
let r = sort$map(\(_,_,n)->n)$ concat$ res
print$ (show$ length r) ++' ': unwords r
-- 日付がオーバーラップしているものどうしグループ化する
groupRange :: [Ticket]->[[Ticket]]
groupRange [] = []
groupRange xs = let (xs', remain) = spanRange xs in xs':groupRange remain
-- 日付がオーバーラップしていなかったら切り分ける
spanRange :: [Ticket]->([Ticket], [Ticket])
spanRange [] = ([], [])
spanRange (x@(fr,t,n):xs)= let (ys,zs) = f fr t xs in (x:ys,zs)
where f _ _ [] = ([], [])
f from to xs@(x@(fr, t, _):xs') | to<fr = ([], xs)
| otherwise = let (ys,zs) = f (min from fr) (max to t) xs' in (x:ys, zs)
-- 組み合わせ列挙
search :: [Ticket] -> [[Ticket]]
search [] = [[]]
search xs = do
(hd@(_, hdend, _):tl) <- tails xs
rest<-search$ dropWhile(\(start, _, _)->start<=hdend) tl -- 直前の終わり<次の始まり になるまで捨てる
return (hd:rest)
-- 最大のものを取り出す
solve :: [Ticket]->[Ticket]
solve ts = snd$maximumBy(\a b->fst a`compare` fst b)$map(\x->(length x, x))$ search ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment