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
- What is this?: Here is a post with a large amount of details: https://programming.dev/post/6637268
- Where do I participate?: https://adventofcode.com/
- Is there a leaderboard for the community?: We have a programming.dev leaderboard with the info on how to join in this post: https://programming.dev/post/6631465
Haskell
Whee, linear algebra! Converting between numeric types is a bit annoying in Haskell, but I’m reasonably happy with this solution.
import Control.Monad import Data.Matrix qualified as M import Data.Maybe import Data.Ratio import Data.Vector qualified as V import Text.Parsec type C = (Int, Int) readInput :: String -> [(C, C, C)] readInput = either (error . show) id . parse (machine `sepBy` newline) "" where machine = (,,) <$> coords <*> coords <*> coords coords = (,) <$> (manyTill anyChar (string ": X") >> anyChar >> num) <*> (string ", Y" >> anyChar >> num) <* newline num = read <$> many1 digit presses :: (C, C, C) -> Maybe C presses ((ax, ay), (bx, by), (px, py)) = do let m = fromIntegral <$> M.fromLists [[ax, bx], [ay, by]] m' <- either (const Nothing) Just $ M.inverse m let [a, b] = M.toList $ m' * M.colVector (fromIntegral <$> V.fromList [px, py]) guard $ denominator a == 1 guard $ denominator b == 1 return (numerator a, numerator b) main = do input <- readInput <$> readFile "input13" mapM_ (print . sum . map (\(a, b) -> 3 * a + b) . mapMaybe presses) [ input, map (\(a, b, (px, py)) -> (a, b, (10000000000000 + px, 10000000000000 + py))) input ]