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
 import math, sequtils, strscans, strutils
1
 import math, sequtils, strscans, strutils
2
 
2
 
3
+# Expected height of our letters
4
+const LetterHeight = 10
5
+
3
 type
6
 type
4
     Point = ref object
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
 for line in readFile("data/10.txt").strip.splitlines:
16
 for line in readFile("data/10.txt").strip.splitlines:
10
     var point = new(Point)
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
         raise newException(Defect,  "Invalid input line: " & line)
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
     points.add(point)
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
 while true:
33
 while true:
19
     var
34
     var
20
         minx = int.high
35
         minx = int.high
22
         miny = int.high
37
         miny = int.high
23
         maxy = int.low
38
         maxy = int.low
24
     for point in points:
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
         minx = min(minx, point.x)
42
         minx = min(minx, point.x)
28
         maxx = max(maxx, point.x)
43
         maxx = max(maxx, point.x)
29
         miny = min(miny, point.y)
44
         miny = min(miny, point.y)
30
         maxy = max(maxy, point.y)
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
         for y in miny..maxy:
48
         for y in miny..maxy:
35
             var grid = newSeq[bool](1 + maxx - minx)
49
             var grid = newSeq[bool](1 + maxx - minx)
36
             for point in points:
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
             echo grid.map(proc(cell: bool): string =
53
             echo grid.map(proc(cell: bool): string =
40
                 if cell:
54
                 if cell:
41
                     "█"
55
                     "█"
43
                     " ").join
57
                     " ").join
44
         echo t
58
         echo t
45
         break
59
         break
46
-    else:
47
-        last_distance = distance
48
-        t.inc
60
+    
61
+    t.inc