86 lines
2.1 KiB
Nim
86 lines
2.1 KiB
Nim
|
import std/strutils
|
||
|
import std/sequtils
|
||
|
import std/re
|
||
|
|
||
|
type
|
||
|
DirEntry = ref object
|
||
|
parent: DirEntry
|
||
|
name: string
|
||
|
dirs: seq[DirEntry]
|
||
|
files: seq[FileEntry]
|
||
|
FileEntry = ref object
|
||
|
name: string
|
||
|
size: int
|
||
|
|
||
|
|
||
|
proc mkcd(a: DirEntry, name: string): DirEntry =
|
||
|
for i in 0.. (a.dirs.len() - 1):
|
||
|
if a.dirs[i].name == name:
|
||
|
return a.dirs[i]
|
||
|
a.dirs.add(DirEntry(parent: a, name: name, dirs: @[], files: @[]))
|
||
|
return a.dirs[len(a.dirs)-1]
|
||
|
|
||
|
proc recursive_size(a: DirEntry): int =
|
||
|
var sz = 0
|
||
|
for d in a.dirs:
|
||
|
sz += d.recursive_size()
|
||
|
for f in a.files:
|
||
|
sz += f.size
|
||
|
return sz
|
||
|
|
||
|
proc sum_size_sub(a: DirEntry, max: int): int =
|
||
|
let sz = a.recursive_size()
|
||
|
var res = 0
|
||
|
if sz < max:
|
||
|
res += sz
|
||
|
for d in a.dirs:
|
||
|
res += d.sum_size_sub(max)
|
||
|
return res
|
||
|
|
||
|
proc print(a: DirEntry, indent: int) =
|
||
|
echo ' '.repeat(indent*2), a.name, " (sz = ", a.recursive_size(), " )"
|
||
|
echo ' '.repeat(indent*2), "{"
|
||
|
for f in a.files:
|
||
|
echo ' '.repeat(indent*2+2), "[F] ", f.name, " (sz = ", f.size, " )"
|
||
|
for d in a.dirs:
|
||
|
d.print(indent+1)
|
||
|
echo ' '.repeat(indent*2), "}"
|
||
|
|
||
|
|
||
|
proc run07_1(): string =
|
||
|
const input = staticRead"../input/day07.txt"
|
||
|
|
||
|
let lines = splitLines(input).filter(proc(p: string): bool = p != "")
|
||
|
|
||
|
var root = DirEntry(parent: nil, name: "/", dirs: @[], files: @[])
|
||
|
|
||
|
var curr = root
|
||
|
|
||
|
for line in lines:
|
||
|
if line == "$ cd ..":
|
||
|
curr = curr.parent
|
||
|
elif line.startsWith("$ cd "):
|
||
|
curr = curr.mkcd(line.substr(5))
|
||
|
elif line == "$ ls":
|
||
|
continue
|
||
|
elif line.startsWith("dir "):
|
||
|
discard curr.mkcd(line.substr(4))
|
||
|
elif line.match(re"^[0-9].*"):
|
||
|
let split = line.split(" ")
|
||
|
curr.files.add(FileEntry(name: split[1], size: parseInt(split[0])))
|
||
|
else:
|
||
|
echo "UNKNOWN LINE: " & line
|
||
|
|
||
|
|
||
|
# echo root.recursive_size()
|
||
|
# root.print(0)
|
||
|
|
||
|
return intToStr(root.sum_size_sub(100000))
|
||
|
|
||
|
|
||
|
when not defined(js):
|
||
|
echo run07_1()
|
||
|
else:
|
||
|
proc js_run07_1(): cstring {.exportc.} =
|
||
|
return cstring(run07_1())
|