aboutsummaryrefslogtreecommitdiffstats
path: root/day18/solution.nim
diff options
context:
space:
mode:
Diffstat (limited to 'day18/solution.nim')
-rw-r--r--day18/solution.nim83
1 files changed, 83 insertions, 0 deletions
diff --git a/day18/solution.nim b/day18/solution.nim
new file mode 100644
index 0000000..0ef81fb
--- /dev/null
+++ b/day18/solution.nim
@@ -0,0 +1,83 @@
1import strutils
2import sequtils
3import sugar
4import sets
5
6type Cube = tuple
7 x, y, z: int
8
9proc parseLine(line: string): Cube =
10 let tokens = map(line.split(","), (e) => e.parseInt())
11 (tokens[0], tokens[1], tokens[2])
12
13proc parseFile(content: string): seq[Cube] =
14 let lines = content.strip().splitLines()
15 result = map(lines, parseLine)
16
17proc nextTo(A, B: Cube): bool =
18 let
19 dx = abs(A.x - B.x)
20 dy = abs(A.y - B.y)
21 dz = abs(A.z - B.z)
22
23 dx + dy + dz <= 1 and dx <= 1 and dy <= 1 and dz <= 1
24
25proc part1(cubes: seq[Cube]): int =
26 result = 6 * cubes.len()
27 for i, cube in cubes[0 .. ^2]:
28 for other in cubes[i+1 .. ^1]:
29 if cube.nextTo(other):
30 result -= 2
31
32var
33 solid: HashSet[Cube]
34 visited: HashSet[Cube]
35 maxn = 0
36 minn = -1
37
38proc blocksAround(cube: Cube): int =
39 for x in [cube.x-1, cube.x+1]:
40 if (x, cube.y, cube.z) in solid:
41 result += 1
42
43 for y in [cube.y-1, cube.y+1]:
44 if (cube.x, y, cube.z) in solid:
45 result += 1
46
47 for z in [cube.z-1, cube.z+1]:
48 if (cube.x, cube.y, z) in solid:
49 result += 1
50
51proc dfs(curr: Cube): int =
52 let maxp = max([curr.x, curr.y, curr.z])
53 let minp = min([curr.x, curr.y, curr.z])
54 if minp < minn or maxp >= maxn or visited.containsOrIncl(curr):
55 return 0
56
57 # if is air block
58 if curr notin solid:
59 result = blocksAround(curr) +
60 dfs((curr.x+1, curr.y, curr.z)) +
61 dfs((curr.x-1, curr.y, curr.z)) +
62 dfs((curr.x, curr.y+1, curr.z)) +
63 dfs((curr.x, curr.y-1, curr.z)) +
64 dfs((curr.x, curr.y, curr.z+1)) +
65 dfs((curr.x, curr.y, curr.z-1))
66
67
68proc part2(cubes: seq[Cube]): int =
69 # echo cubes
70 for cube in cubes:
71 maxn = max([cube.x, cube.y, cube.z])
72 maxn += 6
73
74 for cube in cubes:
75 solid.incl(cube)
76
77 result = dfs((0,0,0))
78
79let content = readFile("./input.txt")
80let input = parseFile(content)
81
82echo part1(input)
83echo part2(input)