Browse Source

Minor day 11 optimisations

Calculate the power inline so we don't have to repeat the rack ID
etc every time; give in and use 1-based arrays instead of mapping
the 1-base back to 0-base.
master
Chris Smith 5 years ago
parent
commit
d137fdb031
1 changed files with 13 additions and 12 deletions
  1. 13
    12
      day11.nim

+ 13
- 12
day11.nim View File

@@ -1,21 +1,22 @@
1 1
 import math, sequtils, strscans, strutils
2 2
 
3
-func power(serial, x, y: int): int =
4
-    let rackId = x + 10
5
-    (rackId * y + serial) * rackId div 100 mod 10 - 5
6
-
7 3
 var
8 4
     serial = readFile("data/11.txt").strip.parseInt
9
-    prefixSum: array[-1..300, array[-1..300, int]]
5
+    prefixSum: array[301, array[301, int]]
10 6
 
11
-for x in 0..299:
12
-    for y in 0..299:
7
+for x in 1..300:
8
+    let serialByRack = (x + 10) * serial
9
+    let rackSquared = (x + 10) * (x + 10)
10
+    var tally = serialByRack
11
+    for y in 1..300:
12
+        tally.inc(rackSquared)
13
+        let power = tally div 100 mod 10 - 5
13 14
         # Construct a prefix sum of the grid: prefixSum[x][y] holds the sum of
14 15
         # all cells in the rectangle from (0,0) to (x,y). We calculate this
15 16
         # by adding the current cell to the rectangle above and the rectangle
16 17
         # to the left. This results in double-counting the rect between (0,0)
17 18
         # and (x-1,y-1), so we subtract that from the result.
18
-        prefixSum[x][y] = power(serial, x+1, y+1) + prefixSum[x][y-1] +
19
+        prefixSum[x][y] = power + prefixSum[x][y-1] +
19 20
                             prefixSum[x-1][y] - prefixSum[x-1][y-1]
20 21
 
21 22
 var
@@ -26,8 +27,8 @@ var
26 27
 
27 28
 for size in 1..300:
28 29
     let s1 = size - 1
29
-    for x in 0..300 - size:
30
-        for y in 0..300 - size:
30
+    for x in 1..300 - size:
31
+        for y in 1..300 - size:
31 32
             # To use the prefix sum to find the value of a rect, we take the
32 33
             # value for the lower right corner and subtract the rects to the
33 34
             # left and the top. Like when constructing the prefix sum this
@@ -37,10 +38,10 @@ for size in 1..300:
37 38
                         prefixSum[x+s1][y-1] + prefixSum[x-1][y-1]
38 39
             if sum > best:
39 40
                 best = sum
40
-                bestPos = $(x + 1) & "," & $(y + 1) & "," & $size
41
+                bestPos = $x & "," & $y & "," & $size
41 42
             if size == 3 and sum > bestThree:
42 43
                 bestThree = sum
43
-                bestThreePos = $(x + 1) & "," & $(y + 1)
44
+                bestThreePos = $x & "," & $y
44 45
 
45 46
 echo bestThreePos
46 47
 echo bestPos