From c6b298b561c66f1b3255baee071ad6c058ea4e66 Mon Sep 17 00:00:00 2001 From: Brian Chu Date: Wed, 7 Dec 2022 19:27:50 -0800 Subject: solution for day 7 --- Program.fs | 2 ++ solutions/day7.fs | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 solutions/day7.fs diff --git a/Program.fs b/Program.fs index f132094..7d12388 100644 --- a/Program.fs +++ b/Program.fs @@ -20,5 +20,7 @@ match (day, part) with | (5, 2) -> printf $"{Day5.part2 ()}\n" | (6, 1) -> printf $"{Day6.part1 ()}\n" | (6, 2) -> printf $"{Day6.part2 ()}\n" +| (7, 1) -> printf $"{Day7.part1 ()}\n" +| (7, 2) -> printf $"{Day7.part2 ()}\n" | (x, y) when (1 <= x && x <= 25) && (y = 1 || y = 2) -> raise (NotImplemented("not implemented yet")) | _ -> raise (NotImplemented("invalid values")) \ No newline at end of file diff --git a/solutions/day7.fs b/solutions/day7.fs new file mode 100644 index 0000000..622c54c --- /dev/null +++ b/solutions/day7.fs @@ -0,0 +1,56 @@ +namespace Solutions + +module Day7 = + open System.IO + open System.Text.RegularExpressions + + type Listing = + | LS + | CD of target: string + | Dir of name: string + | File of name: string * size: int + + let (|RegexMatch|_|) pattern line = + let matched = Regex.Match(line, pattern) + if matched.Success then + let groups = + matched.Groups |> Seq.map (fun x -> x.Value) |> Seq.tail |> List.ofSeq + Some groups + else None + + let parseListing = function + | RegexMatch "\$ cd (\/|\S+)" args -> CD args[0] + | RegexMatch "\$ ls" [] -> LS + | RegexMatch "dir (\S+)" name -> Dir name[0] + | RegexMatch "(\d+) (\S+)" data -> File (data[1], int data[0]) + | _ -> failwith "shouldn't happen" + + let input = File.ReadLines("inputs/day7.txt") |> Seq.map parseListing |> List.ofSeq + + + let dirSizes listings = + let processListing (pwd, tree) listing = + match listing with + | CD ".." -> (List.tail pwd, tree) + | CD target -> (target::pwd, tree) + | File (name, size) -> + let rec addFileSize rem dirs = + match rem with + | [] -> dirs + | _ :: t -> + let addIfExists current = defaultArg current 0 + size + let newDirs = Map.change rem (addIfExists >> Some) dirs + addFileSize t newDirs + pwd, addFileSize pwd tree + | _ -> pwd, tree + listings |> List.fold processListing ([], Map.empty) |> snd + + let part1 () = dirSizes input |> Map.values |> Seq.filter (fun size -> size <= 100000) |> Seq.sum + + let part2 () = + let sizes = dirSizes input + let totalSpace = 70000000 + let targetSpace = 30000000 + let usedSpace = sizes[[ "/" ]] + let needToFree = usedSpace - (totalSpace - targetSpace) + sizes.Values |> Seq.sort |> Seq.find (fun x -> x >= needToFree) \ No newline at end of file -- cgit 1.4.1-2-gfad0