This commit is contained in:
Danny Hpy 2023-02-26 19:35:15 +01:00
parent 7e06788d8d
commit a15606d934
Signed by: dannyhpy
GPG Key ID: 7139FBBEA22D1CEC
1 changed files with 105 additions and 0 deletions

105
2022/07/both.nim Normal file
View File

@ -0,0 +1,105 @@
import
std/strutils,
std/strformat,
std/tables
import
../../adventofcode
proc `/`(base, tail: string): string =
if tail == "..":
let sep = base.rfind('/')
if sep > 0: return base[0 ..< sep]
else: return "/"
else:
if base[^1] == '/':
return base & tail
else:
return base & "/" & tail
type
PseudoFileKind = enum
pfFile, pfDir
PseudoFile = ref object
case kind: PseudoFileKind
of pfFile:
size: Natural
of pfDir:
fileNames: seq[string]
proc newPseudoFile(size: Natural = 0): PseudoFile =
result = PseudoFile(kind: pfFile, size: size)
proc newPseudoDir(): PseudoFile =
result = PseudoFile(kind: pfDir)
let input = adventofcode.getInput()
var files = initTable[string, PseudoFile]()
var dirSizes = initTable[string, Natural]()
var cwd = "/"
var cwdObj = newPseudoDir()
files["/"] = cwdObj
proc computeSize(path: string): Natural =
if not files.hasKey path: return
let file = files[path]
case file.kind
of pfFile: return file.size
of pfDir:
if dirSizes.hasKey path:
return dirSizes[path]
for name in file.fileNames:
result += computeSize(path / name)
dirSizes[path] = result
for line in input.splitLines:
let args = line.splitWhitespace()
if args[0] == "$":
if args[1] == "cd":
if args[2][0] == '/':
cwd = args[2]
else:
cwd = cwd / args[2]
when not defined(release):
echo fmt"{cwd = }"
if files.hasKey cwd:
cwdObj = files[cwd]
else:
cwdObj = newPseudoDir()
files[cwd] = cwdObj
else:
if args[1] notin cwdObj.fileNames:
cwdObj.fileNames.add args[1]
if args[0] == "dir":
let dir = newPseudoDir()
files[cwd / args[1]] = dir
else:
let file = newPseudoFile(size=parseInt args[0])
files[cwd / args[1]] = file
when not defined(second):
var sum = 0
discard computeSize "/"
for path, dirSize in dirSizes:
if dirSize < 100_000:
sum += dirSize
echo fmt"Answer: {sum}"
else:
import
std/algorithm,
std/sequtils
const maxFsSize = 70_000_000
const updateSize = 30_000_000
let currFsSize = computeSize "/"
let requiredSize = currFsSize - (maxFsSize - updateSize)
when not defined(release):
echo fmt"{requiredSize = }"
let dirSizesSeq = sorted toSeq dirSizes.values()
for size in dirSizesSeq:
if size > requiredSize:
echo fmt"Answer: {size}"
break