Browse Source

Day 11

master
Chris Smith 5 years ago
parent
commit
46b2a06b3b
3 changed files with 49 additions and 0 deletions
  1. 2
    0
      answers/11.txt
  2. 1
    0
      data/11.txt
  3. 46
    0
      day11.nim

+ 2
- 0
answers/11.txt View File

@@ -0,0 +1,2 @@
1
+20,43
2
+233,271,13

+ 1
- 0
data/11.txt View File

@@ -0,0 +1 @@
1
+1309

+ 46
- 0
day11.nim View File

@@ -0,0 +1,46 @@
1
+import math, sequtils, strscans, strutils
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
+var
8
+    serial = readFile("data/11.txt").strip.parseInt
9
+    prefixSum: array[-1..300, array[-1..300, int]]
10
+
11
+for x in 0..299:
12
+    for y in 0..299:
13
+        # Construct a prefix sum of the grid: prefixSum[x][y] holds the sum of
14
+        # all cells in the rectangle from (0,0) to (x,y). We calculate this
15
+        # by adding the current cell to the rectangle above and the rectangle
16
+        # to the left. This results in double-counting the rect between (0,0)
17
+        # 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-1][y] - prefixSum[x-1][y-1]
20
+
21
+var
22
+    best = int.low
23
+    bestPos = ""
24
+    bestThree = int.low
25
+    bestThreePos = ""
26
+
27
+for size in 1..300:
28
+    let s1 = size - 1
29
+    for x in 0..300 - size:
30
+        for y in 0..300 - size:
31
+            # To use the prefix sum to find the value of a rect, we take the
32
+            # value for the lower right corner and subtract the rects to the
33
+            # left and the top. Like when constructing the prefix sum this
34
+            # double-counts the rectangle diagonally to the top left, so we
35
+            # re-add that.
36
+            var sum = prefixSum[x+s1][y+s1] - prefixSum[x-1][y+s1] -
37
+                        prefixSum[x+s1][y-1] + prefixSum[x-1][y-1]
38
+            if sum > best:
39
+                best = sum
40
+                bestPos = $(x + 1) & "," & $(y + 1) & "," & $size
41
+            if size == 3 and sum > bestThree:
42
+                bestThree = sum
43
+                bestThreePos = $(x + 1) & "," & $(y + 1)
44
+
45
+echo bestThreePos
46
+echo bestPos