diff --git a/day14.hs b/day14.hs new file mode 100644 index 0000000..bae2908 --- /dev/null +++ b/day14.hs @@ -0,0 +1,60 @@ +import Data.List.Split +import Data.List +import Data.Char as Char +import Linear.V3 +import Debug.Trace as T + +main = do + reactions <- map getReaction <$> lines <$> getContents + let amout = getConstruction reactions (1,"A") + let ore = getOre [(1,"FUEL")] [] reactions + let result = foldl (++)[] (map(\(amount,xs) -> map(\(a,e) -> ((amount * a),e)) xs) (map (getConstructionRest reactions) ore)) + let sumResult = foldl combineNeeds [] result + putStrLn(show $ head reactions) + putStrLn(show ore) + putStrLn(show sumResult) +data Reaction = Reaction { input :: [(Int, String)], + output :: (Int,String) + } deriving Show + +getReaction :: String -> Reaction +getReaction input = Reaction left right + where split = splitOn " => " input + left = map getElements (splitOn ", " (split!!0)) + right = getElements $ split!!1 + +getElements :: String -> (Int,String) +getElements input = (amount,element) + where split = splitOn " " input + amount = read $ (split!!0) + element = split!!1 + +getNextStep :: [Reaction] -> Reaction -> [Reaction] +getNextStep xs (Reaction left right) = filter(\(Reaction i o) -> elem (snd o) reactElem ) xs + where reactElem = map(\(a,b) -> b) left + +getConstruction :: [Reaction] -> (Int,String) -> (Int,[(Int, String)]) +getConstruction reactions (amount,elem) + | length reaction > 0 = (div amount ( fst $ output $ head $ reaction),(input $ head $ reaction)) + | otherwise = ((div amount ( fst $ output $ head $ reaction)) + 1,(input $ head $ reaction)) + where reaction = filter(\(Reaction i o) -> ((snd o) == elem) && (mod amount (fst o) == 0)) reactions + + +getConstructionRest :: [Reaction] -> (Int,String) -> (Int,[(Int, String)]) +getConstructionRest reactions (amount, elem) + | elem == "ORE" = (1,[(amount,elem)]) + | otherwise = ((div amount ( fst $ output $ head $ reaction)) + 1,(input $ head $ reaction)) + where reaction = filter(\(Reaction i o) -> ((snd o) == elem)) reactions + +getOre :: [(Int,String)] -> [(Int,String)] -> [Reaction] -> [(Int,String)] +getOre needs oldNeeds reactions + | needs == oldNeeds = newNeeds + | otherwise = getOre (T.traceShowId(newNeeds)) needs reactions + where newNeeds =foldl combineNeeds [] ( foldl (++)[] (map(\(amount,xs) -> map(\(a,e) -> ((amount * a),e)) xs) construction)) + construction = map (getConstruction reactions) needs + +combineNeeds :: [(Int,String)] -> (Int,String) -> [(Int,String)] +combineNeeds xs (amt, elem) + | null oldVal = xs ++ [(amt,elem)] + | otherwise = (xs \\ oldVal) ++ [((amt + (fst (head oldVal))),elem)] + where oldVal = filter(\(a,e) -> e == elem) xs