-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsolution.nim
123 lines (109 loc) · 2.95 KB
/
solution.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
import std/[
algorithm,
bitops,
deques,
heapqueue,
intsets,
json,
lists,
math,
rdstdin,
re,
sequtils,
sets,
strformat,
strutils,
tables,
sugar,
]
type
Point = tuple[position: (int, int), velocity: (int, int)]
proc parseLine(line: string): Point =
if line =~ re"position=<\s*(-?\d+),\s*(-?\d+)> velocity=<\s*(-?\d+),\s*(-?\d+)>":
let m = matches[0 ..< 4].mapIt(it.parseInt)
((m[0], m[1]), (m[2], m[3]))
else:
raise newException(ValueError, "parse error: " & line)
proc parse(input: string): seq[Point] =
input.split("\n").mapIt(it.parseLine)
when defined(test):
let input = """
position=< 9, 1> velocity=< 0, 2>
position=< 7, 0> velocity=<-1, 0>
position=< 3, -2> velocity=<-1, 1>
position=< 6, 10> velocity=<-2, -1>
position=< 2, -4> velocity=< 2, 2>
position=<-6, 10> velocity=< 2, -2>
position=< 1, 8> velocity=< 1, -1>
position=< 1, 7> velocity=< 1, 0>
position=<-3, 11> velocity=< 1, -2>
position=< 7, 6> velocity=<-1, -1>
position=<-2, 3> velocity=< 1, 0>
position=<-4, 3> velocity=< 2, 0>
position=<10, -3> velocity=<-1, 1>
position=< 5, 11> velocity=< 1, -2>
position=< 4, 7> velocity=< 0, -1>
position=< 8, -2> velocity=< 0, 1>
position=<15, 0> velocity=<-2, 0>
position=< 1, 6> velocity=< 1, 0>
position=< 8, 9> velocity=< 0, -1>
position=< 3, 3> velocity=<-1, 1>
position=< 0, 5> velocity=< 0, -1>
position=<-2, 2> velocity=< 2, 0>
position=< 5, -2> velocity=< 1, 2>
position=< 1, 4> velocity=< 2, 1>
position=<-2, 7> velocity=< 2, -2>
position=< 3, 6> velocity=<-1, -1>
position=< 5, 0> velocity=< 1, 0>
position=<-6, 0> velocity=< 2, 0>
position=< 5, 9> velocity=< 1, -2>
position=<14, 7> velocity=<-2, 0>
position=<-3, 6> velocity=< 2, -1>
""".strip
block:
let points = input.parse
doAssert points[0] == ((9, 1), (0, 2))
doAssert points[1] == ((7, 0), (-1, 0))
proc move(p: Point, t: int): Point =
let (pos, vec) = p
let (x, y) = pos
let (vx, vy) = vec
((x + vx * t, y + vy * t), vec)
proc move(points: seq[Point], t: int): seq[Point] =
points.mapIt(it.move(t))
proc print(points: seq[Point]): bool =
var minX, minY = int.high
var maxX, maxY = int.low
for (pos, vec) in points:
let (x, y) = pos
minX = minX.min x
maxX = maxX.max x
minY = minY.min y
maxY = maxY.max y
let cols = maxX - minX + 1
let rows = maxY - minY + 1
if rows > 100 or cols > 100: return false
var grid = newSeqWith(rows, ".".repeat(cols))
for (pos, vec) in points:
let (x, y) = pos
grid[y - minY][x - minX] = '#'
echo grid.join("\n")
true
when defined(test):
block:
let points = input.parse
print(points.move(3))
proc part1(input: string) =
let points = input.parse
var t = 0
while true:
t += 1
if print(points.move(t)):
echo t
var line = ""
let ok = readLineFromStdin("", line)
if not ok: break
when isMainModule and not defined(test):
let input = readFile("input").strip
part1(input)
# echo part2(input)