Parsing the file:
filename = get(ARGS, 1, "sample_input")
input = open(f -> read(f, String), filename) |> chomp |> i -> split(i, "\n")
23-element Vector{SubString{String}}: "\$ cd /" "\$ ls" "dir a" "14848514 b.txt" "8504156 c.dat" "dir d" "\$ cd a" "\$ ls" "dir e" "29116 f" ⋮ "584 i" "\$ cd .." "\$ cd .." "\$ cd d" "\$ ls" "4060174 j" "8033020 d.log" "5626152 d.ext" "7214296 k"
Custom fetch for deeply-nested Dicts (thanks ChatGPT)
function custom_fetch(keys, dict)
key = keys[1]
value = get(dict, key, Dict())
# if there is only one key in the list of keys, return the value
if length(keys) == 1
return value
end
remaining_keys = keys[2:end]
return custom_fetch(remaining_keys, value)
end
custom_fetch (generic function with 1 method)
Custom updated for deeply-nested Dicts (thanks ChatGPT)
function custom_update(keys, value, dict)
key = keys[1]
curr_value = get(dict, key, Dict())
# if there is only one key in the list of keys, update the value in the
# Dictionary and return the updated Dictionary
if length(keys) == 1
dict[key] = value
return dict
end
# if there are more keys in the list of keys, recursively call the
# `custom_update()` function with the remaining keys, the value, and
# the current value (which should be a nested Dictionary)
remaining_keys = keys[2:end]
curr_value = custom_update(remaining_keys, value, curr_value)
dict[key] = curr_value
return dict
end
custom_update (generic function with 1 method)
Let’s format dirs with / appended
root = Dict()
current_dir = ""
current_path = []
for cmd in input
if startswith(cmd, "\$")
if cmd == "\$ cd .."
global current_dir = pop!(current_path)
elseif startswith(cmd, "\$ cd")
global current_dir = replace(cmd, "\$ cd " => "")
push!(current_path, current_dir)
end
elseif startswith(cmd, r"[1-9]")
(size, local_filename) = split(cmd, " ")
existing_files = custom_fetch(current_path, root)
global root = custom_update(vcat(current_path, [local_filename]), parse(Int, size), root)
end
end
root
Dict{Any, Any} with 1 entry: "/" => Dict{Any, Any}("b.txt"=>14848514, "a"=>Dict{Any, Any}("f"=>29116, "g"=…
Custom check file sizes function for deeply-nested Dicts (thanks ChatGPT)
function check_size(folder)
# initialize the total size to 0
total_size = 0
# iterate over the key-value pairs in the folder
for (key, value) in pairs(folder)
# check if the value is a dictionary (i.e., a folder)
if isa(value, Dict)
# if it is a folder, recursively check the size of the folder
total_size += check_size(value)
else
# if it is not a folder, it must be a file, so add its size to the total
total_size += value
end
end
# return the total size of the folder
return total_size
end
check_size (generic function with 1 method)
Iterating over all folders
folders = []
function parse_folders(folder)
for (key, value) in folder
# check for folder
if isa(value, Dict)
push!(folders, check_size(folder[key]))
parse_folders(folder[key])
end
end
end
parse_folders(root)
folders
4-element Vector{Any}: 48381165 94853 584 24933642
Filtering folders
println("Part 1: ", folders |> f -> filter(v -> v < 100000, f) |> values |> sum)
Part 1: 95437
min_size = 30000000 - (70000000 - check_size(root["/"]))
println("Part 2: ", folders |> f -> filter(v -> v > min_size, f) |> minimum)
Part 2: 24933642