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

  • Amy@piefed.blahaj.zone
    link
    fedilink
    English
    arrow-up
    4
    ·
    edit-2
    1 day 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