49 lines
1.6 KiB
Haskell
49 lines
1.6 KiB
Haskell
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)
|