-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay6.nim
131 lines (104 loc) · 2.69 KB
/
Day6.nim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
from std/sequtils import toSeq
from std/enumerate import enumerate
from std/strformat import fmt
import std/sets
type
Direction = enum
left, right, up, down
VisitedCoordinate = object
x: int
y: int
direction: Direction
proc readInput(): seq[seq[char]] =
let file = open("data/day6.txt")
defer: file.close()
var line: string
var list: seq[seq[char]] = @[]
while file.readLine(line):
list.add(toSeq(line.items))
return list
proc xDiff(dir: Direction): int =
result = case dir:
of Direction.up:
-1
of Direction.down:
1
of Direction.left, Direction.right:
0
proc yDiff(dir: Direction): int =
result = case dir:
of Direction.left:
-1
of Direction.right:
1
of Direction.up, Direction.down:
0
proc newDirection(dir: Direction): Direction =
result = case dir:
of Direction.up:
Direction.right
of Direction.down:
Direction.left
of Direction.left:
Direction.up
of Direction.right:
Direction.down
proc prettyPrint(x: seq[seq[char]]) =
for row in x:
echo cast[string](row)
echo '-'
proc walkaround(data_original: seq[seq[char]], startingX: int, startingY: int): int =
var data = data_original.deepCopy()
var visited = initHashSet[VisitedCoordinate]()
var visitedPositions = initHashSet[array[0..1, int]]()
var
currentDirection: Direction = Direction.up
x: int = startingX
y: int = startingY
while true:
let nextX = x + xDiff(currentDirection)
let nextY = y + yDiff(currentDirection)
if visited.contains(VisitedCoordinate(x: nextX, y: nextY, direction: currentDirection)):
return -1
var spot: char
try:
spot = data[nextX][nextY]
if spot != '#':
data[nextX][nextY] = 'X'
except:
break
case spot:
of '.', 'X':
# Move
x = nextX
y = nextY
of '#':
# Bumped into obstacle
currentDirection = newDirection(currentDirection)
continue
else:
discard
visited.incl(VisitedCoordinate(x: x, y: y, direction: currentDirection))
visitedPositions.incl([x, y])
return visitedPositions.len
let data = readInput()
var
startingX: int = -1
startingY: int = -1
# Find the guard
block find:
for i, row in enumerate(data):
for j, spot in enumerate(row):
if spot == '^':
startingX = i
startingY = j
break find
echo walkaround(data, startingX, startingY)
var part2 = 0
for i in countup(0, data.len - 1):
for j in countup(0, data[0].len - 1):
var data_copy = data.deepCopy()
data_copy[i][j] = '#'
if walkaround(data_copy, startingX, startingY) == -1:
part2 += 1
echo part2