2023 day 21, version 2.
This commit is contained in:
parent
5f8c74fd1c
commit
c496ea25c9
@ -39,8 +39,7 @@ print(f"answer 1 is {answer_1}")
|
|||||||
# rhombus every n steps
|
# rhombus every n steps
|
||||||
#
|
#
|
||||||
# we are going to find the number of cells reached for the initial rhombus, n steps
|
# we are going to find the number of cells reached for the initial rhombus, n steps
|
||||||
# after and n * 2 steps after, and then interpolate the value to get a 2nd order
|
# after and n * 2 steps after
|
||||||
# polynomial
|
|
||||||
#
|
#
|
||||||
cycle = len(map)
|
cycle = len(map)
|
||||||
rhombus = (len(map) - 3) // 2 + 1
|
rhombus = (len(map) - 3) // 2 + 1
|
||||||
@ -56,9 +55,9 @@ if logging.root.getEffectiveLevel() == logging.INFO:
|
|||||||
rows = [
|
rows = [
|
||||||
[
|
[
|
||||||
map[i % n_rows][j % n_cols] if (i, j) not in tiles else "O"
|
map[i % n_rows][j % n_cols] if (i, j) not in tiles else "O"
|
||||||
for j in range(-2 * cycle, 3 * cycle + 1)
|
for j in range(-2 * cycle, 3 * cycle)
|
||||||
]
|
]
|
||||||
for i in range(-2 * cycle, 3 * cycle + 1)
|
for i in range(-2 * cycle, 3 * cycle)
|
||||||
]
|
]
|
||||||
|
|
||||||
for i in range(len(rows)):
|
for i in range(len(rows)):
|
||||||
@ -71,6 +70,64 @@ if logging.root.getEffectiveLevel() == logging.INFO:
|
|||||||
|
|
||||||
logging.info(f"values to fit: {values}")
|
logging.info(f"values to fit: {values}")
|
||||||
|
|
||||||
|
# version 1:
|
||||||
|
#
|
||||||
|
# after 3 cycles, the figure looks like the following:
|
||||||
|
#
|
||||||
|
# I M D
|
||||||
|
# I J A K D
|
||||||
|
# H A F A L
|
||||||
|
# C E A K B
|
||||||
|
# C G B
|
||||||
|
#
|
||||||
|
# after 4 cycles, the figure looks like the following:
|
||||||
|
#
|
||||||
|
# I M D
|
||||||
|
# I J A K D
|
||||||
|
# I J A B A K D
|
||||||
|
# H A B A B A L
|
||||||
|
# C E A B A N F
|
||||||
|
# C E A N F
|
||||||
|
# C G F
|
||||||
|
#
|
||||||
|
# the 'radius' of the rhombus is the number of cycles minus 1
|
||||||
|
#
|
||||||
|
# the 4 'corner' (M, H, L, G) are counted once, the blocks with a corner triangle (D, I,
|
||||||
|
# C, B) are each counted radius times, the blocks with everything but one corner (J, K,
|
||||||
|
# E, N) are each counted radius - 1 times
|
||||||
|
#
|
||||||
|
# there are two versions of the whole block, A and B in the above (or odd and even),
|
||||||
|
# depending on the number of cycles, either A or B will be in the center
|
||||||
|
#
|
||||||
|
|
||||||
|
counts = [
|
||||||
|
[
|
||||||
|
sum(
|
||||||
|
(i, j) in tiles
|
||||||
|
for i in range(ci * cycle, (ci + 1) * cycle)
|
||||||
|
for j in range(cj * cycle, (cj + 1) * cycle)
|
||||||
|
)
|
||||||
|
for cj in range(-2, 3)
|
||||||
|
]
|
||||||
|
for ci in range(-2, 3)
|
||||||
|
]
|
||||||
|
|
||||||
|
radius = (26501365 - rhombus) // cycle - 1
|
||||||
|
A = counts[2][2] if radius % 2 == 0 else counts[2][1]
|
||||||
|
B = counts[2][2] if radius % 2 == 1 else counts[2][1]
|
||||||
|
answer_2 = (
|
||||||
|
(radius + 1) * A
|
||||||
|
+ radius * B
|
||||||
|
+ 2 * radius * (radius + 1) // 2 * A
|
||||||
|
+ 2 * radius * (radius - 1) // 2 * B
|
||||||
|
+ sum(counts[i][j] for i, j in ((0, 2), (-1, 2), (2, 0), (2, -1)))
|
||||||
|
+ sum(counts[i][j] for i, j in ((0, 1), (0, 3), (-1, 1), (-1, 3))) * (radius + 1)
|
||||||
|
+ sum(counts[i][j] for i, j in ((1, 1), (1, 3), (-2, 1), (-2, 3))) * radius
|
||||||
|
)
|
||||||
|
print(f"answer 2 (v1) is {answer_2}")
|
||||||
|
|
||||||
|
# version 2: fitting a polynomial
|
||||||
|
#
|
||||||
# the value we are interested in (26501365) can be written as R + K * C where R is the
|
# the value we are interested in (26501365) can be written as R + K * C where R is the
|
||||||
# step at which we find the first rhombus, and K the repeat step, so instead of fitting
|
# step at which we find the first rhombus, and K the repeat step, so instead of fitting
|
||||||
# for X values (R, R + K, R + 2 K), we are going to fit for (0, 1, 2), giving us much
|
# for X values (R, R + K, R + 2 K), we are going to fit for (0, 1, 2), giving us much
|
||||||
@ -89,4 +146,4 @@ a, b, c = (y1 + y3) // 2 - y2, 2 * y2 - (3 * y1 + y3) // 2, y1
|
|||||||
|
|
||||||
n = (26501365 - rhombus) // cycle
|
n = (26501365 - rhombus) // cycle
|
||||||
answer_2 = a * n * n + b * n + c
|
answer_2 = a * n * n + b * n + c
|
||||||
print(f"answer 2 is {answer_2}")
|
print(f"answer 2 (v2) is {answer_2}")
|
||||||
|
Loading…
Reference in New Issue
Block a user