diff --git a/13/example.txt b/13/example.txt new file mode 100644 index 0000000..912f482 --- /dev/null +++ b/13/example.txt @@ -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/13/solution.hs b/13/solution.hs new file mode 100644 index 0000000..54469fc --- /dev/null +++ b/13/solution.hs @@ -0,0 +1,49 @@ +import qualified Data.List.Split as S +import Data.List +import Data.Matrix as M +import Data.Ratio +import Debug.Trace + +traceOut :: Show a => a -> a +traceOut x = (traceShow x x) + +addFirst :: [[a]] -> a -> [[a]] +addFirst [] x = [[x]] +addFirst (y:ys) x = ([x] ++ y) : ys + +split :: [Char] -> String -> [String] +split _ [] = [] +split delims (x:xs) + | elem x delims = [[]] ++ split delims xs + | otherwise = addFirst (split delims xs) x + +splitInput :: [String] -> [[[Ratio Int]]] +splitInput = map (map (map ((% 1) . read . last . split "+=") . split [',']). split ['\n']) + +solve1 :: [[[Ratio Int]]] -> Ratio Int +solve1 [] = 0 +solve1 (x:xs) = (let a = (inverse $ M.transpose $ fromLists ([x!!0, x!!1])) in + case a of + Left _ -> 0 + Right matrix -> let b = matrix * (M.transpose $ fromLists [x!!2]) in if (all (\x -> denominator x == 1) b) then sum (multiplier*b) else 0 + ) + solve1 xs + +solve2 :: [[[Ratio Int]]] -> Ratio Int +solve2 [] = 0 +solve2 (x:xs) = (let a = (inverse $ M.transpose $ fromLists ([x!!0, x!!1])) in + case a of + Left _ -> 0 + Right matrix -> let b = matrix * (M.transpose $ shift + fromLists [x!!2]) in if (all (\x -> denominator x == 1) b) then sum(multiplier*b) else 0 + ) + solve1 xs + +multiplier :: Matrix (Ratio Int) = fromLists [[3 % 1, 0], [0, 1 % 1]] +shift :: Matrix (Ratio Int) = fromLists [[10000000000000 % 1, 10000000000000 % 1]] + +main :: IO() +main = do + fileinp <- readFile "input.txt" + let parsed = splitInput $ S.splitOn "\n\n" fileinp + let solved1 = solve1 parsed + let solved2 = solve2 parsed + print (numerator $ solved1) + print (numerator $ solved2)