aboutsummaryrefslogtreecommitdiffstats
path: root/day14/solution.nim
diff options
context:
space:
mode:
authorAn0nSaiko <porfeas12@gmail.com>2022-12-14 16:23:54 +0200
committerAn0nSaiko <porfeas12@gmail.com>2022-12-14 16:23:54 +0200
commitb383a7aa3497c0ad113949563688ecdc249ed7bc (patch)
tree79f07fd0ee498b8dbbc55341f839e962abb43c28 /day14/solution.nim
parentDay 13 (diff)
downloadaoc22-b383a7aa3497c0ad113949563688ecdc249ed7bc.tar.gz
aoc22-b383a7aa3497c0ad113949563688ecdc249ed7bc.zip
Day 14
Diffstat (limited to 'day14/solution.nim')
-rw-r--r--day14/solution.nim111
1 files changed, 111 insertions, 0 deletions
diff --git a/day14/solution.nim b/day14/solution.nim
new file mode 100644
index 0000000..0056704
--- /dev/null
+++ b/day14/solution.nim
@@ -0,0 +1,111 @@
1import strutils
2import sequtils
3import sets
4import strformat
5
6type Point = tuple[row: int, col: int]
7
8proc has(occupied: HashSet[Point], point: Point): bool =
9 point in occupied
10
11proc parsePoint(point: string): Point =
12 let tokens = point.split(",")
13 assert(tokens.len() == 2)
14 Point((tokens[1].parseInt(), tokens[0].parseInt()))
15
16proc parseLine(line: string): seq[Point] =
17 map(line.replace("-> ").split(" "), parsePoint)
18
19var maxRow = -1
20var maxCol = -1
21var minCol = 10000
22proc parseFile(content: string): HashSet[Point] =
23 let lines = content.strip.splitLines()
24 var rockLists = map(lines, parseLine)
25
26 for row in rockLists:
27 for point in row:
28 maxRow = max(maxRow, point.row)
29 maxCol = max(maxCol, point.col)
30 minCol = min(minCol, point.col)
31
32 for rocks in rockLists:
33 # a = begin, b = end
34 for i, a in rocks[0..^2]:
35 let b = rocks[i+1]
36 echo fmt"a = {a}, b = {b}"
37 for col in min(a.col, b.col) .. max(a.col, b.col):
38 let toPush = Point((a.row, col))
39 result.incl(toPush)
40
41 for row in min(a.row, b.row) .. max(a.row, b.row):
42 let toPush = Point((row, a.col))
43 result.incl(toPush)
44
45proc draw(occupied: HashSet[Point]): void =
46 for row in 0 .. maxRow:
47 var line = ""
48 for col in minCol .. maxCol:
49 let current = Point((row, col))
50 line &= (if occupied.has(current): '#' else: '.')
51
52 echo line
53
54proc below(point: Point): Point =
55 Point((point.row+1, point.col))
56
57proc rbelow(point: Point): Point =
58 Point((point.row+1, point.col+1))
59
60proc lbelow(point: Point): Point =
61 Point((point.row+1, point.col-1))
62
63proc outOfBounds(point: Point): bool =
64 point.row > maxRow
65
66var part2 = false
67proc drop(occupied: var HashSet[Point], col: int): bool =
68 var point = Point((0, col))
69
70 if part2 and occupied.has(point):
71 return false
72
73 while true:
74 let
75 below = point.below()
76 rbelow = point.rbelow()
77 lbelow = point.lbelow()
78
79 if point.outOfBounds():
80 if part2:
81 break
82 return false
83
84 if not occupied.has(below):
85 point = below
86 continue
87 if not occupied.has(lbelow):
88 point = lbelow
89 continue
90
91 if not occupied.has(rbelow):
92 point = rbelow
93 continue
94
95 break
96 occupied.incl(point)
97 return true
98
99proc solve(occupied: HashSet[Point]): int =
100 var occupied = occupied
101 while drop(occupied, 500):
102 result += 1
103
104let content = readFile("./input.txt")
105let occupied = parseFile(content)
106
107occupied.draw()
108echo fmt"{maxRow}, {minCol}-{maxCol}"
109echo solve(occupied)
110part2 = true
111echo solve(occupied)