aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Dessaux2024-12-16 22:26:23 +0100
committerJulien Dessaux2024-12-16 22:26:23 +0100
commit9ed8dc9af26b19716616246250553df3ffdf5d37 (patch)
tree4abf1dc0df1948af80f3afc9cd3e724501a7a487
parent2024-12 in haskell (diff)
downloadadvent-of-code-9ed8dc9af26b19716616246250553df3ffdf5d37.tar.gz
advent-of-code-9ed8dc9af26b19716616246250553df3ffdf5d37.tar.bz2
advent-of-code-9ed8dc9af26b19716616246250553df3ffdf5d37.zip
2024-13 in haskell
-rw-r--r--2024/13-Claw_Contraption/example15
-rw-r--r--2024/13-Claw_Contraption/first.hs63
-rw-r--r--2024/13-Claw_Contraption/input1279
-rw-r--r--2024/13-Claw_Contraption/second.hs58
4 files changed, 1415 insertions, 0 deletions
diff --git a/2024/13-Claw_Contraption/example b/2024/13-Claw_Contraption/example
new file mode 100644
index 0000000..912f482
--- /dev/null
+++ b/2024/13-Claw_Contraption/example
@@ -0,0 +1,15 @@
+Button A: X+94, Y+34
+Button B: X+22, Y+67
+Prize: X=8400, Y=5400
+
+Button A: X+26, Y+66
+Button B: X+67, Y+21
+Prize: X=12748, Y=12176
+
+Button A: X+17, Y+86
+Button B: X+84, Y+37
+Prize: X=7870, Y=6450
+
+Button A: X+69, Y+23
+Button B: X+27, Y+71
+Prize: X=18641, Y=10279
diff --git a/2024/13-Claw_Contraption/first.hs b/2024/13-Claw_Contraption/first.hs
new file mode 100644
index 0000000..8ed15f9
--- /dev/null
+++ b/2024/13-Claw_Contraption/first.hs
@@ -0,0 +1,63 @@
+-- requires cabal install --lib megaparsec parser-combinators heap vector
+module Main (main) where
+
+import Control.Monad (void, when)
+import Data.Either
+import qualified Data.Matrix as MTX
+import Data.Ratio
+import Data.Void (Void)
+import Text.Megaparsec
+import Text.Megaparsec.Char
+
+exampleExpectedOutput = 480
+
+type Pair = (Rational, Rational) -- X Y
+type Entry = (Pair, Pair, Pair) -- ButtonA ButtonB Prize
+type Input = [Entry]
+
+type Parser = Parsec Void String
+
+parseNumber :: Parser Rational
+parseNumber = fromInteger . read <$> some digitChar
+
+parseButton :: Parser Pair
+parseButton = (,) <$> (string "Button " *> letterChar *> string ": X+" *> parseNumber)
+ <*> (string ", Y+" *> parseNumber <* eol)
+
+parsePrize :: Parser Pair
+parsePrize = (,) <$> (string "Prize: X=" *> parseNumber)
+ <*> (string ", Y=" *> parseNumber <* eol)
+
+parseEntry :: Parser Entry
+parseEntry = (,,) <$> parseButton
+ <*> parseButton
+ <*> parsePrize
+
+parseInput' :: Parser Input
+parseInput' = some (parseEntry <* optional eol) <* eof
+
+parseInput :: String -> IO Input
+parseInput filename = do
+ input <- readFile filename
+ case runParser parseInput' filename input of
+ Left bundle -> error $ errorBundlePretty bundle
+ Right input' -> return input'
+
+-- ax + bx = c
+-- ay + by = d
+compute :: Input -> Rational
+compute = sum . map compute'
+ where
+ compute' ((ax, ay), (bx, by), (px, py)) = let (Right sol) = MTX.rref $ MTX.fromList 2 3 [ ax, bx, px
+ , ay, by, py ]
+ x = sol MTX.! (1, 3)
+ y = sol MTX.! (2, 3)
+ in if (denominator x == 1 && denominator y == 1) then 3 * x + y else 0
+
+main :: IO ()
+main = do
+ example <- parseInput "example"
+ let exampleOutput = compute example
+ when (exampleOutput /= exampleExpectedOutput) (error $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show exampleExpectedOutput)
+ input <- parseInput "input"
+ print $ compute input
diff --git a/2024/13-Claw_Contraption/input b/2024/13-Claw_Contraption/input
new file mode 100644
index 0000000..8a8ee23
--- /dev/null
+++ b/2024/13-Claw_Contraption/input
@@ -0,0 +1,1279 @@
+Button A: X+23, Y+33
+Button B: X+62, Y+25
+Prize: X=6801, Y=3810
+
+Button A: X+31, Y+56
+Button B: X+27, Y+16
+Prize: X=18354, Y=8640
+
+Button A: X+45, Y+86
+Button B: X+30, Y+11
+Prize: X=5640, Y=8462
+
+Button A: X+39, Y+66
+Button B: X+97, Y+46
+Prize: X=9362, Y=7100
+
+Button A: X+66, Y+11
+Button B: X+11, Y+34
+Prize: X=4577, Y=8227
+
+Button A: X+73, Y+14
+Button B: X+94, Y+95
+Prize: X=10129, Y=9101
+
+Button A: X+65, Y+25
+Button B: X+59, Y+93
+Prize: X=2109, Y=1233
+
+Button A: X+19, Y+90
+Button B: X+67, Y+71
+Prize: X=3091, Y=8236
+
+Button A: X+74, Y+38
+Button B: X+17, Y+81
+Prize: X=3375, Y=7587
+
+Button A: X+47, Y+13
+Button B: X+12, Y+50
+Prize: X=19038, Y=924
+
+Button A: X+45, Y+21
+Button B: X+22, Y+37
+Prize: X=6821, Y=8669
+
+Button A: X+71, Y+29
+Button B: X+36, Y+96
+Prize: X=4434, Y=7014
+
+Button A: X+15, Y+55
+Button B: X+60, Y+17
+Prize: X=15440, Y=4357
+
+Button A: X+80, Y+49
+Button B: X+48, Y+90
+Prize: X=5328, Y=7566
+
+Button A: X+22, Y+48
+Button B: X+69, Y+35
+Prize: X=18409, Y=11853
+
+Button A: X+76, Y+39
+Button B: X+39, Y+72
+Prize: X=7655, Y=4812
+
+Button A: X+25, Y+30
+Button B: X+98, Y+21
+Prize: X=7277, Y=3999
+
+Button A: X+59, Y+42
+Button B: X+12, Y+31
+Prize: X=4477, Y=5051
+
+Button A: X+16, Y+35
+Button B: X+32, Y+21
+Prize: X=3696, Y=16097
+
+Button A: X+61, Y+27
+Button B: X+14, Y+49
+Prize: X=8585, Y=19166
+
+Button A: X+15, Y+49
+Button B: X+54, Y+27
+Prize: X=5009, Y=4005
+
+Button A: X+56, Y+77
+Button B: X+67, Y+28
+Prize: X=6554, Y=6062
+
+Button A: X+18, Y+64
+Button B: X+76, Y+72
+Prize: X=4220, Y=5688
+
+Button A: X+34, Y+16
+Button B: X+19, Y+36
+Prize: X=1612, Y=2328
+
+Button A: X+28, Y+11
+Button B: X+20, Y+45
+Prize: X=3100, Y=1755
+
+Button A: X+11, Y+36
+Button B: X+40, Y+21
+Prize: X=2630, Y=7616
+
+Button A: X+46, Y+12
+Button B: X+36, Y+59
+Prize: X=11292, Y=8388
+
+Button A: X+69, Y+19
+Button B: X+14, Y+49
+Prize: X=18362, Y=2812
+
+Button A: X+15, Y+95
+Button B: X+77, Y+47
+Prize: X=5794, Y=9374
+
+Button A: X+27, Y+87
+Button B: X+64, Y+18
+Prize: X=6444, Y=2130
+
+Button A: X+20, Y+67
+Button B: X+75, Y+56
+Prize: X=6795, Y=6167
+
+Button A: X+86, Y+61
+Button B: X+29, Y+82
+Prize: X=5464, Y=7070
+
+Button A: X+13, Y+79
+Button B: X+84, Y+13
+Prize: X=4021, Y=7957
+
+Button A: X+73, Y+13
+Button B: X+14, Y+77
+Prize: X=15266, Y=4754
+
+Button A: X+23, Y+98
+Button B: X+53, Y+23
+Prize: X=4336, Y=3466
+
+Button A: X+35, Y+13
+Button B: X+14, Y+63
+Prize: X=1925, Y=2738
+
+Button A: X+47, Y+14
+Button B: X+35, Y+72
+Prize: X=4048, Y=1320
+
+Button A: X+18, Y+61
+Button B: X+62, Y+28
+Prize: X=15782, Y=14681
+
+Button A: X+38, Y+13
+Button B: X+48, Y+79
+Prize: X=4736, Y=466
+
+Button A: X+23, Y+54
+Button B: X+71, Y+17
+Prize: X=7751, Y=4426
+
+Button A: X+90, Y+69
+Button B: X+39, Y+96
+Prize: X=8697, Y=9510
+
+Button A: X+63, Y+14
+Button B: X+22, Y+79
+Prize: X=10219, Y=6504
+
+Button A: X+45, Y+23
+Button B: X+12, Y+46
+Prize: X=2003, Y=1135
+
+Button A: X+54, Y+15
+Button B: X+27, Y+78
+Prize: X=17567, Y=14516
+
+Button A: X+34, Y+21
+Button B: X+11, Y+23
+Prize: X=12471, Y=5696
+
+Button A: X+67, Y+42
+Button B: X+37, Y+96
+Prize: X=7696, Y=10212
+
+Button A: X+28, Y+74
+Button B: X+36, Y+12
+Prize: X=396, Y=13702
+
+Button A: X+86, Y+48
+Button B: X+27, Y+49
+Prize: X=1407, Y=1905
+
+Button A: X+17, Y+36
+Button B: X+61, Y+37
+Prize: X=12574, Y=14609
+
+Button A: X+16, Y+28
+Button B: X+47, Y+27
+Prize: X=4372, Y=16648
+
+Button A: X+14, Y+40
+Button B: X+49, Y+41
+Prize: X=1771, Y=2981
+
+Button A: X+69, Y+17
+Button B: X+34, Y+73
+Prize: X=4756, Y=6277
+
+Button A: X+75, Y+93
+Button B: X+56, Y+13
+Prize: X=2786, Y=1705
+
+Button A: X+69, Y+30
+Button B: X+17, Y+70
+Prize: X=5156, Y=2680
+
+Button A: X+91, Y+92
+Button B: X+13, Y+64
+Prize: X=6734, Y=10012
+
+Button A: X+11, Y+37
+Button B: X+21, Y+11
+Prize: X=18964, Y=12956
+
+Button A: X+14, Y+35
+Button B: X+31, Y+23
+Prize: X=5314, Y=5119
+
+Button A: X+32, Y+13
+Button B: X+63, Y+83
+Prize: X=19490, Y=10380
+
+Button A: X+32, Y+62
+Button B: X+47, Y+20
+Prize: X=1260, Y=14382
+
+Button A: X+82, Y+22
+Button B: X+42, Y+65
+Prize: X=8018, Y=3387
+
+Button A: X+69, Y+42
+Button B: X+28, Y+55
+Prize: X=17829, Y=12213
+
+Button A: X+93, Y+48
+Button B: X+16, Y+57
+Prize: X=1715, Y=1860
+
+Button A: X+95, Y+24
+Button B: X+26, Y+97
+Prize: X=5246, Y=5033
+
+Button A: X+26, Y+71
+Button B: X+90, Y+31
+Prize: X=5182, Y=4701
+
+Button A: X+32, Y+23
+Button B: X+37, Y+91
+Prize: X=3504, Y=3549
+
+Button A: X+95, Y+46
+Button B: X+18, Y+48
+Prize: X=10177, Y=7442
+
+Button A: X+12, Y+62
+Button B: X+63, Y+20
+Prize: X=13535, Y=17316
+
+Button A: X+54, Y+18
+Button B: X+26, Y+57
+Prize: X=10796, Y=3707
+
+Button A: X+12, Y+48
+Button B: X+60, Y+31
+Prize: X=19664, Y=13962
+
+Button A: X+19, Y+38
+Button B: X+57, Y+16
+Prize: X=7340, Y=522
+
+Button A: X+47, Y+17
+Button B: X+34, Y+54
+Prize: X=13547, Y=1197
+
+Button A: X+21, Y+52
+Button B: X+34, Y+12
+Prize: X=18100, Y=9276
+
+Button A: X+91, Y+34
+Button B: X+30, Y+63
+Prize: X=5106, Y=5067
+
+Button A: X+64, Y+33
+Button B: X+11, Y+22
+Prize: X=11857, Y=17799
+
+Button A: X+13, Y+74
+Button B: X+28, Y+28
+Prize: X=3295, Y=8114
+
+Button A: X+67, Y+18
+Button B: X+30, Y+68
+Prize: X=7715, Y=4770
+
+Button A: X+85, Y+50
+Button B: X+22, Y+88
+Prize: X=9023, Y=10862
+
+Button A: X+18, Y+43
+Button B: X+70, Y+39
+Prize: X=18570, Y=7377
+
+Button A: X+17, Y+33
+Button B: X+30, Y+17
+Prize: X=4714, Y=3421
+
+Button A: X+14, Y+67
+Button B: X+72, Y+12
+Prize: X=808, Y=2628
+
+Button A: X+78, Y+15
+Button B: X+39, Y+65
+Prize: X=7020, Y=4685
+
+Button A: X+17, Y+46
+Button B: X+95, Y+57
+Prize: X=2389, Y=1863
+
+Button A: X+28, Y+97
+Button B: X+65, Y+47
+Prize: X=2192, Y=1892
+
+Button A: X+41, Y+71
+Button B: X+56, Y+17
+Prize: X=4078, Y=6742
+
+Button A: X+16, Y+40
+Button B: X+69, Y+25
+Prize: X=12681, Y=15365
+
+Button A: X+33, Y+55
+Button B: X+78, Y+38
+Prize: X=4260, Y=5812
+
+Button A: X+12, Y+45
+Button B: X+46, Y+14
+Prize: X=8392, Y=18642
+
+Button A: X+33, Y+14
+Button B: X+18, Y+27
+Prize: X=12749, Y=17332
+
+Button A: X+14, Y+65
+Button B: X+27, Y+24
+Prize: X=2596, Y=2728
+
+Button A: X+32, Y+62
+Button B: X+39, Y+14
+Prize: X=16653, Y=17268
+
+Button A: X+12, Y+40
+Button B: X+57, Y+37
+Prize: X=4217, Y=16825
+
+Button A: X+67, Y+44
+Button B: X+19, Y+46
+Prize: X=4645, Y=4748
+
+Button A: X+73, Y+89
+Button B: X+77, Y+21
+Prize: X=7505, Y=6745
+
+Button A: X+26, Y+13
+Button B: X+18, Y+44
+Prize: X=15034, Y=13357
+
+Button A: X+45, Y+61
+Button B: X+36, Y+12
+Prize: X=3492, Y=2084
+
+Button A: X+26, Y+52
+Button B: X+45, Y+14
+Prize: X=7208, Y=18704
+
+Button A: X+18, Y+41
+Button B: X+61, Y+15
+Prize: X=19617, Y=16443
+
+Button A: X+27, Y+55
+Button B: X+81, Y+15
+Prize: X=4455, Y=5475
+
+Button A: X+37, Y+60
+Button B: X+87, Y+13
+Prize: X=8407, Y=2618
+
+Button A: X+45, Y+12
+Button B: X+17, Y+71
+Prize: X=7194, Y=1125
+
+Button A: X+46, Y+17
+Button B: X+40, Y+70
+Prize: X=17324, Y=9138
+
+Button A: X+28, Y+50
+Button B: X+45, Y+25
+Prize: X=14211, Y=17625
+
+Button A: X+12, Y+70
+Button B: X+44, Y+33
+Prize: X=400, Y=1215
+
+Button A: X+86, Y+30
+Button B: X+78, Y+96
+Prize: X=5384, Y=2910
+
+Button A: X+21, Y+55
+Button B: X+48, Y+18
+Prize: X=2762, Y=6834
+
+Button A: X+20, Y+49
+Button B: X+68, Y+40
+Prize: X=16676, Y=13367
+
+Button A: X+43, Y+24
+Button B: X+21, Y+44
+Prize: X=18622, Y=3868
+
+Button A: X+64, Y+21
+Button B: X+26, Y+65
+Prize: X=1886, Y=7182
+
+Button A: X+92, Y+23
+Button B: X+17, Y+67
+Prize: X=6073, Y=5597
+
+Button A: X+14, Y+32
+Button B: X+23, Y+15
+Prize: X=14831, Y=9287
+
+Button A: X+86, Y+57
+Button B: X+14, Y+88
+Prize: X=7798, Y=8396
+
+Button A: X+71, Y+17
+Button B: X+22, Y+70
+Prize: X=5732, Y=6884
+
+Button A: X+11, Y+69
+Button B: X+87, Y+30
+Prize: X=9216, Y=13820
+
+Button A: X+25, Y+68
+Button B: X+71, Y+26
+Prize: X=8245, Y=18040
+
+Button A: X+52, Y+35
+Button B: X+15, Y+69
+Prize: X=2729, Y=2956
+
+Button A: X+81, Y+43
+Button B: X+16, Y+50
+Prize: X=4247, Y=7489
+
+Button A: X+15, Y+32
+Button B: X+43, Y+15
+Prize: X=18075, Y=2014
+
+Button A: X+45, Y+73
+Button B: X+53, Y+25
+Prize: X=5131, Y=7287
+
+Button A: X+95, Y+35
+Button B: X+14, Y+25
+Prize: X=6311, Y=3595
+
+Button A: X+24, Y+72
+Button B: X+65, Y+22
+Prize: X=2510, Y=14828
+
+Button A: X+12, Y+89
+Button B: X+80, Y+33
+Prize: X=6464, Y=7037
+
+Button A: X+11, Y+21
+Button B: X+53, Y+29
+Prize: X=14589, Y=11385
+
+Button A: X+51, Y+75
+Button B: X+37, Y+15
+Prize: X=17832, Y=3350
+
+Button A: X+58, Y+34
+Button B: X+13, Y+33
+Prize: X=15315, Y=7103
+
+Button A: X+58, Y+74
+Button B: X+79, Y+23
+Prize: X=8036, Y=6052
+
+Button A: X+91, Y+48
+Button B: X+11, Y+43
+Prize: X=2094, Y=3262
+
+Button A: X+35, Y+19
+Button B: X+16, Y+41
+Prize: X=10599, Y=14620
+
+Button A: X+30, Y+12
+Button B: X+41, Y+54
+Prize: X=13205, Y=13550
+
+Button A: X+18, Y+34
+Button B: X+46, Y+18
+Prize: X=478, Y=5554
+
+Button A: X+55, Y+19
+Button B: X+13, Y+50
+Prize: X=15778, Y=13621
+
+Button A: X+42, Y+14
+Button B: X+13, Y+35
+Prize: X=4802, Y=12646
+
+Button A: X+19, Y+95
+Button B: X+97, Y+56
+Prize: X=4759, Y=9638
+
+Button A: X+13, Y+68
+Button B: X+74, Y+73
+Prize: X=1371, Y=5601
+
+Button A: X+24, Y+65
+Button B: X+83, Y+12
+Prize: X=7732, Y=1364
+
+Button A: X+20, Y+34
+Button B: X+46, Y+14
+Prize: X=2532, Y=16552
+
+Button A: X+62, Y+20
+Button B: X+12, Y+60
+Prize: X=6086, Y=19340
+
+Button A: X+62, Y+98
+Button B: X+55, Y+20
+Prize: X=3900, Y=2550
+
+Button A: X+22, Y+45
+Button B: X+59, Y+33
+Prize: X=18781, Y=5858
+
+Button A: X+60, Y+29
+Button B: X+12, Y+45
+Prize: X=18440, Y=19558
+
+Button A: X+50, Y+19
+Button B: X+22, Y+39
+Prize: X=19748, Y=2366
+
+Button A: X+13, Y+74
+Button B: X+42, Y+50
+Prize: X=3997, Y=10084
+
+Button A: X+61, Y+17
+Button B: X+12, Y+62
+Prize: X=7708, Y=12832
+
+Button A: X+11, Y+31
+Button B: X+66, Y+14
+Prize: X=3048, Y=18244
+
+Button A: X+55, Y+16
+Button B: X+22, Y+49
+Prize: X=16336, Y=8296
+
+Button A: X+46, Y+12
+Button B: X+31, Y+64
+Prize: X=2535, Y=6632
+
+Button A: X+53, Y+25
+Button B: X+13, Y+21
+Prize: X=3569, Y=15621
+
+Button A: X+18, Y+59
+Button B: X+63, Y+17
+Prize: X=3770, Y=11192
+
+Button A: X+46, Y+12
+Button B: X+19, Y+37
+Prize: X=6196, Y=19736
+
+Button A: X+19, Y+73
+Button B: X+38, Y+25
+Prize: X=4199, Y=8026
+
+Button A: X+72, Y+60
+Button B: X+20, Y+87
+Prize: X=5724, Y=5403
+
+Button A: X+39, Y+11
+Button B: X+38, Y+72
+Prize: X=18434, Y=206
+
+Button A: X+20, Y+72
+Button B: X+70, Y+23
+Prize: X=7310, Y=7293
+
+Button A: X+41, Y+67
+Button B: X+50, Y+27
+Prize: X=422, Y=8325
+
+Button A: X+30, Y+80
+Button B: X+66, Y+14
+Prize: X=776, Y=5344
+
+Button A: X+11, Y+29
+Button B: X+63, Y+22
+Prize: X=15012, Y=17058
+
+Button A: X+13, Y+44
+Button B: X+85, Y+51
+Prize: X=17219, Y=6673
+
+Button A: X+25, Y+59
+Button B: X+39, Y+11
+Prize: X=17976, Y=15604
+
+Button A: X+59, Y+30
+Button B: X+22, Y+45
+Prize: X=8281, Y=6635
+
+Button A: X+38, Y+50
+Button B: X+85, Y+22
+Prize: X=4507, Y=1528
+
+Button A: X+13, Y+12
+Button B: X+16, Y+52
+Prize: X=2514, Y=5448
+
+Button A: X+52, Y+14
+Button B: X+15, Y+68
+Prize: X=5714, Y=7004
+
+Button A: X+41, Y+21
+Button B: X+26, Y+56
+Prize: X=17732, Y=13192
+
+Button A: X+72, Y+40
+Button B: X+22, Y+48
+Prize: X=18704, Y=8800
+
+Button A: X+80, Y+86
+Button B: X+81, Y+13
+Prize: X=11929, Y=6231
+
+Button A: X+72, Y+16
+Button B: X+21, Y+79
+Prize: X=14828, Y=5092
+
+Button A: X+62, Y+24
+Button B: X+28, Y+71
+Prize: X=9482, Y=4259
+
+Button A: X+31, Y+14
+Button B: X+14, Y+54
+Prize: X=914, Y=1338
+
+Button A: X+39, Y+17
+Button B: X+11, Y+50
+Prize: X=2698, Y=13446
+
+Button A: X+75, Y+39
+Button B: X+21, Y+74
+Prize: X=6363, Y=6652
+
+Button A: X+15, Y+81
+Button B: X+82, Y+51
+Prize: X=4348, Y=4281
+
+Button A: X+61, Y+24
+Button B: X+34, Y+75
+Prize: X=5283, Y=7563
+
+Button A: X+72, Y+33
+Button B: X+11, Y+39
+Prize: X=17203, Y=9617
+
+Button A: X+21, Y+52
+Button B: X+77, Y+44
+Prize: X=4540, Y=10560
+
+Button A: X+30, Y+14
+Button B: X+13, Y+41
+Prize: X=14049, Y=16261
+
+Button A: X+21, Y+41
+Button B: X+34, Y+17
+Prize: X=9712, Y=5542
+
+Button A: X+56, Y+87
+Button B: X+81, Y+15
+Prize: X=5004, Y=6444
+
+Button A: X+12, Y+66
+Button B: X+88, Y+13
+Prize: X=1260, Y=1278
+
+Button A: X+28, Y+62
+Button B: X+67, Y+28
+Prize: X=3746, Y=19504
+
+Button A: X+15, Y+61
+Button B: X+82, Y+29
+Prize: X=16461, Y=12602
+
+Button A: X+22, Y+59
+Button B: X+74, Y+33
+Prize: X=5892, Y=19334
+
+Button A: X+20, Y+47
+Button B: X+64, Y+41
+Prize: X=4156, Y=11048
+
+Button A: X+61, Y+37
+Button B: X+42, Y+84
+Prize: X=7381, Y=8047
+
+Button A: X+59, Y+11
+Button B: X+20, Y+42
+Prize: X=1850, Y=2756
+
+Button A: X+69, Y+25
+Button B: X+26, Y+73
+Prize: X=4751, Y=19072
+
+Button A: X+61, Y+21
+Button B: X+18, Y+58
+Prize: X=16458, Y=8618
+
+Button A: X+88, Y+39
+Button B: X+35, Y+66
+Prize: X=6246, Y=7716
+
+Button A: X+81, Y+20
+Button B: X+21, Y+67
+Prize: X=8802, Y=8293
+
+Button A: X+75, Y+89
+Button B: X+52, Y+12
+Prize: X=4336, Y=3008
+
+Button A: X+55, Y+18
+Button B: X+13, Y+36
+Prize: X=19484, Y=19592
+
+Button A: X+62, Y+35
+Button B: X+24, Y+45
+Prize: X=18008, Y=14615
+
+Button A: X+56, Y+30
+Button B: X+28, Y+48
+Prize: X=6720, Y=5580
+
+Button A: X+22, Y+53
+Button B: X+41, Y+15
+Prize: X=15194, Y=10016
+
+Button A: X+19, Y+52
+Button B: X+64, Y+25
+Prize: X=14612, Y=4460
+
+Button A: X+23, Y+11
+Button B: X+33, Y+57
+Prize: X=6641, Y=18797
+
+Button A: X+31, Y+68
+Button B: X+59, Y+15
+Prize: X=15183, Y=2170
+
+Button A: X+12, Y+32
+Button B: X+42, Y+29
+Prize: X=3366, Y=2917
+
+Button A: X+12, Y+34
+Button B: X+44, Y+14
+Prize: X=15992, Y=2860
+
+Button A: X+46, Y+93
+Button B: X+97, Y+23
+Prize: X=4212, Y=1245
+
+Button A: X+27, Y+17
+Button B: X+17, Y+45
+Prize: X=11411, Y=15891
+
+Button A: X+55, Y+20
+Button B: X+34, Y+71
+Prize: X=9870, Y=12505
+
+Button A: X+15, Y+39
+Button B: X+66, Y+41
+Prize: X=746, Y=7263
+
+Button A: X+95, Y+51
+Button B: X+21, Y+99
+Prize: X=8616, Y=10854
+
+Button A: X+95, Y+16
+Button B: X+70, Y+67
+Prize: X=2690, Y=1226
+
+Button A: X+14, Y+24
+Button B: X+94, Y+40
+Prize: X=9464, Y=4352
+
+Button A: X+33, Y+80
+Button B: X+58, Y+15
+Prize: X=19115, Y=18265
+
+Button A: X+72, Y+35
+Button B: X+11, Y+54
+Prize: X=12332, Y=6651
+
+Button A: X+25, Y+35
+Button B: X+39, Y+14
+Prize: X=3671, Y=1526
+
+Button A: X+12, Y+73
+Button B: X+98, Y+84
+Prize: X=8958, Y=13009
+
+Button A: X+95, Y+27
+Button B: X+38, Y+55
+Prize: X=4085, Y=4918
+
+Button A: X+33, Y+11
+Button B: X+14, Y+53
+Prize: X=9819, Y=2318
+
+Button A: X+88, Y+37
+Button B: X+53, Y+97
+Prize: X=3860, Y=3715
+
+Button A: X+72, Y+26
+Button B: X+48, Y+57
+Prize: X=2448, Y=1003
+
+Button A: X+46, Y+28
+Button B: X+18, Y+41
+Prize: X=11938, Y=17046
+
+Button A: X+12, Y+48
+Button B: X+74, Y+43
+Prize: X=19634, Y=15239
+
+Button A: X+95, Y+39
+Button B: X+46, Y+95
+Prize: X=10094, Y=10157
+
+Button A: X+82, Y+34
+Button B: X+31, Y+81
+Prize: X=8143, Y=7397
+
+Button A: X+46, Y+14
+Button B: X+31, Y+56
+Prize: X=15179, Y=3476
+
+Button A: X+92, Y+13
+Button B: X+34, Y+56
+Prize: X=9082, Y=2768
+
+Button A: X+41, Y+11
+Button B: X+62, Y+70
+Prize: X=804, Y=696
+
+Button A: X+90, Y+15
+Button B: X+59, Y+64
+Prize: X=4870, Y=1895
+
+Button A: X+43, Y+11
+Button B: X+27, Y+62
+Prize: X=11720, Y=8400
+
+Button A: X+64, Y+27
+Button B: X+24, Y+44
+Prize: X=5416, Y=2793
+
+Button A: X+53, Y+94
+Button B: X+51, Y+17
+Prize: X=6155, Y=5334
+
+Button A: X+30, Y+11
+Button B: X+23, Y+60
+Prize: X=2222, Y=1409
+
+Button A: X+11, Y+57
+Button B: X+49, Y+21
+Prize: X=5062, Y=13550
+
+Button A: X+33, Y+13
+Button B: X+57, Y+79
+Prize: X=4685, Y=14057
+
+Button A: X+13, Y+62
+Button B: X+72, Y+12
+Prize: X=2422, Y=4592
+
+Button A: X+21, Y+53
+Button B: X+59, Y+33
+Prize: X=4967, Y=10057
+
+Button A: X+69, Y+40
+Button B: X+28, Y+57
+Prize: X=17253, Y=11830
+
+Button A: X+25, Y+55
+Button B: X+71, Y+48
+Prize: X=7715, Y=7235
+
+Button A: X+45, Y+25
+Button B: X+14, Y+41
+Prize: X=1391, Y=4924
+
+Button A: X+51, Y+11
+Button B: X+14, Y+32
+Prize: X=14436, Y=9800
+
+Button A: X+65, Y+18
+Button B: X+21, Y+91
+Prize: X=3911, Y=2446
+
+Button A: X+53, Y+57
+Button B: X+79, Y+23
+Prize: X=2831, Y=2487
+
+Button A: X+38, Y+65
+Button B: X+55, Y+26
+Prize: X=17193, Y=7231
+
+Button A: X+36, Y+25
+Button B: X+14, Y+68
+Prize: X=2662, Y=7385
+
+Button A: X+51, Y+22
+Button B: X+19, Y+64
+Prize: X=11978, Y=2798
+
+Button A: X+31, Y+55
+Button B: X+40, Y+17
+Prize: X=12598, Y=2078
+
+Button A: X+16, Y+36
+Button B: X+50, Y+15
+Prize: X=2258, Y=1863
+
+Button A: X+22, Y+90
+Button B: X+81, Y+59
+Prize: X=6274, Y=10414
+
+Button A: X+58, Y+14
+Button B: X+35, Y+80
+Prize: X=4605, Y=19390
+
+Button A: X+24, Y+15
+Button B: X+20, Y+93
+Prize: X=2448, Y=6360
+
+Button A: X+44, Y+24
+Button B: X+18, Y+39
+Prize: X=7128, Y=5540
+
+Button A: X+81, Y+67
+Button B: X+90, Y+11
+Prize: X=7074, Y=1093
+
+Button A: X+51, Y+16
+Button B: X+12, Y+33
+Prize: X=12497, Y=10950
+
+Button A: X+89, Y+41
+Button B: X+47, Y+95
+Prize: X=4463, Y=3743
+
+Button A: X+20, Y+45
+Button B: X+26, Y+12
+Prize: X=4302, Y=8474
+
+Button A: X+22, Y+88
+Button B: X+89, Y+75
+Prize: X=6544, Y=11002
+
+Button A: X+30, Y+68
+Button B: X+57, Y+26
+Prize: X=5678, Y=18428
+
+Button A: X+24, Y+70
+Button B: X+75, Y+28
+Prize: X=18920, Y=19352
+
+Button A: X+69, Y+20
+Button B: X+14, Y+65
+Prize: X=19613, Y=12505
+
+Button A: X+50, Y+70
+Button B: X+58, Y+12
+Prize: X=8362, Y=7278
+
+Button A: X+87, Y+58
+Button B: X+11, Y+85
+Prize: X=2258, Y=5777
+
+Button A: X+71, Y+34
+Button B: X+11, Y+65
+Prize: X=1511, Y=3531
+
+Button A: X+63, Y+23
+Button B: X+31, Y+49
+Prize: X=4884, Y=4044
+
+Button A: X+49, Y+21
+Button B: X+22, Y+51
+Prize: X=4789, Y=2676
+
+Button A: X+21, Y+71
+Button B: X+49, Y+16
+Prize: X=17154, Y=7804
+
+Button A: X+37, Y+11
+Button B: X+49, Y+72
+Prize: X=13066, Y=14023
+
+Button A: X+90, Y+36
+Button B: X+53, Y+86
+Prize: X=6524, Y=4424
+
+Button A: X+71, Y+13
+Button B: X+17, Y+62
+Prize: X=5108, Y=12592
+
+Button A: X+16, Y+50
+Button B: X+50, Y+24
+Prize: X=10032, Y=7620
+
+Button A: X+55, Y+11
+Button B: X+13, Y+70
+Prize: X=6658, Y=10983
+
+Button A: X+14, Y+36
+Button B: X+55, Y+31
+Prize: X=15540, Y=1556
+
+Button A: X+34, Y+54
+Button B: X+27, Y+13
+Prize: X=12112, Y=8144
+
+Button A: X+68, Y+63
+Button B: X+77, Y+16
+Prize: X=9005, Y=6074
+
+Button A: X+52, Y+99
+Button B: X+59, Y+22
+Prize: X=4621, Y=4191
+
+Button A: X+57, Y+23
+Button B: X+27, Y+61
+Prize: X=13373, Y=1507
+
+Button A: X+39, Y+56
+Button B: X+40, Y+14
+Prize: X=15692, Y=11946
+
+Button A: X+50, Y+21
+Button B: X+17, Y+35
+Prize: X=4466, Y=13717
+
+Button A: X+12, Y+37
+Button B: X+54, Y+16
+Prize: X=8066, Y=12508
+
+Button A: X+54, Y+22
+Button B: X+14, Y+28
+Prize: X=1552, Y=7098
+
+Button A: X+24, Y+57
+Button B: X+66, Y+32
+Prize: X=4994, Y=12455
+
+Button A: X+39, Y+73
+Button B: X+49, Y+28
+Prize: X=4940, Y=5105
+
+Button A: X+63, Y+25
+Button B: X+26, Y+42
+Prize: X=2819, Y=2481
+
+Button A: X+87, Y+50
+Button B: X+34, Y+79
+Prize: X=9327, Y=6609
+
+Button A: X+88, Y+78
+Button B: X+12, Y+40
+Prize: X=4948, Y=4650
+
+Button A: X+78, Y+46
+Button B: X+14, Y+36
+Prize: X=16096, Y=12012
+
+Button A: X+75, Y+14
+Button B: X+22, Y+94
+Prize: X=6985, Y=6248
+
+Button A: X+29, Y+57
+Button B: X+33, Y+12
+Prize: X=434, Y=483
+
+Button A: X+60, Y+47
+Button B: X+13, Y+77
+Prize: X=3763, Y=5019
+
+Button A: X+42, Y+14
+Button B: X+51, Y+85
+Prize: X=5490, Y=7134
+
+Button A: X+74, Y+48
+Button B: X+16, Y+38
+Prize: X=10264, Y=2080
+
+Button A: X+42, Y+24
+Button B: X+13, Y+61
+Prize: X=1834, Y=4798
+
+Button A: X+47, Y+82
+Button B: X+50, Y+15
+Prize: X=14653, Y=17558
+
+Button A: X+74, Y+21
+Button B: X+17, Y+95
+Prize: X=7122, Y=7612
+
+Button A: X+18, Y+56
+Button B: X+89, Y+29
+Prize: X=7328, Y=5446
+
+Button A: X+36, Y+73
+Button B: X+57, Y+21
+Prize: X=1925, Y=3535
+
+Button A: X+53, Y+36
+Button B: X+13, Y+34
+Prize: X=9614, Y=6604
+
+Button A: X+30, Y+23
+Button B: X+22, Y+98
+Prize: X=3616, Y=6261
+
+Button A: X+37, Y+79
+Button B: X+87, Y+29
+Prize: X=1412, Y=1604
+
+Button A: X+37, Y+25
+Button B: X+14, Y+34
+Prize: X=728, Y=13612
+
+Button A: X+21, Y+51
+Button B: X+58, Y+25
+Prize: X=8630, Y=5411
+
+Button A: X+71, Y+80
+Button B: X+12, Y+85
+Prize: X=3871, Y=5005
+
+Button A: X+82, Y+37
+Button B: X+51, Y+84
+Prize: X=7154, Y=8351
+
+Button A: X+62, Y+42
+Button B: X+31, Y+66
+Prize: X=2976, Y=4626
+
+Button A: X+54, Y+22
+Button B: X+27, Y+62
+Prize: X=13463, Y=9180
+
+Button A: X+12, Y+50
+Button B: X+50, Y+12
+Prize: X=5058, Y=13152
+
+Button A: X+18, Y+52
+Button B: X+77, Y+29
+Prize: X=3147, Y=5029
+
+Button A: X+21, Y+86
+Button B: X+95, Y+66
+Prize: X=3578, Y=2700
+
+Button A: X+34, Y+78
+Button B: X+26, Y+14
+Prize: X=3866, Y=5902
+
+Button A: X+45, Y+28
+Button B: X+14, Y+42
+Prize: X=5409, Y=2902
+
+Button A: X+60, Y+29
+Button B: X+35, Y+66
+Prize: X=19625, Y=11658
+
+Button A: X+14, Y+49
+Button B: X+79, Y+38
+Prize: X=3957, Y=8128
+
+Button A: X+44, Y+12
+Button B: X+15, Y+77
+Prize: X=2978, Y=4166
+
+Button A: X+15, Y+36
+Button B: X+42, Y+13
+Prize: X=1040, Y=7437
+
+Button A: X+41, Y+30
+Button B: X+11, Y+65
+Prize: X=1311, Y=4775
+
+Button A: X+56, Y+19
+Button B: X+28, Y+62
+Prize: X=12940, Y=10005
+
+Button A: X+12, Y+38
+Button B: X+63, Y+41
+Prize: X=17435, Y=15109
+
+Button A: X+18, Y+86
+Button B: X+83, Y+25
+Prize: X=8962, Y=6406
+
+Button A: X+42, Y+18
+Button B: X+19, Y+52
+Prize: X=3636, Y=7386
+
+Button A: X+31, Y+22
+Button B: X+40, Y+97
+Prize: X=1803, Y=1554
+
+Button A: X+33, Y+43
+Button B: X+83, Y+28
+Prize: X=4286, Y=3581
+
+Button A: X+37, Y+50
+Button B: X+98, Y+19
+Prize: X=4671, Y=1548
+
+Button A: X+54, Y+27
+Button B: X+12, Y+95
+Prize: X=6096, Y=9812
+
+Button A: X+24, Y+80
+Button B: X+31, Y+16
+Prize: X=1359, Y=1648
+
+Button A: X+41, Y+11
+Button B: X+35, Y+73
+Prize: X=617, Y=13611
+
+Button A: X+22, Y+46
+Button B: X+72, Y+49
+Prize: X=10986, Y=636
+
+Button A: X+55, Y+14
+Button B: X+15, Y+41
+Prize: X=10895, Y=4037
+
+Button A: X+28, Y+28
+Button B: X+66, Y+13
+Prize: X=6920, Y=2892
+
+Button A: X+45, Y+13
+Button B: X+16, Y+51
+Prize: X=1883, Y=915
diff --git a/2024/13-Claw_Contraption/second.hs b/2024/13-Claw_Contraption/second.hs
new file mode 100644
index 0000000..b0af3d9
--- /dev/null
+++ b/2024/13-Claw_Contraption/second.hs
@@ -0,0 +1,58 @@
+-- requires cabal install --lib megaparsec parser-combinators heap vector
+module Main (main) where
+
+import Control.Monad (void, when)
+import Data.Either
+import qualified Data.Matrix as MTX
+import Data.Ratio
+import Data.Void (Void)
+import Text.Megaparsec
+import Text.Megaparsec.Char
+
+type Pair = (Rational, Rational) -- X Y
+type Entry = (Pair, Pair, Pair) -- ButtonA ButtonB Prize
+type Input = [Entry]
+
+type Parser = Parsec Void String
+
+parseNumber :: Parser Rational
+parseNumber = fromInteger . read <$> some digitChar
+
+parseButton :: Parser Pair
+parseButton = (,) <$> (string "Button " *> letterChar *> string ": X+" *> parseNumber)
+ <*> (string ", Y+" *> parseNumber <* eol)
+
+parsePrize :: Parser Pair
+parsePrize = (,) <$> (string "Prize: X=" *> parseNumber)
+ <*> (string ", Y=" *> parseNumber <* eol)
+
+parseEntry :: Parser Entry
+parseEntry = (,,) <$> parseButton
+ <*> parseButton
+ <*> parsePrize
+
+parseInput' :: Parser Input
+parseInput' = some (parseEntry <* optional eol) <* eof
+
+parseInput :: String -> IO Input
+parseInput filename = do
+ input <- readFile filename
+ case runParser parseInput' filename input of
+ Left bundle -> error $ errorBundlePretty bundle
+ Right input' -> return input'
+
+-- ax + bx = c
+-- ay + by = d
+compute :: Input -> Rational
+compute = sum . map compute'
+ where
+ compute' ((ax, ay), (bx, by), (px, py)) = let (Right sol) = MTX.rref $ MTX.fromList 2 3 [ ax, bx, px + 10000000000000
+ , ay, by, py + 10000000000000 ]
+ x = sol MTX.! (1, 3)
+ y = sol MTX.! (2, 3)
+ in if (denominator x == 1 && denominator y == 1) then 3 * x + y else 0
+
+main :: IO ()
+main = do
+ input <- parseInput "input"
+ print $ compute input