Day 9: Movie Theater

Megathread guidelines

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL

FAQ

you are viewing a single comment's thread
view the rest of the comments
[โ€“] 4 points 11 months ago* (last edited 11 months ago)

Haskell

This is pretty ugly. I got rather fed up after trying out various heuristics when the test case passed but actual data didn't.

import Control.Arrow  
import Data.Function  
import Data.Ix  
import Data.List  
import Data.Ord  

readInput :: String -> [(Int, Int)]  
readInput = map ((read *** (read . tail)) . break (== ',')) . lines  

pairs = concatMap (\(x : xs) -> map (x,) xs) . init . tails  

toRange ((a, b), (c, d)) = ((min a c, min b d), (max a c, max b d))  

onTiles loop rect = cornersInside && not crossingEdges  
  where  
    cornersInside =  
      let ((a, b), (c, d)) = rect  
       in inside (a, d) && inside (c, b)  
    verticalEdges = sortOn (Down . fst . fst) $ filter (uncurry ((==) `on` fst)) loop  
    inside (x, y) =  
      let intersecting ((a, b), (_, d)) = a <= x && inRange (min b d, max b d) y  
       in maybe False (uncurry ((>) `on` snd)) $ find intersecting verticalEdges  
    crossingEdges =  
      let ((a, b), (c, d)) = rect  
       in any (crossingLoop . toRange) $  
            [ ((a, b), (c, b)),  
              ((c, b), (c, d)),  
              ((c, d), (a, d)),  
              ((a, d), (a, b))  
            ]  
    crossingLoop ((a, b), (c, d))  
      | a == c = anyEdge (\((e, f), (g, h)) -> f == h && f > b && f < d && g > a && e < c)  
      | b == d = anyEdge (\((e, f), (g, h)) -> e == g && e > a && e < c && h > b && f < d)  
    anyEdge = flip any $ map toRange loop  

main = do  
  input <- readInput <$> readFile "input09"  
  let rects = pairs input  
      loop = zip (last input : input) input  
      go = print . maximum . map (rangeSize . toRange)  
  go rects  
  go $ filter (onTiles loop) rects  
  • source