Day 14: Restroom Redoubt

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

  • VegOwOtenks@lemmy.world
    link
    fedilink
    English
    arrow-up
    2
    ·
    13 days ago

    Haskell

    I solved part two interactively, I’m not very happy about it

    Reveal Code
    import Control.Arrow
    import Data.Bifunctor hiding (first, second)
    import Control.Monad
    
    import qualified Data.List as List
    import qualified Data.Set as Set
    import qualified Data.Map as Map
    import qualified Data.Maybe as Maybe
    
    parse :: String -> [((Int, Int), (Int, Int))]
    parse = map (break (== ' ') >>> second (drop 1) >>> join bimap (drop 2) >>> join bimap (break (== ',')) >>> join bimap (second (drop 1)) >>> join bimap (join bimap read)) . filter (/= "") . lines
    
    moveRobot ((px, py), (vx, vy)) t = (px + t * vx, py + t * vy)
    
    constrainCoordinates (mx, my) (px, py) = (px `mod` mx, py `mod` my)
    
    coordinateConstraints = (101, 103)
    
    robotQuadrant (mx, my) (px, py)
            | px > middleX && py < middleY = Just 1 -- upper right
            | px > middleX && py > middleY = Just 2 -- lower right
            | px < middleX && py > middleY = Just 3 -- lower left
            | px < middleX && py < middleY = Just 4 -- upper left
            | otherwise = Nothing
            where
                    middleX = (mx `div` 2)
                    middleY = (my `div` 2)
    
    countQuadrants (q1, q2, q3, q4) 1 = (succ q1, q2, q3, q4)
    countQuadrants (q1, q2, q3, q4) 2 = (q1, succ q2, q3, q4)
    countQuadrants (q1, q2, q3, q4) 3 = (q1, q2, succ q3, q4)
    countQuadrants (q1, q2, q3, q4) 4 = (q1, q2, q3, succ q4)
    
    part1 = map (flip moveRobot 100 >>> constrainCoordinates coordinateConstraints)
            >>> map (robotQuadrant coordinateConstraints)
            >>> Maybe.catMaybes
            >>> foldl (countQuadrants) (0, 0, 0, 0)
            >>> \ (a, b, c, d) -> a * b * c * d
    
    showMaybe (Just i) = head . show $ i
    showMaybe Nothing  = ' '
    
    buildRobotString robotMap = [ [ showMaybe (robotMap Map.!? (x, y))  | x <- [0..fst coordinateConstraints] ] | y <- [0..snd coordinateConstraints]]
    
    part2 rs t = map (flip moveRobot t >>> constrainCoordinates coordinateConstraints)
            >>> flip zip (repeat 1)
            >>> Map.fromListWith (+)
            >>> buildRobotString
            $ rs
    
    showConstellation (i, s) = do
            putStrLn (replicate 49 '#' ++ show i ++ replicate 49 '#')
            putStrLn $ s
    
    main = do
            f <- getContents
            let i = parse f
            print $ part1 i
    
            let constellations = map (id &&& (part2 i >>> List.intercalate "\n")) . filter ((== 86) . (`mod` 103)) $ [0..1000000]
            mapM_ showConstellation constellations
            print 7502