Spiral filling formula - math

I'm trying to find a formula for spiral filling of an array.
Example:
0 1 2 3 4
11 12 13 14 5
10 9 8 7 6
My formula is based on "corners" of a spiral. The "corners" are bold in the example. With coordinates of the cell, we can find coordinates of biggest "corner" less than the number we want to find. With coordinates of "corner", we can find the index of this "corner". With the index of corner number, we can find the number. How to find the formula for corner number by its index?

Strong clue:
Let's width of array is W and height is H. We can see the next sequence:
0
(W-1)
(W-1) + (H-1)
(W-1) + (H-1) + (W-1)
(W-1) + (H-1) + (W-1) + (H-2) //full round, increment shifts
(W-1) + (H-1) + (W-1) + (H-2) + (W-2)
...
If you want to make a formula, note multiplicity of W and H, arithmetic progressions, and remainders by modulo 2 and 4

Related

(LUA) Generate a unique number from 2 numbers

I have a grid of tiles each with coordinates such as (-3, 5) or (1, 540) I want to generate a unique seed for each tile but I haven't found a way to do such
You need some kind of "pairing function" - Wiki describes such functions for natural numbers while you need integers including negative ones.
You can enumerate all integer points at coordinate plane in spiral manner
^ OY
|
16 15 14 13 12
17 4 3 2 11
18 5 0 1 10 ==> OX
19 6 7 8 9
20 21 22 23 24
So, for example, point -2,-2 has index 20
To calculate such index from coordinates, you can use simple algorithm (details here)
if y * y >= x * x then begin
p := 4 * y * y - y - x;
if y < x then
p := p - 2 * (y - x)
end
else begin
p := 4 * x * x - y - x;
if y < x then
p := p + 2 *(y - x)
end;
You don't ask for reverse mapping, but it is definitely possible (layer number is (1 + floor(sqrt(p))) / 2 and so on)
To complete: Python function for reverse mapping
def ptoxy(p):
layer = (int(math.sqrt(p)) + 1) // 2 # integer division
topleft = 4*layer*layer
if p <= topleft:
if p <= topleft - 2 * layer:
return [layer, 3*layer + p - topleft]
else:
return [-layer + topleft - p, layer]
else:
if p >= topleft + 2 * layer:
return [p-topleft - 3*layer, -layer]
else:
return [-layer, layer-p + topleft]
and link to quick-made test
If you have a grid of tiles, you may consider that you have a first tile, at the top-left corner and a last tile at the bottom-right corner.
[0] [1] [2]
[3] [4] [5]
[6] [7] [8]
But the [Row:Col] notation is more handy.
[0:0] [0:1] [0:2]
[1:0] [1:1] [1:2]
[2:0] [2:1] [2:2]
So you can access the [Row:Col] element with the formula:
ColumnCount = 3
Element = (Row * ColumnCount) + Col
For example (2:1) offset in your grid will be 2*3+1 which is 7.
[0:0] [0:1] [0:2]
[1:0] [1:1] [1:2]
[2:0] [2:1] [2:2]
--v--
2*3+1 = 7
It's simple and each tile will have a unique identifier.

finding implicit representation of 2D plane

I want to find the implicit representation of a 2D plane that is tangent to the sphere S at point (4,3,4),
where S: (x-1)^2 + (y-2)^2 + z^2 - 26 = 0
How can I find it?
Sphere equation
(x-1)^2 + (y-2)^2 + z^2 - 26 = 0
denotes that center has coordinates
C = (1, 2, 0)
and radius-vector to point P=(4,3,4) is
N = P - C = (3, 1, 4)
This vector is normal to the plane, so plane equation is
3*x + 1*y + 4*z + d = 0
Substitute known point P into equation to get d coefficient:
d = - (3*4 + 3 + 4*4) = -31
Finally plane equation is
3x + y + 4z - 31 = 0
P.S. I believe that using term 2D plane is random error

Find row of pyramid based on index?

Given a pyramid like:
0
1 2
3 4 5
6 7 8 9
...
and given the index of the pyramid i where i represents the ith number of the pyramid, is there a way to find the index of the row to which the ith element belongs? (e.g. if i = 6,7,8,9, it is in the 3rd row, starting from row 0)
There's a connection between the row numbers and the triangular numbers. The nth triangular number, denoted Tn, is given by Tn = n(n-1)/2. The first couple triangular numbers are 0, 1, 3, 6, 10, 15, etc., and if you'll notice, the starts of each row are given by the nth triangular number (the fact that they come from this triangle is where this name comes from.)
So really, the goal here is to determine the largest n such that Tn ≤ i. Without doing any clever math, you could solve this in time O(√n) by just computing T0, T1, T2, etc. until you find something bigger than i. Even better, you could binary search for it in time O(log n) by computing T1, T2, T4, T8, etc. until you overshoot, then binary searching on the range you found.
Alternatively, we could try to solve for this directly. Suppose we want to find the choice of n such that
n(n + 1) / 2 = i
Expanding, we get
n2 / 2 + n / 2 = i.
Equivalently,
n2 / 2 + n / 2 - i = 0,
or, more easily:
n2 + n - 2i = 0.
Now we use the quadratic formula:
n = (-1 &pm; √(1 + 8i)) / 2
The negative root we can ignore, so the value of n we want is
n = (-1 + √(1 + 8i)) / 2.
This number won't necessarily be an integer, so to find the row you want, we just round down:
row = ⌊(-1 + √(1 + 8i)) / 2⌋.
In code:
int row = int((-1 + sqrt(1 + 8 * i)) / 2);
Let's confirm that this works by testing it out a bit. Where does 9 go? Well, we have
(-1 + √(1 + 72)) / 2 = (-1 + √73) / 2 = 3.77
Rounding down, we see it goes in row 3 - which is correct!
Trying another one, where does 55 go? Well,
(-1 + √(1 + 440)) / 2 = (√441 - 1) / 2 = 10
So it should go in row 10. The tenth triangular number is T10 = 55, so in fact, 55 starts off that row. Looks like it works!
I get row = math.floor (√(2i + 0.25) - 0.5) where i is your number
Essentially the same as the guy above but I reduced n2 + n to (n + 0.5)2 - 0.25
I think ith element belongs nth row where n is number of n(n+1)/2 <= i < (n+1)(n+2)/2
For example, if i = 6, then n = 3 because n(n+1)/2 <= 6
and if i = 8, then n = 3 because n(n+1)/2 <= 8

Number of subsets of {1,2,3,...,N} containing at least 3 consecutive elements

Suppose we have a set like {1,2,3} then there is only one way to choose 3 consecutive numbers... it's the set {1,2,3}...
For a set of {1,2,3,4} we have 3 ways: 123 234 1234
(technically these are unordered sets of numbers, but writing them consecutively helps)
f(5) ; {1,2,3,4,5} -> 8 ways: 123 1234 1235 12345 234 2345 345 1345
f(6) ; {1,2,3,4,5,6} -> 20 ways: ...
f(7) ; {1,2,3,4,5,6,7} -> 47 ways: ...
So for a given N, I can get the answer by applying brute force, and calculating all such subset having 3 or more consecutive number.
Here I am just trying to find out a pattern, a technique to get the number of all such subset for a given N.
The problem is further generalized to .....discover m consecutive number within a set of size N.
There is a bijection between this problem and "the number of N-digit binary numbers with at least three consecutive 1s in a row somewhere" (the bijection being a number is 0 if excluded in the subset, and 1 if included in the subset).
This is a known problem, and should be enough information to google for a result, if you search for number of n-digit binary strings with m consecutive 1s, the second hit is Finding all n digit binary numbers with r adjacent digits as 1
Alternatively you can just look it up as http://oeis.org/search?q=0%2C0%2C1%2C3%2C8%2C20%2C47 (based on the brute-forcing you did for the first few terms) - resulting in an explicit formula of 2^n - tribonacci(n+3), see here for an explicit formula for tribonacci numbers. It also gives a recurrence relation. The analogy given is "probability (out of 2^n) of getting at least 1 run of 3 heads within n flips of a fair coin"
I can only assume that the answer to the general problem is 2^n - Fm(n+m), where Fm is the mth n-step Fibonacci number (edit: that does seem to be the case)
This sounds like homework to me, so I'll just get you started. FoOne approach is to think of the Lowest and Highest members of the run, L and H. If the set size is N and your minimum run length is M, then for each possible position P of L, you can work out how many positions of H there are....
With a bit of python code, we can investigate this:
y = set()
def cons(li, num):
if len(li) < num:
return
if len(li) == num:
y.add(tuple([i for i in li]))
else:
y.add(tuple([i for i in li]))
cons(li[1:], num)
cons(li[:-1], num)
This solution will be quite slow (it's exponential in complexity, actually), but try it out for a few small list sizes and I think you should be able to pick up the pattern.
Not sure if you mean consecutive or not. If not, then for {1, 2, 3, 4} there are 4 possibilities: {1, 2, 3} {2, 3, 4} {1, 3, 4} {1, 2, 3, 4}
I think you can calculate the solution with N!/3! where N! = N*(N-1)(N-2)...*1.
Quick answer:
Sequences(n) = (n-1)*(n-2) / 2
Long answer:
You can do this by induction. First, I'm going to re-state the problem, because your problem statement isn't clear enough.
Rule 1: For all sets of consecutive numbers 1..n where n is 2 or more
Rule 2: Count the subsets S(n) of consecutive numbers m..m+q where q is 2 or more
S(n=3)
By inspection we find only one - 123
S(n=4)
By inspection we find 3! - 123 234 and 1234
Note that S(4) contains S(3), plus two new ones... both include the new digit 4... hmm.
S(n=5)
By inspection we find ... S(n=4) as well as 345 2345 and 12345. That's 3+3=6 total.
I think there's a pattern forming here. Let's define a new function T.
Rule 3: S(n) = S(n-1) + T(n) ... for some T.
We know that S(n) contains the digit n, and should have spotted by now that S(n) also contains (as a subcomponent) all sequences of length 3 to n that include the digit n. We know they cannot be in S(n-1) so they must be in T(n).
Rule 4: T(n) contains all sequence ending in n that are of length 3 to n.
How many sequences are in S(n)?
Let's look back at S(3) S(4) and S(5), and incorporate T(n):
S(3) = S(3)
S(4) = S(3) + T(4)
S(5) = S(4) + T(5) = S(3) + T(4) + T(5)
let's generalise:
S(n) = S(3) + T(f) for all f from 4 to n.
So how many are in a given T?
Look back at rule 5 - how many sequences does it describe?
For T(4) it describes all sequences 3 and longer ending in 4. (that's 234)
For T(5) it describes all sequences 3 and longer ending in 5. (that's 345 2345 = 2)
T count Examples
4 2 1234 234
5 3 12345 2345 345
6 4 123456 23456 3456 456
Looks awfully like T(n) is simply n-2!
So
S(6) = T(6) + T(5) + T(4) + S(3)
10 = 4 + 3 + 2 + 1
And
S(7) = 15 = 5 + 4 + 3 + 2 + 1
S(8) = 21 = 6 + 5 + 4 + 3 + 2 + 1
Turning this into a formula
What's 2 * S(8)?
42 = 6 + 5 + 4 + 3 + 2 + 1 + 1 + 2 + 3 + 4 + 5 + 6
Add each pair of biggest and smallest numbers:
42 = 7 + 7 + 7 + 7 + 7 + 7
42 = 7 * 6
But that's 2 * S(8), so
S(8) = 42/2 = 21 = 7 * 6 / 2
This generalizes:
S(n) = (n-1)*(n-2) / 2
Let's check this works:
S(3) = 2*1/2 = 1
S(4) = 3*2/2 = 3
S(5) = 4*3/2 = 6
S(6) = 5*4/2 = 10
I'm satisfied.

How do you get N(N+1) from N+1 + N + 1 + ... + N + 1 + N + 1?

How does:
1 + 2 + ... + N-1 + N
+ N + N-1 + ... + 2 + 1
---------------------------
N+1 + N+1 + ... + N+1 + N+1
equal N(N + 1)? Shouldn't it be 4N + 4 or 4(N + 1)?
It is N(N + 1).
Because you have N number of (N+1) terms.
If N is 4, sure. Otherwise you need to fill in the rest of the elided values that the ellipses represent.
i assume your notation means row 1
+ row 2 = row 3?
in this case, look at the columns. Each column of the first 2 rows adds up to n+1. there are n columns. thus row 1 + row 2 = n*(n+1)
Read the part about the early years of Carl Friederich Gauss here. He solved almost the same problem when he was in primary school.

Resources