[haskell]
import HigherOrderFunctions
import Data.List.Split
import qualified Data.Set as Set
main :: IO ()
main = do
input ((Int, Int), (Int, Int))
parseLine s = ((xPos, xPos + width - 1), (yPos, yPos + height - 1)) where
startPos = words s !! 2
xPos = read $ splitOn "," startPos !! 0
yPos = read $ init $ splitOn "," startPos !! 1
lengthWidth = words s !! 3
width = read $ splitOn "x" lengthWidth !! 0
height = read $ splitOn "x" lengthWidth !! 1
expandBox :: ((Int, Int), (Int, Int)) -> [(Int, Int)]
expandBox (xs, ys) = [(x, y) | x 1) . expandBox . parseLine $ l
soln1 :: [String] -> Int
soln1 ls = length $ filter (\(k,v) -> v /= 1) $ reduceByKey (+) $ flatMap explodeLine ls
parseLineWithId :: String -> (Int, ((Int, Int), (Int, Int)))
parseLineWithId s = (read . tail $ words s !! 0, parseLine s)
explodeLineWithId :: String -> [((Int, Int), Int)]
explodeLineWithId l = keyMap (\x -> lineId) . expandBox $ box where
(lineId,box) = parseLineWithId l
soln2 :: [String] -> Int
soln2 ls = missingNum !! 0 where
boxesWithIds = collect $ flatMap explodeLineWithId ls
withTwoValues = filter (\(k,v) -> length v /= 1) boxesWithIds
overlapIds = unique . flatMap snd $ withTwoValues
missingNum = Set.toList $ Set.difference (Set.fromList [1..(length ls)]) (Set.fromList overlapIds)
$ time ./soln
124850
1097
real 0m1.932s
user 0m1.843s
sys 0m0.084s
I had to rewrite parts of HigherOrderFunctions to use Data.Set and Data.Map, so the majority of my time was spent on plumbing. But damn, once that's done, using these concepts feels so smooth.
Attached: 1517917941476.jpg (1137x1635, 301K)