Printing a 2D pattern - algorithm

I discovered this pattern and decided to print it.
1 2 5 10 17
3 4 7 12 19
6 8 9 14 21
11 13 15 16 23
18 20 22 24 25
Rule here is to move from (0,0) to (0,1) to (1,0) to (1,1) to (0,2) to (2,0) to (1,2) to (2,1) to (2,2) and so on upto NxN matrix.
I have a very complex approach for printing it. Is there any easy way to print this pattern?
Update: Added one more row and column

It seems like the general rule is as follows:
Given a position as a tuple (n, m), the next position is
(n+1, 0), if n = m
(m, n), if n > m
(m, n+1), if n < m
In Python:
def next_pos(n, m):
if n == m: return (n+1, 0)
if n > m: return (m, n)
if n < m: return (m, n+1)
Example:
N = 5
n, m = (0, 0)
matrix = [[None for _ in range(N)] for _ in range(N)]
for x in range(N*N):
matrix[m][n] = x+1
n, m = next_pos(n, m)
Result:
1 2 5 10 17
3 4 7 12 19
6 8 9 14 21
11 13 15 16 23
18 20 22 24 25

Here is a Python solution that first extends every row by every other number starting with 1 more than the last perfect square, and then adds a new row, which consists of every other number starting with 2 more than the last perfect square, along with the final entry (which is the next perfect square in the sequence):
def expandSquare(square):
n = len(square[0])
for i, row in enumerate(square):
row.append(n**2 + 1 + 2*i)
square.append([k for k in range(n**2 + 2, (n+1)**2,2)] + [(n+1)**2])
def makeSquare(n):
square = [[1]]
for i in range(1,n): expandSquare(square)
return square
def pprint(square):
print('\n'.join('\t'.join(str(i) for i in row) for row in square))
For example,
>>> pprint(makeSquare(5))
1 2 5 10 17
3 4 7 12 19
6 8 9 14 21
11 13 15 16 23
18 20 22 24 25

Related

Generic triangular numbers sequence formula

I know that I can get the nth element of the following sequence
1 3 6 10 15 21
With the formula
(n * (n + 1)) / 2
where n is the nth number I want. How can I generalise the formula to get the nth element of the following sequences where by following sequences I mean
1 -> 1 3 6 10 15 21
2 -> 2 5 9 14 20
3 -> 4 8 13 19
4 -> 7 12 18
5 -> 11 17
6 -> 16
It is not quite clear what do you mean by n-th element in 2D-table (potentially infinite)
Simple formula for element at row and column (numbered from 1):
(r+c-1)*(r+c)/2 - (r-1)
Possible intuition for this formula:
Key moment: element with coordinates r,c stands on the diagonal number d, where d = r + c - 1
There are s = d*(d+1)/2 elements in d filled diagonals, so the last element of d-th diagonal (rightmost top) has value s, and element in r-th row of the same diagonal is
v(r,c) = s-(r-1) = (d)*(d+1)/2 -(r-1) = (r+c-1)*(r+c)/2 - (r-1)

Fenwick trees to determine which interval a point falls in

Let a0,...,an-1 be a sequence of lengths. We can construct intervals [0,a0], (a1,a2+a1],(a2+a1,a3+a2+a1],... I store the sequence a1,...,an-1 in a Fenwick tree.
I ask the question: given a number m, how can I efficiently (log n time) find into which interval m falls?
For example, given the a: 3, 5, 2, 7, 9, 4.
The Fenwick Tree stores 3, 8, 2, 17, 9, 13.
The intervals are [0,3],(3,8],(8,10],(10,17],(17,26],(26,30].
Given the number 9, the algorithm should return the 3rd index of the Fenwick Tree (2 if 0-based arrays are used, 3 if 1-based arrays are used). Given the number 26, the algorithm should return the 5th index of the Fenwick Tree (4 if 0-based arrays are used or 5 if 1-based arrays are used).
Possibly another data structure might be more suited to this operation. I am using Fenwick Trees because of their seeming simplicity and efficiency.
We can get an O(log n)-time search operation. The trick is to integrate the binary search with the prefix sum operation.
def get_total(tree, i):
total = 0
while i > 0:
total += tree[i - 1]
i -= i & (-i)
return total
def search(tree, total):
j = 1
while j < len(tree):
j <<= 1
j >>= 1
i = -1
while j > 0:
if i + j < len(tree) and total > tree[i + j]:
total -= tree[i + j]
i += j
j >>= 1
return i + 1
tree = [3, 8, 2, 17, 9, 13]
print('Intervals')
for i in range(len(tree)):
print(get_total(tree, i), get_total(tree, i + 1))
print('Searches')
for total in range(31):
print(total, search(tree, total))
Output is
Intervals
0 3
3 8
8 10
10 17
17 26
26 30
Searches
0 0
1 0
2 0
3 0
4 1
5 1
6 1
7 1
8 1
9 2
10 2
11 3
12 3
13 3
14 3
15 3
16 3
17 3
18 4
19 4
20 4
21 4
22 4
23 4
24 4
25 4
26 4
27 5
28 5
29 5
30 5
If the intervals don't change frequently, you can use a simple binary search in the accumulated array to do that. In Python you can use the bisect module to do that. Each query will be O(log n):
import bisect
A = [3, 5, 2, 7, 9, 4]
for i in xrange(1, len(A)):
A[i] += A[i-1]
print bisect.bisect_left(A, 9)
print bisect.bisect_left(A, 26)
If the intervals change, you can use the same idea, but each array lookup will be O(log n), making the query operation O(log² n) overall.

Fastest way to find sum of any rectangle in matrix

I have a m x n matrix and want to be able to calculate sums of arbitrary rectangular submatrices. This will happen several times for the given matrix. What data structure should I use?
For example I want to find sum of rectangle in matrix
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
Sum is 68.
What I'll do is accumulating it row by row:
1 2 3 4
6 8 10 12
15 18 21 24
28 32 36 40
And then, if I want to find sum of the matrix I just accumulate 28,32,36,40 = 136. Only four operation instead of 15.
If I want to find sum of second and third row, I just accumulate 15,18,21,24 and subtract 1, 2, 3, 4. = 6+8+10+12+15+18+21+24 = 68.
But in this case I can use another matrix, accumulating this one by columns:
1 3 6 10
5 11 18 26
9 19 30 42
13 27 42 58
and in this case I just sum 26 and 42 = 68. Only 2 operation instead of 8. For wider sub-matrix is is efficient to use second method and matrix, for higher - first one. Can I somehow split merge this to methods to one matrix?
So I just sum to corner and subtract another two?
You're nearly there with your method. The solution is to use a summed area table (aka Integral Image):
http://en.wikipedia.org/wiki/Summed_area_table
The key idea is you do one pass through your matrix and accumulate such that "the value at any point (x, y) in the summed area table is just the sum of all the pixels above and to the left of (x, y), inclusive.".
Then you can compute the sum inside any rectangle in constant time with four lookups.
Why can't you just add them using For loops?
int total = 0;
for(int i = startRow; i = endRow; i++)
{
for(int j = startColumn; j = endColumn; j++)
{
total += array[i][j];
}
}
Where your subarray ("rectangle") would go from startRow to endRow (width) and startColumn to endColumn (height).

Prime factorization of a factorial

I need to write a program to input a number and output its factorial's prime factorization in the form:
4!=(2^3)*(3^1)
5!=(2^3)*(3^1)*(5^1)
The problem is I still can't figure out how to get that result.
Apparently each first number in brackets is for the ascending prime numbers up until the actual factorial. The second number in brackets is the amount of times the number occurs in the factorial.
What I can't figure out is for example in 5!=(2^3)*(3^1)*(5^1), how does 2 only occur 3 times, 3 only 1 time and 5 only one time in 120 (5!=120).
I have now solved this thanks to the helpful people who commented but I'm now having trouble trying to figure out how could I take a number and get the factorial in this format without actually calculating the factorial.
Every number can be represented by a unique (up to re-ordering) multiplication of prime numbers, called the prime factorization of the number, as you are finding the prime factors that can uniquely create that number.
2^3=8
3^1=3
5^1=5
and 8*3*5=120
But this also means that: (2^3)*(3^1)*(5^1) = 120
It's not saying that 2 occurs 3 times as a digit in the number 120, which it obviously does not, but rather to multiply 2 by 2 by 2, for a total of 3 twos. Likewise for the 3 and 5, which occur once in the prime factorization of 120. The expression which you mention is showing you this unique prime factorization of the number 120. This is one way of getting the prime factorization of a number in Python:
def pf(number):
factors=[]
d=2
while(number>1):
while(number%d==0):
factors.append(d)
number=number/d
d+=1
return factors
Running it you get:
>>> pf(120)
[2, 2, 2, 3, 5]
Which multiplied together give you 120, as explained above. Here's a little diagram to illustrate this more clearly:
Consider e.g. 33!. It's a product of:
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
the factors are:
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2
2 2 2 2
2 2
2
3 3 3 3 3 3 3 3 3 3 3
3 3 3
3
5 5 5 5 5 5
5
7 7 7 7
11 11 11
13 13
17
19
23
29 31
Do you see the pattern?
33! = 2^( 33 div 2 + 33 div 4 + 33 div 8 + 33 div 16 + 33 div 32) *
3^( 33 div 3 + 33 div 9 + 33 div 27) *
5^( 33 div 5 + 33 div 25) *
----
7^( 33 div 7) * 11^( 33 div 11) * 13^( 33 div 13) *
----
17 * 19 * 23 * 29 * 31
Thus, to find prime factorization of n! without doing any multiplications or factorizations, we just need to have the ordered list of primes not greater than n, which we process (with a repeated integer division and a possible summation) in three stages - primes that are smaller or equal to the square root of n; such that are smaller or equal to n/2; and the rest.
Actually with lazy evaluation it's even simpler than that. Assuming primes is already implemented returning a stream of prime numbers in order, in Haskell, factorial factorization is found as
ff n = [(p, sum . takeWhile (> 0) . tail . iterate (`div` p) $ n)
| p <- takeWhile (<= n) primes]
-- Prelude> ff 33
-- [(2,31),(3,15),(5,7),(7,4),(11,3),(13,2),(17,1),(19,1),(23,1),(29,1),(31,1)]
because 33 div 4 is (33 div 2) div 2, etc..
2^3 is another way of writing 23, or two to the third power. (2^3)(3^1)(5^1) = 23 × 3 × 5 = 120.
(2^3)(3^1)(5^1) is just the prime factorization of 120 expressed in plain ASCII text rather than with pretty mathematical formatting. Your assignment requires output in this form simply because it's easier for you to output than it would be for you to figure out how to output formatted equations (and probably because it's easier to process for grading).
The conventions used here for expressing equations in plain text are standard enough that you can directly type this text into google.com or wolframalpha.com and it will calculate the result as 120 for you: (2^3)(3^1)(5^1) on wolframalpha.com / (2^3)(3^1)(5^1) on google.com
WolframAlpha can also compute prime factorizations, which you can use to get test results to compare your program with. For example: prime factorization of 1000!
A naïve solution that actually calculates the factorial will only handle numbers up to 12 (if using 32 bit ints). This is because 13! is ~6.2 billion, larger than the largest number that can be represented in a 32 bit int.
However it's possible to handle much larger inputs if you avoid calculating the factorial first. I'm not going to tell you exactly how to do that because either figuring it out is part of your assignment or you can ask your prof/TAs. But below are some hints.
ab × ac = ab+c
equation (a) 10 = 21 × 51
equation (b) 15 = 31 × 51
10 × 15 = ? Answer using the right hand sides of equations (a) and (b), not with the number 150.
10 × 15 = (21 × 51) × (31 × 51) = 21 × 31 × (51 × 51) = 21 × 31 × 52
As you can see, computing the prime factorization of 10 × 15 can be done without multiplying 10 by 15; You can instead compute the prime factorization of the individual terms and then combine those factorizations.
If you write out the factorial 5!:
1 * 2 * 3 * 4 * 5,
you will notice that there is one non-prime number: 4. 4 can be written as 2 * 2 or 2^2, which is where the extra 2s come from.
Add up all of the occurrences (exponential forms are in parentheses; add exponents for like bases):
2 (2^1) * 3 (3^1) * 4 (2^2) * 5 (5^1), you get the proper answer.
You can use O(n/2 log log n) algorithm using only sums (no need precalc primes).
This is a sieve using relation
f = a * b ~> f^k = a^k * b^k
then, we reduce all initial factors 1 * 2 * 3 * ... * n moving k from big numbers to small numbers.
Using Sieve of Atkin the Will Ness algorithm could be better for very big n if not, I think it could be better
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
int n = atoi(argv[1]);
int *p = (int *) malloc(sizeof(int) * (n + 1));
int i, j, d;
for(i = 0; i <= n; i++)
p[i] = 1;
for(i = n >> 1; i > 1; i--)
if(p[i]) {
for(j = i + i, d = 2; j <= n; j += i, d++) {
if(p[j]) {
p[i] += p[j];
p[d] += p[j];
p[j] = 0;
}
}
}
printf("1");
for(i = 2; i <= n; i++)
if(p[i])
printf(" * %i^%i", i, p[i]);
printf("\n");
return 0;
}

Summation of difference between matrix elements

I am in the process of building a function in MATLAB. As a part of it I have to calculate differences between elements in two matrices and sum them up.
Let me explain considering two matrices,
1 2 3 4 5 6
13 14 15 16 17 18
and
7 8 9 10 11 12
19 20 21 22 23 24
The calculations in the first row - only four elements in both matrices are considered at once (zero indicates padding):
(1-8)+(2-9)+(3-10)+(4-11): This replaces 1 in initial matrix.
(2-9)+(3-10)+(4-11)+(5-12): This replaces 2 in initial matrix.
(3-10)+(4-11)+(5-12)+(6-0): This replaces 3 in initial matrix.
(4-11)+(5-12)+(6-0)+(0-0): This replaces 4 in initial matrix. And so on
I am unable to decide how to code this in MATLAB. How do I do it?
I use the following equation.
Here i ranges from 1 to n(h), n(h), the number of distant pairs. It depends on the lag distance chosen. So if I choose a lag distance of 1, n(h) will be the number of elements - 1.
When I use a 7 X 7 window, considering the central value, n(h) = 4 - 1 = 3 which is the case here.
You may want to look at the circshfit() function:
a = [1 2 3 4; 9 10 11 12];
b = [5 6 7 8; 12 14 15 16];
for k = 1:3
b = circshift(b, [0 -1]);
b(:, end) = 0;
diff = sum(a - b, 2)
end

Resources