Day 13: Claw Contraption

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

  • gentooer@programming.dev
    link
    fedilink
    English
    arrow-up
    3
    ·
    14 days ago

    Haskell, 14 ms. The hardest part was the parser today. I somehow thought that the buttons could have negative values in X or Y too, so it’s a bit overcomplicated.

    import Text.ParserCombinators.ReadP
    
    int, signedInt :: ReadP Int
    int = read <$> (many1 $ choice $ map char ['0' .. '9'])
    signedInt = ($) <$> choice [id <$ char '+', negate <$ char '-'] <*> int
    
    machine :: ReadP ((Int, Int), (Int, Int), (Int, Int))
    machine = do
        string "Button A: X"
        xa <- signedInt
        string ", Y"
        ya <- signedInt
        string "\nButton B: X"
        xb <- signedInt
        string ", Y"
        yb <- signedInt
        string "\nPrize: X="
        x0 <- int
        string ", Y="
        y0 <- int
        return ((xa, ya), (xb, yb), (x0, y0))
    
    machines :: ReadP [((Int, Int), (Int, Int), (Int, Int))]
    machines = sepBy machine (string "\n\n")
    
    calc :: ((Int, Int), (Int, Int), (Int, Int)) -> Maybe (Int, Int)
    calc ((ax, ay), (bx, by), (x0, y0)) = case
            ( (x0 * by - y0 * bx) `divMod` (ax * by - ay * bx)
            , (x0 * ay - y0 * ax) `divMod` (bx * ay - by * ax)
            ) of
        ((a, 0), (b, 0)) -> Just (a, b)
        _                -> Nothing
    
    enlarge :: (a, b, (Int, Int)) -> (a, b, (Int, Int))
    enlarge (u, v, (x0, y0)) = (u, v, (10000000000000 + x0, 10000000000000 + y0))
    
    solve :: [((Int, Int), (Int, Int), (Int, Int))] -> Int
    solve ts = sum
        [ 3 * a + b
        | Just (a, b) <- map calc ts
        ]
    
    main :: IO ()
    main = do
        ts <- fst . last . readP_to_S machines <$> getContents
        mapM_ (print . solve) [ts, map enlarge ts]
    
    • CameronDev@programming.devOPM
      link
      fedilink
      arrow-up
      3
      ·
      13 days ago

      I wasted hours on the parsing, because my regex ([0-9]*) was giving me empty strings. Made me feel very dumb when I worked it out