{-# Language QuasiQuotes, ImportQualifiedPost, NumericUnderscores #-}
module Main where
import Data.List (tails)
import Data.List.NonEmpty (NonEmpty(..), (<|))
import Data.Map qualified as Map
import Data.Tree (Tree(..))
import Data.Tree qualified as Tree
import Advent (format)
type Path = [String]
type Input = [Either String [Either (Int, String) String]]
main :: IO ()
IO ()
main =
do input <- [format|2022 7
($ cd %s%n
|$ ls%n
(%u %s%n
|dir %s%n)*)*|]
let totalSizes = [([String], Int)] -> [Int]
lsToTotalSizes ([String]
-> [Either String [Either (Int, String) String]]
-> [([String], Int)]
summarizeLs [] [Either String [Either (Int, String) String]]
input)
print (sum [n | n <- totalSizes, n <= 100_000])
let minNeeded = [Int] -> Int
forall a. HasCallStack => [a] -> a
head [Int]
totalSizes Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
30_000_000 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
70_000_000
print (minimum [n | n <- totalSizes, n >= minNeeded])
lsToTotalSizes :: [(Path, Int)] -> [Int]
lsToTotalSizes :: [([String], Int)] -> [Int]
lsToTotalSizes [([String], Int)]
dirs = Map [String] Int -> [Int]
forall k a. Map k a -> [a]
Map.elems ((Int -> Int -> Int) -> [([String], Int)] -> Map [String] Int
forall k a. Ord k => (a -> a -> a) -> [(k, a)] -> Map k a
Map.fromListWith Int -> Int -> Int
forall a. Num a => a -> a -> a
(+) [([String]
d',Int
n) | ([String]
d,Int
n) <- [([String], Int)]
dirs, [String]
d' <- [String] -> [[String]]
forall a. [a] -> [[a]]
tails [String]
d])
summarizeLs ::
Path ->
Input ->
[(Path, Int)]
summarizeLs :: [String]
-> [Either String [Either (Int, String) String]]
-> [([String], Int)]
summarizeLs [String]
_ [] = []
summarizeLs [String]
_ (Left String
"/" : [Either String [Either (Int, String) String]]
xs) = [String]
-> [Either String [Either (Int, String) String]]
-> [([String], Int)]
summarizeLs [] [Either String [Either (Int, String) String]]
xs
summarizeLs [String]
cwd (Left String
".." : [Either String [Either (Int, String) String]]
xs) = [String]
-> [Either String [Either (Int, String) String]]
-> [([String], Int)]
summarizeLs (Int -> [String] -> [String]
forall a. Int -> [a] -> [a]
drop Int
1 [String]
cwd) [Either String [Either (Int, String) String]]
xs
summarizeLs [String]
cwd (Left String
dir : [Either String [Either (Int, String) String]]
xs) = [String]
-> [Either String [Either (Int, String) String]]
-> [([String], Int)]
summarizeLs (String
dir String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String]
cwd) [Either String [Either (Int, String) String]]
xs
summarizeLs [String]
cwd (Right [Either (Int, String) String]
ls : [Either String [Either (Int, String) String]]
xs) = ([String]
cwd, [Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Int
n | Left (Int
n,String
_) <- [Either (Int, String) String]
ls]) ([String], Int) -> [([String], Int)] -> [([String], Int)]
forall a. a -> [a] -> [a]
: [String]
-> [Either String [Either (Int, String) String]]
-> [([String], Int)]
summarizeLs [String]
cwd [Either String [Either (Int, String) String]]
xs