summary refs log tree commit diff stats
path: root/solutions
diff options
context:
space:
mode:
authorBrian Chu <brianmchu42@gmail.com>2022-12-07 19:27:50 -0800
committerBrian Chu <brianmchu42@gmail.com>2022-12-07 22:43:51 -0800
commitc6b298b561c66f1b3255baee071ad6c058ea4e66 (patch)
treefded91865051a6db32c156214c98fa1f2cb5eaec /solutions
parent0f4c87139ea2099d000d59ab0acf9307011a9af0 (diff)
downloadAdventOfCode2022-c6b298b561c66f1b3255baee071ad6c058ea4e66.tar.gz
solution for day 7
Diffstat (limited to 'solutions')
-rw-r--r--solutions/day7.fs56
1 files changed, 56 insertions, 0 deletions
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