Skip to content

Instantly share code, notes, and snippets.

@object
Created December 7, 2022 08:21
Show Gist options
  • Select an option

  • Save object/23f582b9cf6dfc451a2b2fd28e645496 to your computer and use it in GitHub Desktop.

Select an option

Save object/23f582b9cf6dfc451a2b2fd28e645496 to your computer and use it in GitHub Desktop.
Advent of Code 2022, December 7
#time "on"
open System
open System.IO
open System.Collections.Generic
let input =
File.ReadAllLines(__SOURCE_DIRECTORY__ + "/../data/input07.txt")
|> Seq.toList
let dirs = Dictionary<string,int64 list>()
let rec parseInput current_path (lines: string list) =
match lines with
| [] ->
dirs
| line :: lines ->
if line.StartsWith "$ cd " then
let dir = line.Substring(5)
if dir = "/" then
let path = "/"
if not (dirs.ContainsKey path) then
dirs.Add(path, [])
parseInput path lines
else if dir = ".." then
let items = current_path.Split "/"
let path = items |> Array.truncate (items.Length-1) |> fun x -> String.Join("/", x)
parseInput path lines
else
let path = if current_path = "/" then current_path + dir else current_path + "/" + dir
if not (dirs.ContainsKey path) then
dirs.Add(path, [])
parseInput path lines
else if line.StartsWith "$ ls" then
parseInput current_path lines
else if line.StartsWith "dir " then
parseInput current_path lines
else
let items = line.Split(" ")
let size = Int64.Parse items[0]
let name = items[1]
let current_dir = dirs[current_path]
dirs[current_path] <- size :: current_dir
parseInput current_path lines
let dir_sizes =
parseInput "/" input |> Seq.toList |> List.map (fun kv -> kv.Key, kv.Value)
|> List.map (fun (d, files) -> d, files |> List.sum)
let dir_sizes_with_subdirs =
dir_sizes
|> List.map (fun (d,s) ->
let subdirs = dir_sizes |> List.filter (fun (sd, _) -> sd.StartsWith d)
d, subdirs |> List.map snd |> List.sum)
// Part One
dir_sizes_with_subdirs |> List.filter (fun (d,s) -> s <= 100000L) |> List.map snd |> List.sum
// Part Two
let total_space = 70000000L
let unused_space = 30000000L
let free_space = dir_sizes_with_subdirs |> List.find (fun (d,_) -> d = "/") |> snd |> fun s -> total_space - s
let needed_space = unused_space - free_space
dir_sizes_with_subdirs |> List.filter (fun (d, s) -> s >= needed_space) |> List.minBy (fun (d, s) -> s - needed_space)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment