This topic is leading on from one I made back last decade - which can be found here.
In that topic I was able to calculate the adjacent sides of only one diagonal however not the rest of the spiral then due to time pressure I had to implement a less mathematical way however I am now able to revisit this topic.
My use for finding the adjacent squares is to create a land purchasing system, similar to how @Defaultio did in Lumber Tycoon 2. The basics are that when you purchase a block of land all the blocks surrounding it become available to purchase, this can be done either manually inputting the adjacent squares for each block and removing the squares in use or can be done by using a Ulam spiral with some equations and removing the squares already bought.
Current Progress:
We have four equations at our disposal to find out the four diagonals as shown in the image below.
However by slightly changing the equation we are able to have an equation for EVERY number.
So with this we can create a table with all numbers and a corresponding equation. So it would look something like this:
local n -- Needed later
local actualEquations -- Needed later
local equations = {
eq1 = {17,35}, -- 4n^2 - 2n + 5
eq2 = {16,34}, -- 4n^2 - 2n + 4
eq3 = {5,15,33}, -- 4n^2 - 2n + 3
eq4 = {4,14,32}, -- 4n^2 - 2n + 2
eq5 = {1,3,13,31}, -- 4n^2 - 2n + 1
eq6 = {2,12,30}, -- 4n^2 - 2n
----
eq7 = {6,8,24,48}, -- 4n^2 - 4n
eq8 = {1,9,25,49}, -- 4n^2 - 4n + 1
eq9 = {2,10,26}, -- 4n^2 - 4n + 2
eq10 = {3,11,27}, -- 4n^2 - 4n + 3
eq11 = {12,28}, -- 4n^2 - 4n + 4
eq12 = {13,29}, -- 4n^2 - 4n + 5
----
eq13 = {4,6,20,42}, -- 4n^2 + 2n
eq14 = {1,7,21,43}, -- 4n^2 + 2n + 1
eq15 = {2, 8, 22, 44}, -- 4n^2 + 2n + 2
eq16 = {9,23,45}, -- 4n^2 + 2n + 3
eq17 = {10,24,46}, -- 4n^2 + 2n + 4
eq18 = {25,47}, -- 4n^2 + 2n + 5
----
eq19 = {2,4,16,36}, -- 4n^2
eq20 = {1,5,17,37}, -- 4n^2 + 1
eq21 = {6,18,38}, -- 4n^2 + 2
eq22 = {7,19,39}, -- 4n^2 + 3
eq23 = {20,40}, -- 4n^2 + 4
eq24 = {21, 41} -- 4n^2 + 5
}
The next thing is a function which will calculate an answer based on n. Because actualEquations
is defined outside of the function, everything in the script is able to access the answers
local function calculate(n)
actualEquations = {
eq1 = {4*n^2 - 2*n + 5},
eq2 = {4*n^2 - 2*n + 4},
eq3 = {4*n^2 - 2*n + 3},
eq4 = {4*n^2 - 2*n + 2},
eq5 = {4*n^2 - 2*n + 1},
eq6 = {4*n^2 - 2*n},
----
eq7 = {4*n^2 - 4*n},
eq8 = {4*n^2 - 4*n + 1},
eq9 = {4*n^2 - 4*n + 2},
eq10 = {4*n^2 - 4*n + 3},
eq11 = {4*n^2 - 4*n + 4},
eq12 = {4*n^2 - 4*n + 5},
----
eq13 = {4*n^2 + 2*n},
eq14 = {4*n^2 + 2*n + 1},
eq15 = {4*n^2 + 2*n + 2},
eq16 = {4*n^2 + 2*n + 3},
eq17 = {4*n^2 + 2*n + 4},
eq18 = {4*n^2 + 2*n + 5},
----
eq19 = {4*n^2},
eq20 = {4*n^2 + 1},
eq21 = {4*n^2 + 2},
eq22 = {4*n^2 + 3},
eq23 = {4*n^2 + 4},
eq24 = {4*n^2 + 5},
}
end
The next thing we are going to need to find is which layer a number is on so we know what to substitute. We can simply find this by finding the largest number on each layer and if it is bigger than the previous layer but smaller of the same as the biggest on that layer it is on that layer. This equation is 4n^2-4n+1
local function findLayer(number)
for n = 0,5 do
local max = 4*n^2-4*n+1
n = n-1
local min = 4*n^2-4*n+1
if min < number and max >= number then
return n
end
end
end
Next, we need to find which equation the number uses, this is using the table named equations
we made earlier.
local function findEquation(toFind)
for i, eq in pairs(equations) do
for _, number in pairs(equations[i]) do
if toFind == number then
return i
end
end
end
end
Now we just need a function to return the perpendicular adjacent numbers.
local function adjacentSquares(number)
local adjacent = {}
table.insert(adjacent, #adjacent+1, number+1) -- Appends the + and - 1 adjacent squares
table.insert(adjacent, #adjacent+1, number-1)
n = findLayer(number) -- Finds the current layer
local eq = findEquation(number) -- Finds the equation to use
print(eq)
local plusOne = calculate(n+1)
plusOne = actualEquations[eq]
table.insert(adjacent, #adjacent+1, plusOne[1]+1)
local minusOne = calculate(n-1)
minusOne = actualEquations[eq]
table.insert(adjacent, #adjacent+1, minusOne[1]-1)
return adjacent
end
Exception:
You can not find the numbers on the diagonals through 1: Including the numbers: 1,3,13,31,7,21,43,9,25,49,5,17,37
There are three ways to find them:
Method 1:
Hard code them
Method 2:
± the number then use the equation where n = n+1 and ± that result
Method 3:
Use the equation where n = n+1 and n = n-1 then ± both the results to find the adjacent perpendicular
My Question
With the current system of finding the perpendicular numbers along two sides of the Ulam spiral, you need to add to plusOne
and on the other two subtract from plusOne
the same goes for minusOne
. So the big question is how do I, without hard coding find the side of the Ulam spiral that any number is on. - Basicaly I am looking for an equation to find which side of a Ulam spiral any number is on.