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
You are viewing a single thread.
View all comments 4 points
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
]