Browse Source

Optimise day 10

master
Chris Smith 5 years ago
parent
commit
6ce0442f34
1 changed files with 28 additions and 15 deletions
  1. 28
    15
      day10.nim

+ 28
- 15
day10.nim View File

@@ -1,20 +1,35 @@
1 1
 import math, sequtils, strscans, strutils
2 2
 
3
+# Expected height of our letters
4
+const LetterHeight = 10
5
+
3 6
 type
4 7
     Point = ref object
5
-        x, y, dx, dy: int
8
+        sx, sy, x, y, dx, dy: int
6 9
 
7
-var points: seq[Point]
10
+var
11
+    points: seq[Point]
12
+    miny = int.high
13
+    maxy = int.low
14
+    mindy, maxdy = 0
8 15
 
9 16
 for line in readFile("data/10.txt").strip.splitlines:
10 17
     var point = new(Point)
11
-    if not line.scanf("position=<$s$i,$s$i> velocity=<$s$i,$s$i>", point.x, point.y, point.dx, point.dy):
18
+    if not line.scanf("position=<$s$i,$s$i> velocity=<$s$i,$s$i>", point.sx, point.sy, point.dx, point.dy):
12 19
         raise newException(Defect,  "Invalid input line: " & line)
20
+    if point.sy < miny:
21
+        miny = point.sy
22
+        mindy = point.dy
23
+    if point.sy > maxy:
24
+        maxy = point.sy
25
+        maxdy = point.dy
13 26
     points.add(point)
14 27
 
15
-var
16
-    t = 0
17
-    last_distance = int.high
28
+# Compute the first time at which the most outlying stars will be within
29
+# letter-height of each other. It may take a few more iterations after
30
+# this for them to get into their final place.
31
+var t = (maxy - miny - LetterHeight) div (mindy - maxdy)
32
+
18 33
 while true:
19 34
     var
20 35
         minx = int.high
@@ -22,20 +37,19 @@ while true:
22 37
         miny = int.high
23 38
         maxy = int.low
24 39
     for point in points:
25
-        point.x += point.dx
26
-        point.y += point.dy
40
+        point.x = point.sx + point.dx * t
41
+        point.y = point.sy + point.dy * t
27 42
         minx = min(minx, point.x)
28 43
         maxx = max(maxx, point.x)
29 44
         miny = min(miny, point.y)
30 45
         maxy = max(maxy, point.y)
31 46
 
32
-    var distance = (maxx - minx) * (maxy - miny)
33
-    if distance > last_distance:
47
+    if maxy - miny == LetterHeight - 1:
34 48
         for y in miny..maxy:
35 49
             var grid = newSeq[bool](1 + maxx - minx)
36 50
             for point in points:
37
-                if point.y - point.dy == y:
38
-                    grid[point.x - point.dx - minx] = true
51
+                if point.y == y:
52
+                    grid[point.x - minx] = true
39 53
             echo grid.map(proc(cell: bool): string =
40 54
                 if cell:
41 55
                     "█"
@@ -43,6 +57,5 @@ while true:
43 57
                     " ").join
44 58
         echo t
45 59
         break
46
-    else:
47
-        last_distance = distance
48
-        t.inc
60
+    
61
+    t.inc