-
Notifications
You must be signed in to change notification settings - Fork 0
/
day7.R
95 lines (85 loc) · 2.29 KB
/
day7.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
source("helpers.R")
txt <- readFile("input7.txt")
ls_mode <- FALSE
tree <- dictionary(lst = list(root = recollections::dictionary()))
path = c("?")
read_lines <- function(txt) {
ustrsplit(txt, "\n")
}
lines <- read_lines(txt)
get_current_dir <- function(tree, path) {
current_dir <- tree
for (dir in path[seq_len(length(path))]) {
if (dir != "") {
current_dir <- getValue(current_dir, dir)
} else {
current_dir <- getValue(current_dir, "root")
}
}
current_dir
}
run_command <- function(tree, command, arg) {
ls_mode <<- FALSE
if (command == "cd") {
if (arg == "/") {
path <<- c("")
} else {
if (arg == "..") {
path <<- path[seq_len(length(path) - 1L)]
} else {
current_dir <- get_current_dir(tree, path)
path <<- c(path, arg)
if (!arg %in% keys(current_dir)) {
setValue(current_dir, arg, recollections::dictionary())
}
}
}
} else if (command == "ls") {
ls_mode <<- TRUE
} else {
stop("Unknown command: ", command)
}
tree
}
read_output <- function(tree, path, file_spec, name) {
current_dir <- get_current_dir(tree, path)
if (file_spec == "dir") {
if (!name %in% keys(current_dir)) {
setValue(current_dir, name, recollections::dictionary())
}
} else {
setValue(current_dir, name, file_spec)
}
}
for (line in lines) {
parts <- ustrsplit(line, " ")
if (parts[[1L]] == "$") {
tree <- run_command(tree, parts[[2L]], parts[[3L]])
} else if (ls_mode) {
read_output(tree, path, parts[[1L]], parts[[2L]])
} else {
stop("Reading output but not in ls_mode")
}
}
sizes <- recollections::dictionary()
get_dir_sizes <- function(subtree, path) {
total_size <- 0L
for (file_name in keys(subtree)) {
file <- getValue(subtree, file_name)
if (is(file, "Dictionary")) {
size <- get_dir_sizes(file, paste(path, file_name, sep = "/"))
} else {
size <- as.integer(file)
}
total_size <- total_size + size
}
setValue(sizes, path, total_size)
total_size
}
get_dir_sizes(getValue(tree, "root"), "")
sizes <- sort(unlist(recollections::toList(sizes)))
cat_solution(13, sum(sizes[sizes <= 100000L]))
disk_size <- 70000000
free <- disk_size - tail(sizes, 1)
needed <- 30000000 - free
cat_solution(14, sizes[sizes >= needed][[1L]])