|
| 1 | +{-#LANGUAGE RecordWildCards #-} |
| 2 | + |
| 3 | +importControl.Applicative (some) |
| 4 | +importControl.Monad (guard) |
| 5 | +importData.Map (Map) |
| 6 | +importqualifiedData.MapasM |
| 7 | +importSystem.Environment (getArgs) |
| 8 | +importText.Parsec (Parsec,char,digit,parse,spaces) |
| 9 | + |
| 10 | +dataClaim=MkClaim |
| 11 | +{claimId,leftEdge,topEdge,width,height::!Integer |
| 12 | +}deriving (Eq,Show) |
| 13 | + |
| 14 | +typeFabric=Map (Integer,Integer)Integer |
| 15 | +typeParser=ParsecString() |
| 16 | + |
| 17 | +main::IO() |
| 18 | +main=do |
| 19 | + args<- getArgs |
| 20 | +case argsof |
| 21 | +[]->putStrLn"Usage: ./appositum input.txt" |
| 22 | + (arg:_)->do |
| 23 | + f<-readFile arg |
| 24 | +let claims= getClaims$lines f |
| 25 | +let fabric= cut claims |
| 26 | +print$ noOverlap fabric claims |
| 27 | + |
| 28 | +cut:: [Claim]->Fabric |
| 29 | +cut= occurrences.concatMap coords |
| 30 | + |
| 31 | +overlap::Fabric->Integer |
| 32 | +overlap= count (>1) |
| 33 | + |
| 34 | +noOverlap::Fabric-> [Claim]->Integer |
| 35 | +noOverlap fabric getClaims=head$do |
| 36 | + claim<- getClaims |
| 37 | +let intersec=M.intersection fabric (cut [claim]) |
| 38 | + guard$all (==1) intersec |
| 39 | +pure$ claimId claim |
| 40 | + |
| 41 | +count::Foldablet=> (a->Bool)->ta->Integer |
| 42 | +count p=foldr f0where |
| 43 | + f x z=if p xthen z+1else z |
| 44 | + |
| 45 | +occurrences::Orda=> [a]->MapaInteger |
| 46 | +occurrences=M.fromListWith(+).map (\x-> (x,1)) |
| 47 | + |
| 48 | +coords::Claim-> [(Integer,Integer)] |
| 49 | +coordsMkClaim {..}=do |
| 50 | + x<- [leftEdge.. leftEdge+ width-1] |
| 51 | + y<- [topEdge.. topEdge+ height-1] |
| 52 | +pure (x, y) |
| 53 | + |
| 54 | +getClaims:: [String]-> [Claim] |
| 55 | +getClaims=map (justs. parse parseClaimmempty) |
| 56 | +where justs (Right x)= x |
| 57 | + |
| 58 | +parseClaim::ParserClaim |
| 59 | +parseClaim=do |
| 60 | + char'#' |
| 61 | + claimID<- integer |
| 62 | + symbolic'@' |
| 63 | + left<- integer |
| 64 | + symbolic',' |
| 65 | + top<- integer |
| 66 | + symbolic':' |
| 67 | + width<- integer |
| 68 | + char'x' |
| 69 | + height<- integer |
| 70 | +pure$MkClaim claimID left top width height |
| 71 | + |
| 72 | +integer::ParserInteger |
| 73 | +integer=read<$> some digit |
| 74 | + |
| 75 | +symbolic::Char->ParserChar |
| 76 | +symbolic c= spaces*> char c<* spaces |