diff --git a/6/solve.hs b/6/solve.hs index faf8b6d03dffb1a806348797eda30e047b4e531a..409359a19b10d55ef63595477bd5a03eb6007b61 100644 --- a/6/solve.hs +++ b/6/solve.hs @@ -35,6 +35,10 @@ solve2 :: String -> Int solve2 s = fst $ head $ filter (\(x, _) -> x > 0) $ map (\x -> evalTuple $ takeLeftRight x 14 i) [1..(length s)-1] where i = zip [1..] s +-- found on reddit +-- part1 = fst . head . filter (((==) =<< nub) . snd) . zip [ 4..] . map (take 4) . tails +-- part2 = fst . head . filter (((==) =<< nub) . snd) . zip [14..] . map (take 14) + main :: IO () main = do input <- head <$> lines <$> readFile "./input.txt" diff --git a/7/solve.hs b/7/solve.hs index e6dacbfee8822da996a44eadd6fde7cab26fca2b..a2778128cdffb7147b3e5cbc40675807b7512208 100644 --- a/7/solve.hs +++ b/7/solve.hs @@ -1,35 +1,31 @@ -- Day 7 -{-# LANGUAGE MultiWayIf #-} +{-# LANGUAGE BangPatterns #-} import Data.List -import Data.Char + +while :: (a -> Bool) -> (a -> a) -> a -> a +while p f = go where go !x = if p x then go (f x) else x cleanUpNav :: [String] -> [String] -cleanUpNav = filter (\x -> not $ "$ cd .." `isInfixOf` x) +cleanUpNav = filter (\x -> not $ "$ cd .." `isInfixOf` x || (x == "$ ls")) -getFilesInDir :: [String] -> [(String, [String])] -getFilesInDir [x] = [] -getFilesInDir (x1:_:xs) = if "cd" `isInfixOf` x1 - then (getDirName x1 "$ cd ", getUntilCommand xs) : getFilesInDir xs - else getFilesInDir xs getDirName :: String -> String -> String getDirName x prefix = if prefix `isPrefixOf` x then last $ words x else "" - getUntilCommand :: [String] -> [String] -getUntilCommand [x] = [] +getUntilCommand [] = [] getUntilCommand (x:xs) = if head x /= '$' then x:getUntilCommand xs else [] -getFileSize :: String -> Int -getFileSize = read . head . words - -nestedDirName :: String -> String -nestedDirName = last . words +getDirNameContent :: [String] -> [(String, [String])] +getDirNameContent [] = [] +getDirNameContent (x:xs) = if "$ cd " `isPrefixOf` x + then (getDirName x "$ cd ", getUntilCommand xs) : getDirNameContent xs + else getDirNameContent xs findDir :: String -> [(String, [String])] -> (String, [String]) findDir n = head . filter (\(x, _) -> x == n) @@ -38,19 +34,34 @@ unwrapDir :: String -> [(String, [String])] -> [String] unwrapDir dirName navStack = snd $ findDir dirName navStack filesInNestedDir :: String -> [(String, [String])]-> [String] -filesInNestedDir x stack = if isAlpha (head x) +filesInNestedDir x stack = if "dir" `isPrefixOf` x then unwrapDir (getDirName x "dir ") stack else [x] -getTotalFilesForDir :: [String] -> [(String, [String])] -> [[String]] -getTotalFilesForDir [x] stack = [filesInNestedDir x stack] -getTotalFilesForDir (x:xs) stack = filesInNestedDir x stack : getTotalFilesForDir xs stack +filesForDir :: [String] -> [(String, [String])] -> [[String]] +filesForDir [x] stack = [filesInNestedDir x stack] +filesForDir (x:xs) stack = filesInNestedDir x stack : filesForDir xs stack + +containsDirs :: [String] -> Bool +containsDirs l = filter ("dir" `isPrefixOf`) l /= [] + +goUntilNoDir :: [String] -> [(String, [String])] -> [String] +goUntilNoDir currentDir stack = if containsDirs currentDir + then goUntilNoDir (concat (filesForDir currentDir stack)) stack + else currentDir + +getFilesInDirs :: [(String, [String])] -> [(String, [String])] +getFilesInDirs stack = map (\(x, y) -> + (x, goUntilNoDir y stack)) stack + +getFileSize :: String -> Int +getFileSize = read . head . words -test :: [(String, [String])] -> [(String, [[String]])] -test stack = map (\(x, y) -> (x, getTotalFilesForDir y stack)) stack +solve1 :: [(String, [String])] -> Int +solve1 s = sum $ filter (\x -> x <= 100000) $ map (\(_, y) -> sum $ map (getFileSize) y) s -parseInput :: IO [(String, [String])] -parseInput = readFile "./sample.txt" >>= return . getFilesInDir . cleanUpNav . lines +readInput :: IO [(String, [String])] +readInput = readFile "./sample.txt" >>= return . getDirNameContent . cleanUpNav . lines main :: IO () -main = undefined +main = readInput >>= print . solve1