solve_day7 :: (test: bool) {
content := read_entire_file(ifx test then "inputs/day7_test.txt" else "inputs/day7.txt");
lines := split(content, "\n");
directories: Table(string, Directory);
part1: u64 = 0;
part2: u64 = 0;
current_dir: string = "/";
root_dir := table_add(*directories, "/", .{
name = "/",
parent = "/",
});
for line: lines {
if line[0] == {
case #char "$";
run_command(line, *current_dir, directories);
case #char "d";
dir_name := sprint("%0%0/", current_dir, slice(line, 4, line.count - 4));
new_dir_ptr := table_add(*directories, dir_name, .{
name = dir_name,
parent = current_dir,
});
current_dir_ptr := table_find_pointer(*directories, current_dir);
array_add(*current_dir_ptr.sub_dirs, new_dir_ptr.name);
case;
space_index := find_index_from_left(line, " ");
current_dir_ptr := table_find_pointer(*directories, current_dir);
file_ptr := array_add(*(current_dir_ptr.files));
<< file_ptr = .{
name = copy_string(slice(line, space_index, line.count - space_index)),
size = string_to_int(slice(line, 0, space_index), 10, u64),
};
current_dir_ptr.file_size_accum += file_ptr.size;
//print("%, %\n", << file_ptr, current_dir.file_size_accum);
}
}
dir_sizes: Table(string, u64);
part2 = calc_dir_sizes("/", directories, *dir_sizes);
needed_size := 30_000_000 - (70_000_000 - part2);
for v,k: dir_sizes {
if v < 100_000 part1 += v;
if needed_size < v part2 = min(part2, v);
}
print("Part 1: %\n", part1);
print("Part 2: %\n", part2);
}
calc_dir_sizes :: (curr: string, dirs: Table, dir_sizes: *Table) -> u64 {
accum: u64 = 0;
curr_dir,_ := table_find(*dirs, curr);
for sub_dir: curr_dir.sub_dirs {
accum += calc_dir_sizes(sub_dir, dirs, dir_sizes);
}
accum += curr_dir.file_size_accum;
table_add(dir_sizes, curr, accum);
return accum;
}
print_dir :: (dir: *Directory) {
print("%, size: %\n", dir.name, dir.sub_dirs.count);
for dir.sub_dirs {
//print_dir(it);
}
}
run_command :: (command: string, current_dir: *string, directories: Table) {
if slice(command, 2, 2) == {
case "ls";
return;
case "cd";
dir := slice(command, 5, command.count - 5);
if dir == "/" return;
current_dir_ptr := table_find_pointer(*directories, << current_dir);
if dir == ".." {
<< current_dir = current_dir_ptr.parent;
} else {
into := tprint("%0%0/", current_dir_ptr.name, dir);
<< current_dir = table_find_pointer(*directories, into).name;
}
case; assert(false, "Bad command: %", command);
}
}
Directory :: struct {
name: string;
parent: string;
file_size_accum: u64;
sub_dirs: [..]string;
files: [..]DFile;
}
DFile :: struct {
name: string;
size: u64;
}