Compare commits
2 Commits
fe8fe811c2
...
a4c25f5d1f
| Author | SHA1 | Date | |
|---|---|---|---|
| a4c25f5d1f | |||
| cadb7ccae1 |
19
day6.hs
19
day6.hs
@@ -4,18 +4,13 @@ main :: IO ()
|
|||||||
main = do
|
main = do
|
||||||
input <- readFile "day6.in"
|
input <- readFile "day6.in"
|
||||||
putStr "Q1: "
|
putStr "Q1: "
|
||||||
print $ q1 input
|
print $ parse 4 input
|
||||||
putStr "Q2: "
|
putStr "Q2: "
|
||||||
print $ q2 input
|
print $ parse 14 input
|
||||||
|
|
||||||
q1, q2 :: String -> Int
|
group :: Int -> [Char] -> [[Char]]
|
||||||
q1 = length . parse 4
|
group _ [] = []
|
||||||
q2 = length . parse 14
|
group n xs = take n xs : group n (tail xs)
|
||||||
|
|
||||||
parse :: Int -> String -> String
|
parse :: Int -> String -> Int
|
||||||
parse n a = parse' n (splitAt n a)
|
parse n = (+ n) . length . takeWhile ((< n) . length) . map nub . group n
|
||||||
|
|
||||||
parse' :: Int -> (String, String) -> String
|
|
||||||
parse' n (a, b)
|
|
||||||
| length (nub (drop (length a - n) a)) == n = a
|
|
||||||
| otherwise = parse' n (a ++ [head b], tail b)
|
|
||||||
|
|||||||
57
day7'.hs
Normal file
57
day7'.hs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import Data.Tree
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = do
|
||||||
|
tree <- flip parse (emptyFs "/") . map words . lines <$> readFile "day7.in"
|
||||||
|
putStr "Q1: "
|
||||||
|
print $
|
||||||
|
foldTree
|
||||||
|
( \x xs ->
|
||||||
|
if null xs || snd x > 100000 then sum xs else snd x + sum xs
|
||||||
|
)
|
||||||
|
tree
|
||||||
|
putStr "Q2: "
|
||||||
|
let maxStorage = 70000000
|
||||||
|
let spaceNeeded = 30000000 - (maxStorage - snd (rootLabel tree))
|
||||||
|
print $
|
||||||
|
foldTree
|
||||||
|
( \x xs ->
|
||||||
|
if snd x < spaceNeeded
|
||||||
|
then minimum (maxStorage : xs)
|
||||||
|
else minimum (snd x : xs)
|
||||||
|
)
|
||||||
|
tree
|
||||||
|
|
||||||
|
tail' :: [a] -> [a]
|
||||||
|
tail' = drop 1
|
||||||
|
|
||||||
|
emptyFs :: String -> Tree (String, Int)
|
||||||
|
emptyFs n = Node (n, 0) []
|
||||||
|
|
||||||
|
insertFs :: Tree (String, Int) -> String -> Tree (String, Int) -> Tree (String, Int)
|
||||||
|
insertFs (Node n xs) name dir = Node (fst n, snd n + snd (rootLabel dir)) (dir : xs)
|
||||||
|
|
||||||
|
totalSize :: [Tree (String, Int)] -> Int
|
||||||
|
totalSize = sum . map (snd . rootLabel)
|
||||||
|
|
||||||
|
ls :: [[String]] -> [Tree (String, Int)]
|
||||||
|
ls = map (\[a, b] -> Node (b, read a) []) . filter ((/= "dir") . head)
|
||||||
|
|
||||||
|
parse :: [[String]] -> Tree (String, Int) -> Tree (String, Int)
|
||||||
|
parse input fs = snd $ parse' input fs
|
||||||
|
|
||||||
|
parse' :: [[String]] -> Tree (String, Int) -> ([[String]], Tree (String, Int))
|
||||||
|
parse' input fs
|
||||||
|
| null input || cur !! 1 == "cd" && cur !! 2 == ".." = (tail' input, fs)
|
||||||
|
| cur !! 1 == "ls" =
|
||||||
|
let (children, rest) = span ((/= "$") . head) (tail' input)
|
||||||
|
childFs = ls children
|
||||||
|
name = fst $ rootLabel fs
|
||||||
|
in parse' rest (Node (name, totalSize childFs) childFs)
|
||||||
|
| otherwise =
|
||||||
|
let name = cur !! 2
|
||||||
|
(nextInput, newFs) = parse' (tail' input) (emptyFs name)
|
||||||
|
replaced = insertFs fs name newFs -- replace empty directory
|
||||||
|
in parse' nextInput replaced
|
||||||
|
where
|
||||||
|
cur = head input
|
||||||
65
day7.hs
Normal file
65
day7.hs
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import Data.Tree
|
||||||
|
|
||||||
|
-- this solution assumes that empty directories can exist,
|
||||||
|
-- if you want to ignore that, there is a slightly more compact code as day7'.hs
|
||||||
|
-- needs cleaning and improvement
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = do
|
||||||
|
tree <- flip parse (emptyFs "/") . map words . lines <$> readFile "day7.in"
|
||||||
|
putStr "Q1: "
|
||||||
|
print $
|
||||||
|
foldTree
|
||||||
|
( \x xs ->
|
||||||
|
if null xs || snd x > 100000 then sum xs else snd x + sum xs
|
||||||
|
)
|
||||||
|
tree
|
||||||
|
putStr "Q2: "
|
||||||
|
let maxStorage = 70000000
|
||||||
|
let spaceNeeded = 30000000 - (maxStorage - snd (rootLabel tree))
|
||||||
|
print $
|
||||||
|
foldTree
|
||||||
|
( \x xs ->
|
||||||
|
if snd x < spaceNeeded
|
||||||
|
then minimum (maxStorage : xs)
|
||||||
|
else minimum (snd x : xs)
|
||||||
|
)
|
||||||
|
tree
|
||||||
|
|
||||||
|
tail' :: [a] -> [a]
|
||||||
|
tail' = drop 1
|
||||||
|
|
||||||
|
emptyFs :: String -> Tree (String, Int)
|
||||||
|
emptyFs n = Node (n, 0) []
|
||||||
|
|
||||||
|
replaceFs :: Tree (String, Int) -> String -> Tree (String, Int) -> Tree (String, Int)
|
||||||
|
replaceFs (Node n xs) name fs =
|
||||||
|
let (h, t) = span ((/= name) . fst . rootLabel) xs
|
||||||
|
in Node
|
||||||
|
(fst n, snd n + snd (rootLabel fs))
|
||||||
|
(h ++ [fs] ++ tail' t)
|
||||||
|
|
||||||
|
totalSize :: [Tree (String, Int)] -> Int
|
||||||
|
totalSize = sum . map (snd . rootLabel)
|
||||||
|
|
||||||
|
ls :: [[String]] -> [Tree (String, Int)]
|
||||||
|
ls = map (\[a, b] -> if a == "dir" then Node (b, 0) [] else Node (b, read a) [])
|
||||||
|
|
||||||
|
parse :: [[String]] -> Tree (String, Int) -> Tree (String, Int)
|
||||||
|
parse input fs = snd $ parse' input fs
|
||||||
|
|
||||||
|
parse' :: [[String]] -> Tree (String, Int) -> ([[String]], Tree (String, Int))
|
||||||
|
parse' input fs
|
||||||
|
| null input || cur !! 1 == "cd" && cur !! 2 == ".." = (tail' input, fs)
|
||||||
|
| cur !! 1 == "ls" =
|
||||||
|
let (children, rest) = span ((/= "$") . head) (tail' input)
|
||||||
|
childFs = ls children
|
||||||
|
name = fst $ rootLabel fs
|
||||||
|
in parse' rest (Node (name, totalSize childFs) childFs)
|
||||||
|
| otherwise =
|
||||||
|
let name = cur !! 2
|
||||||
|
(nextInput, newFs) = parse' (tail' input) (emptyFs name)
|
||||||
|
replaced = replaceFs fs name newFs -- replace empty directory
|
||||||
|
in parse' nextInput replaced
|
||||||
|
where
|
||||||
|
cur = head input
|
||||||
Reference in New Issue
Block a user