aboutsummaryrefslogtreecommitdiffstats
path: root/day07/solution.nim
diff options
context:
space:
mode:
authorOrfeas <38209077+0xfea5@users.noreply.github.com>2024-06-08 13:50:47 +0300
committerOrfeas <38209077+0xfea5@users.noreply.github.com>2024-06-08 13:50:47 +0300
commit7be570c4a6e86fb7060f0bc06910ca57003dfe90 (patch)
treea998f976596cb902cd8988d74f756b72660bc29c /day07/solution.nim
parentDay 21 (part1) (diff)
downloadaoc22-7be570c4a6e86fb7060f0bc06910ca57003dfe90.tar.gz
aoc22-7be570c4a6e86fb7060f0bc06910ca57003dfe90.zip
Update file names and init.shHEADmain
Diffstat (limited to 'day07/solution.nim')
-rw-r--r--day07/solution.nim97
1 files changed, 97 insertions, 0 deletions
diff --git a/day07/solution.nim b/day07/solution.nim
new file mode 100644
index 0000000..e6f4643
--- /dev/null
+++ b/day07/solution.nim
@@ -0,0 +1,97 @@
1import std/strutils
2
3type
4 Command = string
5 # using LeFile for name because File already exists
6 LeFile = ref object
7 Size: int
8 Name: string
9
10type
11 Directory = ref object
12 Name: string
13 Files: seq[LeFile]
14 Parent: Directory
15 Subdirectories: seq[Directory]
16
17# Directory methods
18method cd(self: Directory, path: string): Directory =
19 if path == "..":
20 return self.Parent
21
22 for subdir in self.Subdirectories:
23 if subdir.Name == path:
24 return subdir
25
26method add(self: Directory, file: LeFile): void =
27 self.Files.add(file)
28
29method add(self: Directory, dir: Directory): void =
30 self.Subdirectories.add(dir)
31
32let total = 70_000_000
33var part1 = 0
34var minRemoved = total
35
36method size(self: Directory, freeThreshold = total): int =
37 var size = 0
38 for file in self.Files:
39 size += file.Size
40
41 for subdir in self.Subdirectories:
42 size += subdir.size(freeThreshold)
43
44 if size <= 100_000:
45 part1 += size
46
47 if size >= freeThreshold:
48 minRemoved = min(minRemoved, size)
49
50 return size
51
52proc run(root: Directory, input: seq[Command]): void =
53 # start pc from 1 to ignore "cd /" command thats coming first
54 var pc = 1
55 var current = root
56
57 let endpc = input.len()
58 while pc < endpc:
59 let command = input[pc]
60 assert(command[0] == '$')
61
62 let tokens = command.splitWhitespace()
63
64 case tokens[1]:
65 of "cd":
66 current = current.cd(tokens[2])
67 pc += 1
68 of "ls":
69 pc += 1
70 while pc < endpc:
71 let file = input[pc]
72 # end of file list
73 if file[0] == '$':
74 break
75
76 let fileInfo = file.splitWhitespace()
77 if fileInfo[0] == "dir":
78 current.add(Directory(Name: fileInfo[1], Files: @[], Parent: current, Subdirectories: @[]))
79 else:
80 current.add(LeFile(Size: fileInfo[0].parseInt(), Name: fileInfo[1]))
81 pc += 1
82 else:
83 assert(false)
84
85 return
86
87let content = readFile("./input.txt").strip().splitLines()
88
89var root = Directory(Name: "/", Files: @[], Parent: nil, Subdirectories: @[])
90run(root, content)
91
92let totalUsed = root.size()
93let totalFree = total - totalUsed
94discard root.size(30_000_000 - totalFree)
95
96echo part1
97echo minRemoved