Skip to content

Instantly share code, notes, and snippets.

@iphysresearch
Created February 26, 2019 09:15
Show Gist options
  • Save iphysresearch/9b01fd852469330e070b88785f79cd81 to your computer and use it in GitHub Desktop.
Save iphysresearch/9b01fd852469330e070b88785f79cd81 to your computer and use it in GitHub Desktop.
[Spiral Memory]
## Spiral Memory
# You come across an experimental new kind of memory stored on an infinite two-dimensional grid.
# Each square on the grid is allocated in a spiral pattern starting at a location marked 1 and then counting up while spiraling outward. For example, the first few squares are allocated like this:
# 17 16 15 14 13
# 18 5 4 3 12
# 19 6 1 2 11
# 20 7 8 9 10
# 21 22 23---> ...
# While this is very space-efficient (no squares are skipped), requested data must be carried back to square 1 (the location of the only access port for this memory system) by programs that can only move up, down, left, or right. They always take the shortest path: the Manhattan Distance between the location of the data and square 1.
## For example:
# Data from square 1 is carried 0 steps, since it's at the access port. Data from square 12 is carried 3 steps, such as: down, left, left. Data from square 23 is carried only 2 steps: up twice.
# Data from square 1024 must be carried 31 steps.
# How many steps are required to carry the data from the square identified in your puzzle input all the way to the access port?
# How to test your answer:
# If you input: 100000 Your Answer should be: 173
# If you input: 2345678 Your Answer should be: 1347
# Series
def b(n):
if n == 1:
return 1
else:
return b(n-1) +8
# Coordinate
def x_plus(n):
if n == 1:
return 1
else:
return x_plus(n-1) + b(n-1)
def y_plus(n):
if n == 1:
return 1
else:
return y_plus(n-1) + b(n-1) + 2
def x_minus(n):
if n == 1:
return 1
else:
return x_minus(n-1) + b(n-1) + 4
def y_minus(n):
if n == 1:
return 1
else:
return y_minus(n-1) + b(n-1) + 6
def Q1(x):
q = x
x = 2000 // 2 # 2000 is the limit for the function x/y_*(n)
distanse = x
while True:
if (q < y_plus(x)) & (q >= x_plus(x)):
# print('1st', x, x_plus(x), y_plus(x))
return min(y_plus(x)-q, q-x_plus(x)) + x -1
elif (q < x_minus(x)) & (q >= y_plus(x)):
# print('2nd', x, x_minus(x), y_plus(x))
return min(x_minus(x)-q, q-y_plus(x)) + x -1
elif (q < y_minus(x)) & (q >= x_minus(x)):
# print('3rd', x, y_minus(x), x_minus(x))
return min(y_minus(x)-q, q-x_minus(x)) + x -1
elif (q < x_plus(x+1)) & (q >= y_minus(x)):
# print('4th', x, x_plus(x), y_minus(x+1))
return min(x_plus(x+1)-q, q-y_minus(x)) + x -1
elif q >= x_plus(x+1):
# print(x, x_plus(x), y_plus(x), x_minus(x), y_minus(x), x_plus(x+1))
# print('multi')
distanse = ( 1 if distanse == 1 else distanse //2 )
x = x + distanse
else:
# print(x, x_plus(x), y_plus(x), x_minus(x), y_minus(x), x_plus(x+1))
# print('divide')
distanse = ( 1 if distanse == 1 else distanse //2 )
x = x - distanse
if __name__ == '__main__':
print(Q1(1))
print(Q1(12))
print(Q1(23))
print(Q1(1024))
print(Q1(100000))
print(Q1(2345678))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment