|
@@ -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
|