Issue with getting to some data in a matrix [duplicate] - c++

How do I print a 5×5 two-dimensional array in spiral order?
Is there any formula so that I can print an array of any size in spiral order?

The idea is to treat the matrix as a series of layers, top-right layers and bottom-left layers. To print the matrix spirally we can peel layers from these matrix, print the peeled part and recursively call the print on the left over part. The recursion terminates when we don't have any more layers to print.
Input matrix:
1 2 3 4
5 6 7 8
9 0 1 2
3 4 5 6
7 8 9 1
After peeling top-right layer:
1 2 3 4
8
5 6 7 2
9 0 1 6
3 4 5 1
7 8 9
After peeling bottom-left layer from sub-matrix:
6 7
5 0 1
9 4 5
3
7 8 9
After peeling top-right layer from sub-matrix:
6 7
1
0 5
4
After peeling bottom-left layer from sub-matrix:
0
4
Recursion terminates.
C functions:
// function to print the top-right peel of the matrix and
// recursively call the print bottom-left on the submatrix.
void printTopRight(int a[][COL], int x1, int y1, int x2, int y2) {
int i = 0, j = 0;
// print values in the row.
for(i = x1; i<=x2; i++) {
printf("%d ", a[y1][i]);
}
// print values in the column.
for(j = y1 + 1; j <= y2; j++) {
printf("%d ", a[j][x2]);
}
// see if more layers need to be printed.
if(x2-x1 > 0) {
// if yes recursively call the function to
// print the bottom left of the sub matrix.
printBottomLeft(a, x1, y1 + 1, x2-1, y2);
}
}
// function to print the bottom-left peel of the matrix and
// recursively call the print top-right on the submatrix.
void printBottomLeft(int a[][COL], int x1, int y1, int x2, int y2) {
int i = 0, j = 0;
// print the values in the row in reverse order.
for(i = x2; i>=x1; i--) {
printf("%d ", a[y2][i]);
}
// print the values in the col in reverse order.
for(j = y2 - 1; j >= y1; j--) {
printf("%d ", a[j][x1]);
}
// see if more layers need to be printed.
if(x2-x1 > 0) {
// if yes recursively call the function to
// print the top right of the sub matrix.
printTopRight(a, x1+1, y1, x2, y2-1);
}
}
void printSpiral(int arr[][COL]) {
printTopRight(arr,0,0,COL-1,ROW-1);
printf("\n");
}

Pop top row
Transpose and flip upside-down (same as rotate 90 degrees counter-clockwise)
Go to 1
Python 2 code:
import itertools
arr = [[1,2,3,4],
[12,13,14,5],
[11,16,15,6],
[10,9,8,7]]
def transpose_and_yield_top(arr):
while arr:
yield arr[0]
arr = list(reversed(zip(*arr[1:])))
print list(itertools.chain(*transpose_and_yield_top(arr)))
For python 3x:
import itertools
arr = [[1,2,3,4],
[12,13,14,5],
[11,16,15,6],
[10,9,8,7]]
def transpose_and_yield_top(arr):
while arr:
yield arr[0]
arr = list(reversed(list(zip(*arr[1:]))))
print(list(itertools.chain(*transpose_and_yield_top(arr))))

I see that no one has use only one for loop and without recursion in the code, and so I want to contribute.
The idea is like this:
Imagine there is a turtle standing at point (0,0), that is, top-left corner, facing east (to the right)
It will keep going forward and each time it sees a sign, the turtle will turn right
So if we put the turtle at point (0,0) facing right-ward, and if we place the signs at appropriate places, the turtle will traverse the array in spiral way.
Now the problem is: "Where to put the signs?"
Let's see where we should put the signs (marked by #, and numbers by O):
For a grid that looks like this:
O O O O
O O O O
O O O O
O O O O
We put the signs like this:
O O O #
# O # O
O # # O
# O O #
For a grid that looks like this:
O O O
O O O
O O O
O O O
We put the signs like this:
O O #
# # O
O # O
# O #
And for a grid that looks like this:
O O O O O O O
O O O O O O O
O O O O O O O
O O O O O O O
O O O O O O O
We put the signs like this:
O O O O O O #
# O O O O # O
O # O O # O O
O # O O O # O
# O O O O O #
We can see that, unless the point is at the top-left part, the signs are places at points where the distances to the closest horizontal border and the closest vertical border are the same, while for the top-left part, the distance to the top border is one more than the distance to the left border, with priority given to top-right in case the point is horizontally centered, and to top-left in case the point is vertically centered.
This can be realized in a simple function quite easily, by taking the minimum of (curRow and height-1-curRow), then the minimum of (curCol and width-1-curCol) and compare if they are the same. But we need to account for the upper-left case, that is, when the minimum is curRow and curCol themselves. In that case we reduce the vertical distance accordingly.
Here is the C code:
#include <stdio.h>
int shouldTurn(int row, int col, int height, int width){
int same = 1;
if(row > height-1-row) row = height-1-row, same = 0; // Give precedence to top-left over bottom-left
if(col >= width-1-col) col = width-1-col, same = 0; // Give precedence to top-right over top-left
row -= same; // When the row and col doesn't change, this will reduce row by 1
if(row==col) return 1;
return 0;
}
int directions[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
void printSpiral(int arr[4][4], int height, int width){
int directionIdx=0, i=0;
int curRow=0, curCol=0;
for(i=0; i<height*width; i++){
printf("%d ",arr[curRow][curCol]);
if(shouldTurn(curRow, curCol, height, width)){
directionIdx = (directionIdx+1)%4;
}
curRow += directions[directionIdx][0];
curCol += directions[directionIdx][1];
}
printf("\n");
}
int main(){
int arr[4][4]= {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
printSpiral(arr, 4, 4);
printSpiral(arr, 3, 4);
}
Which outputs:
1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10
1 2 3 4 8 12 11 10 9 5 6 7

Here are the three interesting ways
Reading in spiral way can be treated like a snake moving towards boundary and turning on hitting the boundary or itself (I find it elegant and most efficient being a single loop of N iterations)
ar = [
[ 0, 1, 2, 3, 4],
[15, 16, 17, 18, 5],
[14, 23, 24, 19, 6],
[13, 22, 21, 20, 7],
[12, 11, 10, 9, 8]]
def print_spiral(ar):
"""
assuming a rect array
"""
rows, cols = len(ar), len(ar[0])
r, c = 0, -1 # start here
nextturn = stepsx = cols # move so many steps
stepsy = rows-1
inc_c, inc_r = 1, 0 # at each step move this much
turns = 0 # how many times our snake had turned
for i in range(rows*cols):
c += inc_c
r += inc_r
print ar[r][c],
if i == nextturn-1:
turns += 1
# at each turn reduce how many steps we go next
if turns%2==0:
nextturn += stepsx
stepsy -= 1
else:
nextturn += stepsy
stepsx -= 1
# change directions
inc_c, inc_r = -inc_r, inc_c
print_spiral(ar)
output:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
A recursive approach would be to print outer layer and call same function for inner rectangle e.g.
def print_spiral(ar, sr=0, sc=0, er=None, ec=None):
er = er or len(ar)-1
ec = ec or len(ar[0])-1
if sr > er or sc > ec:
print
return
# print the outer layer
top, bottom, left, right = [], [], [], []
for c in range(sc,ec+1):
top.append(ar[sr][c])
if sr != er:
bottom.append(ar[er][ec-(c-sc)])
for r in range(sr+1,er):
right.append(ar[r][ec])
if ec != sc:
left.append(ar[er-(r-sr)][sc])
print " ".join([str(a) for a in top + right + bottom + left]),
# peel next layer of onion
print_spiral(ar, sr+1, sc+1, er-1, ec-1)
Finally here is a small snippet to do it, not efficient but fun :), basically it prints top row, and rotates whole rectangle anti-clockwise and repeats
def print_spiral(ar):
if not ar: return
print " ".join(str(a) for a in ar[0]),
ar = zip(*[ reversed(row) for row in ar[1:]])
print_spiral(ar)

This program works for any n*n matrix..
public class circ {
public void get_circ_arr (int n,int [][] a)
{
int z=n;
{
for (int i=0;i<n;i++)
{
for (int l=z-1-i;l>=i;l--)
{
int k=i;
System.out.printf("%d",a[k][l]);
}
for (int j=i+1;j<=z-1-i;j++)
{
int k=i;
{
System.out.printf("%d",a[j][k]);
}
}
for (int j=i+1;j<=z-i-1;j++)
{
int k=z-1-i;
{
System.out.printf("%d",a[k][j]);
}
}
for (int j=z-2-i;j>=i+1;j--)
{
int k=z-i-1;
{
System.out.printf("%d",a[j][k]);
}
}
}
}
}
}
Hope it helps

I was obsessed with this problem when I was learning Ruby. This was the best I could do:
def spiral(matrix)
matrix.empty? ? [] : matrix.shift + spiral(matrix.transpose.reverse)
end
You can check out some of my other solutions by stepping back through the revisions in this gist. Also, if you follow the link back to whom I forked the gist from, you'll find some other clever solutions. Really interesting problem that can be solved in multiple elegant ways — especially in Ruby.

JavaScript solution:
var printSpiral = function (matrix) {
var i;
var top = 0;
var left = 0;
var bottom = matrix.length;
var right = matrix[0].length;
while (top < bottom && left < right) {
//print top
for (i = left; i < right; i += 1) {
console.log(matrix[top][i]);
}
top++;
//print right column
for (i = top; i < bottom; i += 1) {
console.log(matrix[i][right - 1]);
}
right--;
if (top < bottom) {
//print bottom
for (i = right - 1; i >= left; i -= 1) {
console.log(matrix[bottom - 1][i]);
}
bottom--;
}
if (left < right) {
//print left column
for (i = bottom - 1; i >= top; i -= 1) {
console.log(matrix[i][left]);
}
left++;
}
}
};

One solution involves directions right, left, up, down, and their corresponding limits (indices). Once the first row is printed, and direction changes (from right) to down, the row is discarded by incrementing the upper limit. Once the last column is printed, and direction changes to left, the column is discarded by decrementing the right hand limit... Details can be seen in the self-explanatory C code.
#include <stdio.h>
#define N_ROWS 5
#define N_COLS 3
void print_spiral(int a[N_ROWS][N_COLS])
{
enum {up, down, left, right} direction = right;
int up_limit = 0,
down_limit = N_ROWS - 1,
left_limit = 0,
right_limit = N_COLS - 1,
downcount = N_ROWS * N_COLS,
row = 0,
col = 0;
while(printf("%d ", a[row][col]) && --downcount)
if(direction == right)
{
if(++col > right_limit)
{
--col;
direction = down;
++up_limit;
++row;
}
}
else if(direction == down)
{
if(++row > down_limit)
{
--row;
direction = left;
--right_limit;
--col;
}
}
else if(direction == left)
{
if(--col < left_limit)
{
++col;
direction = up;
--down_limit;
--row;
}
}
else /* direction == up */
if(--row < up_limit)
{
++row;
direction = right;
++left_limit;
++col;
}
}
void main()
{
int a[N_ROWS][N_COLS] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
print_spiral(a);
}
Link for Testing and Download.

Given a matrix of chars, implement a method that prints all characters in the following order: first the outer circle,
then the next one and so on.
public static void printMatrixInSpiral(int[][] mat){
if(mat.length == 0|| mat[0].length == 0){
/* empty matrix */
return;
}
StringBuffer str = new StringBuffer();
int counter = mat.length * mat[0].length;
int startRow = 0;
int endRow = mat.length-1;
int startCol = 0;
int endCol = mat[0].length-1;
boolean moveCol = true;
boolean leftToRight = true;
boolean upDown = true;
while(counter>0){
if(moveCol){
if(leftToRight){
/* printing entire row left to right */
for(int i = startCol; i <= endCol ; i++){
str.append(mat[startRow][i]);
counter--;
}
leftToRight = false;
moveCol = false;
startRow++;
}
else{
/* printing entire row right to left */
for(int i = endCol ; i >= startCol ; i--){
str.append(mat[endRow][i]);
counter--;
}
leftToRight = true;
moveCol = false;
endRow--;
}
}
else
{
if(upDown){
/* printing column up down */
for(int i = startRow ; i <= endRow ; i++){
str.append(mat[i][endCol]);
counter--;
}
upDown = false;
moveCol = true;
endCol--;
}
else
{
/* printing entire col down up */
for(int i = endRow ; i >= startRow ; i--){
str.append(mat[i][startCol]);
counter--;
}
upDown = true;
moveCol = true;
startCol++;
}
}
}
System.out.println(str.toString());
}

Two dimensional N*N Matrix is Square matrix
Idea:
We have to traverse in four different directions to traverse like spiral.
We have to traverse inside matrix once one layer of spiral is over.
So total, we need 5 loops, 4 loops to traverse like spiral and 1 loop to traverse through the layers.
public void printSpiralForm(int[][] a, int length)
{
for( int i = 0 , j = length-1 ; i < j ; i++ , j-- )
{
for( int k = i ; k < j ; k++ )
{
System.out.print( a[i][k] + " " ) ;
}
for( int k = i ; k < j ; k++ )
{
System.out.print(a[k][j] + " ");
}
for( int k = j ; k > i ; k-- )
{
System.out.print(a[j][k] + " ") ;
}
for( int k = j ; k > i ; k-- )
{
System.out.print( a[k][i] + " " ) ;
}
}
if ( length % 2 == 1 )
{
System.out.println( a[ length/2 ][ length/2 ] ) ;
}
}

Just keep it simple -->
public class spiralMatrix {
public static void printMatrix(int[][] matrix, int rows, int col)
{
int rowStart=0;
int rowEnd=rows-1;
int colStart=0;
int colEnd=col-1;
while(colStart<=colEnd && rowStart<=rowEnd)
{
for(int i=colStart;i<colEnd;i++)
System.out.println(matrix[rowStart][i]);
for(int i=rowStart;i<rowEnd;i++)
System.out.println(matrix[i][colEnd]);
for(int i=colEnd;i>colStart;i--)
System.out.println(matrix[rowEnd][i]);
for(int i=rowEnd;i>rowStart;i--)
System.out.println(matrix[i][colStart]);
rowStart++;
colEnd--;
rowEnd--;
colStart++;
}
}
public static void main(String[] args){
int[][] array={{1,2,3,4},{5,6,7,8}};
printMatrix(array,2,4);
}
}

This is my implementation:
public static void printMatrix(int matrix[][], int M, int N){
int level = 0;
int min = (M < N) ? M:N;
System.out.println();
while(level <= min/2){
for(int j = level; j < N - level - 1; j++){
System.out.print(matrix[level][j] + "\t");
}
for(int i = level; i < M - level - 1; i++) {
System.out.print(matrix[i][N - level - 1] + "\t");
}
for(int j = N - level - 1; j > level; j--){
System.out.print(matrix[M - level - 1][j] + "\t");
}
for(int i = M - level - 1; i > level; i-- ){
System.out.print(matrix[i][level] + "\t");
}
level++;
}
}

Here is my solution. Please correct if I'm wrong.
class Spiral:
def spiralOrder(self, A):
result = []
c = []
c.append(A[0])
b = A[1:]
while len(b) > 0:
b = self.rotate(b)
c.append(b[0])
b = b[1:]
for item in c:
for fitem in item:
print fitem,
result.append(fitem)
return result
def rotate(self,a):
b = []
l = zip(*a)
for i in xrange(len(l)-1,-1,-1):
b.append(list(l[i]))
return b
if __name__ == '__main__':
a = [[1, 2, 3,3], [4, 5, 6,6], [7, 8, 9,10]]
s = Spiral()
s.spiralOrder(a)

Slash Top Row -> Transpose -> Flip -> Repeat.
void slashTransposeFlip(int[][] m){
if( m.length * m[0].length == 1){ //only one element left
System.out.print(m[0][0]);
}else{
//print the top row
for(int a:m[0]){System.out.print(a+" ");}
//slash the top row from the matrix.
int[][] n = Arrays.copyOfRange(m,1,m.length);
int[][] temp = n;
int rows = temp.length;
int columns = temp[0].length;
//invert rows and columns and create new array
n = new int[columns][rows];
//transpose
for(int x=0;x<rows;x++)
for(int y=0;y<columns;y++)
n[y][x] = temp[x][y];
//flipping time
for (int i = 0; i < n.length / 2; i++) {
int[] t = n[i];
n[i] = n[n.length - 1 - i];
n[n.length - 1 - i] = t;
}
//recursively call again the reduced matrix.
slashTransposeFlip(n);
}
}

Complexity: Single traverse O(n)
Please let me add my single loop answer with complexity O(n). I have observed that during left-right and right-left traverse of the matrix, there is an increase and decrease by one respectively in the row-major index. Similarly, for the top-bottom and bottom-top traverse there is increase and decrease by n_cols. Thus I made an algorithm for that. For example, given a (3x5) matrix with entries the row-major indexes the print output is: 1,2,3,4,5,10,15,14,13,12,11,6,7,8,9.
------->(+1)
^ 1 2 3 4 5 |
(+n_cols) | 6 7 8 9 10 | (-n_cols)
| 11 12 13 14 15
(-1)<-------
Code solution:
#include <iostream>
using namespace std;
int main() {
// your code goes here
bool leftToRight=true, topToBottom=false, rightToLeft=false, bottomToTop=false;
int idx=0;
int n_rows = 3;
int n_cols = 5;
int cnt_h = n_cols, cnt_v = n_rows, cnt=0;
int iter=1;
for (int i=0; i <= n_rows*n_cols + (n_rows - 1)*(n_cols - 1)/2; i++){
iter++;
if(leftToRight){
if(cnt >= cnt_h){
cnt_h--; cnt=0;
leftToRight = false; topToBottom = true;
//cout << "Iter: "<< iter << " break_leftToRight"<<endl;
}else{
cnt++;
idx++;
//cout << "Iter: "<< iter <<" idx: " << idx << " cnt: "<< cnt << " cnt_h: "<< cnt_h<< endl;
cout<< idx << endl;
}
}else if(topToBottom){
if(cnt >= cnt_v-1){
cnt_v--; cnt=0;
leftToRight = false; topToBottom = false; rightToLeft=true;
//cout << "Iter: "<< iter << " break_topToBottom"<<endl;
}else{
cnt++;
idx+=n_cols;
//cout << "Iter: "<< iter << " idx: " << idx << " cnt: "<< cnt << " cnt_v: "<< cnt_h<< endl;
cout << idx <<endl;
}
}else if(rightToLeft){
if(cnt >= cnt_h){
cnt_h--; cnt=0;
leftToRight = false; topToBottom = false; rightToLeft=false; bottomToTop=true;
//cout << "Iter: "<< iter << " break_rightToLeft"<<endl;
//cout<< idx << endl;
}else{
cnt++;
idx--;
//cout << "Iter: "<< iter << " idx: " << idx << " cnt: "<< cnt << " cnt_h: "<< cnt_h<< endl;
cout << idx <<endl;
}
}else if(bottomToTop){
if(cnt >= cnt_v-1){
cnt_v--; cnt=0;
leftToRight = true; topToBottom = false; rightToLeft=false; bottomToTop=false;
//cout << "Iter: "<< iter << " break_bottomToTop"<<endl;
}else{
cnt++;
idx-=n_cols;
//cout << "Iter: "<< iter << " idx: " << idx << " cnt: "<< cnt << " cnt_v: "<< cnt_h<< endl;
cout<< idx << endl;
}
}
//cout << i << endl;
}
return 0;
}

function spiral(a) {
var s = [];
while (a.length) {
// concat 1st row, push last cols, rotate 180 (reverse inner/outer)...
s = s.concat(a.shift());
a = a
.map(function(v) {
s.push(v.pop());
return v.reverse();
})
.reverse();
}
return s;
}
var arr = [
[1, 2, 3, 4],
[12, 13, 14, 5],
[11, 16, 15, 6],
[10, 9, 8, 7]
];
console.log(spiral(arr));// -> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
arr = [
[0, 1, 2, 3, 4],
[15, 16, 17, 18, 5],
[14, 23, 24, 19, 6],
[13, 22, 21, 20, 7],
[12, 11, 10, 9, 8]
];
console.log(spiral(arr));// -> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]

For printing a 2-D matrix consider matrix as a composition of rectangles and/or line where smaller rectangle is fitted into larger one, take boundary of matrix which forms a rectangle to be printed, starting with up-left element each time in each layer; once done with this go inside for next layer of smaller rectangle, in case i don't have a rectangle then it should be line to be printed, a horizontal or vertical. I have pasted the code with an example matrix, HTH.
#include <stdio.h>
int a[2][4] = { 1, 2 ,3, 44,
8, 9 ,4, 55 };
void print(int, int, int, int);
int main() {
int row1, col1, row2, col2;
row1=0;
col1=0;
row2=1;
col2=3;
while(row2>=row1 && col2>=col1)
{
print(row1, col1, row2, col2);
row1++;
col1++;
row2--;
col2--;
}
return 0;
}
void print(int row1, int col1, int row2, int col2) {
int i=row1;
int j=col1;
/* This is when single horizontal line needs to be printed */
if( row1==row2 && col1!=col2) {
for(j=col1; j<=col2; j++)
printf("%d ", a[i][j]);
return;
}
/* This is when single vertical line needs to be printed */
if( col1==col2 && row1!=row2) {
for(i=row1; j<=row2; i++)
printf("%d ", a[i][j]);
return;
}
/* This is reached when there is a rectangle to be printed */
for(j=col1; j<=col2; j++)
printf("%d ", a[i][j]);
for(j=col2,i=row1+1; i<=row2; i++)
printf("%d ", a[i][j]);
for(i=row2,j=col2-1; j>=col1; j--)
printf("%d ", a[i][j]);
for(j=col1,i=row2-1; i>row1; i--)
printf("%d ", a[i][j]);
}

Here is my implementation in Java:
public class SpiralPrint {
static void spiral(int a[][],int x,int y){
//If the x and y co-ordinate collide, break off from the function
if(x==y)
return;
int i;
//Top-left to top-right
for(i=x;i<y;i++)
System.out.println(a[x][i]);
//Top-right to bottom-right
for(i=x+1;i<y;i++)
System.out.println(a[i][y-1]);
//Bottom-right to bottom-left
for(i=y-2;i>=x;i--)
System.out.println(a[y-1][i]);
//Bottom left to top-left
for(i=y-2;i>x;i--)
System.out.println(a[i][x]);
//Recursively call spiral
spiral(a,x+1,y-1);
}
public static void main(String[] args) {
int a[][]={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
spiral(a,0,4);
/*Might be implemented without the 0 on an afterthought, all arrays will start at 0 anyways. The second parameter will be the dimension of the array*/
}
}

//shivi..coding is adictive!!
#include<shiviheaders.h>
#define R 3
#define C 6
using namespace std;
void PrintSpiral(int er,int ec,int arr[R][C])
{
int sr=0,sc=0,i=0;
while(sr<=er && sc<=ec)
{
for(int i=sc;i<=ec;++i)
cout<<arr[sr][i]<<" ";
++sr;
for(int i=sr;i<=er;++i)
cout<<arr[i][ec]<<" ";
ec--;
if(sr<=er)
{
for(int i=ec;i>=sc;--i)
cout<<arr[er][i]<<" ";
er--;
}
if(sc<=ec)
{
for(int i=er;i>=sr;--i)
cout<<arr[i][sc]<<" ";
++sc;
}
}
}
int main()
{
int a[R][C] = { {1, 2, 3, 4, 5, 6},
{7, 8, 9, 10, 11, 12},
{13, 14, 15, 16, 17, 18}
};
PrintSpiral(R-1, C-1, a);
}

int N = Integer.parseInt(args[0]);
// create N-by-N array of integers 1 through N
int[][] a = new int[N][N];
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
a[i][j] = 1 + N*i + j;
// spiral
for (int i = N-1, j = 0; i > 0; i--, j++) {
for (int k = j; k < i; k++) System.out.println(a[j][k]);
for (int k = j; k < i; k++) System.out.println(a[k][i]);
for (int k = i; k > j; k--) System.out.println(a[i][k]);
for (int k = i; k > j; k--) System.out.println(a[k][j]);
}
// special case for middle element if N is odd
if (N % 2 == 1) System.out.println(a[(N-1)/2][(N-1)/2]);
}
}

Java code if anybody is interested.
Input:
4
1 2 3 4
5 6 7 8
9 1 2 3
4 5 6 7
Output: 1 2 3 4 8 3 7 6 5 4 9 5 6 7 2 1
public class ArraySpiralPrinter {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); //marrix size
//read array
int[][] ar = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
ar[i][j] = sc.nextInt();
}
}
printTopRight(0, 0, n - 1, n - 1, ar);
}
//prints top and right layers.
//(x1,y1) to (x1, y2) - top layer & (x1,y2) to (x2, y2)
private static void printTopRight(int x1, int y1, int x2, int y2, int[][] ar) {
//print row values - top
for (int y = y1; y <= y2; y++) {
System.out.printf("%d ", ar[x1][y]);
}
//print column value - right
for (int x = x1 + 1; x <= x2; x++) {
System.out.printf("%d ", ar[x][y2]);
}
//are there any remaining layers
if (x2 - x1 > 0) {
//call printBottemLeft
printBottomLeft(x1 + 1, y1, x2, y2 - 1, ar);
}
}
//prints bottom and left layers in reverse order
//(x2,y2) to (x2, y1) - bottom layer & (x2,y1) to (x1, y1)
private static void printBottomLeft(int x1, int y1, int x2, int y2, int[][] ar) {
//print row values in reverse order - bottom
for (int y = y2; y >= y1; y--) {
System.out.printf("%d ", ar[x2][y]);
}
//print column value in reverse order - left
for (int x = x2-1; x >= x1; x--) {
System.out.printf("%d ", ar[x][y1]);
}
//are there any remaining layers
if (x2 - x1 > 0) {
printTopRight(x1, y1 + 1, x2 - 1, y2, ar);
}
}
}

This is a recursive version in C that I could think of:-
void printspiral (int[][100],int, int, int, int);
int main()
{
int r,c, i, j;
printf ("Enter the dimensions of the matrix");
scanf("%d %d", &r, &c);
int arr[r][100];
int min = (r<c?r:c);
if (min%2 != 0) min = min/2 +1;
for (i = 0;i<r; i++)
for (j = 0; j<c; j++)
scanf ("%d",&arr[i][j]);
printspiral(arr,0,r,c,min );
}
void printspiral (int arr[][100], int i, int j, int k, int min)
{
int a;
for (a = i; a<k;a++)
printf("%d\n", arr[i][a]);
for (a=i+1;a<j;a++)
printf ("%d\n", arr[a][k-1]);
for (a=k-2; a>i-1;a--)
printf("%d\n", arr[j-1][a]);
for (a=j-2; a>i; a--)
printf("%d\n", arr[a][i]);
if (i < min)
printspiral(arr,i+1, j-1,k-1, min);
}

http://www.technicalinterviewquestions.net/2009/03/print-2d-array-matrix-spiral-order.html
here is the best explanation for the above answer :) along with diagram :)

public static void printSpiral1(int array[][],int row,int col){
int rowStart=0,colStart=0,rowEnd=row-1,colEnd=col-1;
int i;
while(rowStart<=rowEnd && colStart<= colEnd){
for(i=colStart;i<=colEnd;i++)
System.out.print(" "+array[rowStart][i]);
for(i=rowStart+1;i<=rowEnd;i++)
System.out.print(" "+array[i][colEnd]);
for(i=colEnd-1;i>=colStart;i--)
System.out.print(" "+array[rowEnd][i]);
for(i=rowEnd-1;i>=rowStart+1;i--)
System.out.print(" "+array[i][colStart]);
rowStart++;
colStart++;
rowEnd--;
colEnd--;
}
}

public class SpiralPrint{
//print the elements of matrix in the spiral order.
//my idea is to use recursive, for each outer loop
public static void printSpiral(int[][] mat, int layer){
int up = layer;
int buttom = mat.length - layer - 1;
int left = layer;
int right = mat[0].length - layer - 1;
if(up > buttom+1 || left > right + 1)
return; // termination condition
//traverse the other frame,
//print up
for(int i = left; i <= right; i ++){
System.out.print( mat[up][i]+ " " );
}
//print right
for(int i = up + 1; i <=buttom; i ++){
System.out.print(mat[i][right] + " ");
}
//print buttom
for(int i = right - 1; i >= left; i --){
System.out.print(mat[buttom][i] + " ");
}
//print left
for(int i = buttom - 1; i > up; i --){
System.out.print(mat[i][left] + " ");
}
//recursive call for the next level
printSpiral(mat, layer + 1);
}
public static void main(String[] args){
int[][] mat = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}, {13,14,15,16}};
int[][] mat2 = {{1,2,3}, {4,5,6}, {7,8,9}, {10,11,12}};
SpiralPrint.printSpiral(mat2,0);
return;
}
}

Here is my solution in C#:
public static void PrintSpiral(int[][] matrix, int n)
{
if (matrix == null)
{
return;
}
for (int layer = 0; layer < Math.Ceiling(n / 2.0); layer++)
{
var start = layer;
var end = n - layer - 1;
var offset = end - 1;
Console.Write("Layer " + layer + ": ");
// Center case
if (start == end)
{
Console.Write(matrix[start][start]);
}
// Top
for (int i = start; i <= offset; i++)
{
Console.Write(matrix[start][i] + " ");
}
// Right
for (int i = start; i <= offset; i++)
{
Console.Write(matrix[i][end] + " ");
}
// Bottom
for (int i = end; i > start; i--)
{
Console.Write(matrix[end][i] + " ");
}
// Left
for (int i = end; i > start; i--)
{
Console.Write(matrix[i][start] + " ");
}
Console.WriteLine();
}
}

Here's my approach using an Iterator . Note this solves almost the same problem..
Complete code here : https://github.com/rdsr/algorithms/blob/master/src/jvm/misc/FillMatrix.java
import java.util.Iterator;
class Pair {
final int i;
final int j;
Pair(int i, int j) {
this.i = i;
this.j = j;
}
#Override
public String toString() {
return "Pair [i=" + i + ", j=" + j + "]";
}
}
enum Direction {
N, E, S, W;
}
class SpiralIterator implements Iterator<Pair> {
private final int r, c;
int ri, ci;
int cnt;
Direction d; // current direction
int level; // spiral level;
public SpiralIterator(int r, int c) {
this.r = r;
this.c = c;
d = Direction.E;
level = 1;
}
#Override
public boolean hasNext() {
return cnt < r * c;
}
#Override
public Pair next() {
final Pair p = new Pair(ri, ci);
switch (d) {
case E:
if (ci == c - level) {
ri += 1;
d = changeDirection(d);
} else {
ci += 1;
}
break;
case S:
if (ri == r - level) {
ci -= 1;
d = changeDirection(d);
} else {
ri += 1;
}
break;
case W:
if (ci == level - 1) {
ri -= 1;
d = changeDirection(d);
} else {
ci -= 1;
}
break;
case N:
if (ri == level) {
ci += 1;
level += 1;
d = changeDirection(d);
} else {
ri -= 1;
}
break;
}
cnt += 1;
return p;
}
private static Direction changeDirection(Direction d) {
switch (d) {
case E:
return Direction.S;
case S:
return Direction.W;
case W:
return Direction.N;
case N:
return Direction.E;
default:
throw new IllegalStateException();
}
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
}
public class FillMatrix {
static int[][] fill(int r, int c) {
final int[][] m = new int[r][c];
int i = 1;
final Iterator<Pair> iter = new SpiralIterator(r, c);
while (iter.hasNext()) {
final Pair p = iter.next();
m[p.i][p.j] = i;
i += 1;
}
return m;
}
public static void main(String[] args) {
final int r = 19, c = 19;
final int[][] m = FillMatrix.fill(r, c);
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
System.out.print(m[i][j] + " ");
}
System.out.println();
}
}
}

Complete pure C program for any 2D array matrix with given row x column.
#include <stdio.h>
void printspiral(int *p,int r, int c) {
int i=0,j=0,m=1,n=0;
static int firstrun=1,gCol;
if (!p||r<=0||c<=0)
return ;
if(firstrun) {
gCol=c;
firstrun=0;
}
for(i=0,j=0;(0<=i && i<c)&&(0<=j && j<r);i+=m,j+=n) {
printf(" %d",p[i+j*gCol]);
if (i==0 && j==1 && (i+1)!=c) break;
else if (i+1==c && !j) {m=0;n=1;}
else if (i+1==c && j+1==r && j) {n=0;m=-1;}
else if (i==0 && j+1==r && j) {m=0;n=-1;}
}
printspiral(&p[i+j*gCol+1],r-2,c-2);
firstrun=1;
printf("\n");
}
int main() {
int a[3][3]={{0,1,2},{3,4,5},{6,7,8}};
int b[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}};
int c[4][3]={{0,1,2},{3,4,5},{6,7,8},{9,10,11}};
int d[3][1]={{0},{1},{2}};
int e[1][3]={{0,1,2}};
int f[1][1]={{0}};
int g[5][5]={{0,1,2,3,4},{5,6,7,8,9},{10,11,12,13,14},{15,16,17,18,19},{20,21,22,23,24}};
printspiral(a,3,3);
printspiral(b,3,4);
printspiral(c,4,3);
printspiral(d,3,1);
printspiral(e,1,3);
printspiral(f,1,1);
printspiral(g,5,5);
return 0;
}

This question is related to this one: Matrix arrangement issues in php
The answers presented seem to work but are complicated to understand. A very simple way to solve this is divide and conquer i.e., after reading the edge, remove it and the next read will be much simpler. Check out a complete solution in PHP below:
#The source number matrix
$source[0] = array(1, 2, 3, 4);
$source[1] = array(5, 6, 7, 8);
$source[2] = array(9, 10, 11, 12);
$source[3] = array(13, 14, 15, 16);
$source[4] = array(17, 18, 19, 20);
#Get the spiralled numbers
$final_spiral_list = get_spiral_form($source);
print_r($final_spiral_list);
function get_spiral_form($matrix)
{
#Array to hold the final number list
$spiralList = array();
$result = $matrix;
while(count($result) > 0)
{
$resultsFromRead = get_next_number_circle($result, $spiralList);
$result = $resultsFromRead['new_source'];
$spiralList = $resultsFromRead['read_list'];
}
return $spiralList;
}
function get_next_number_circle($matrix, $read)
{
$unreadMatrix = $matrix;
$rowNumber = count($matrix);
$colNumber = count($matrix[0]);
#Check if the array has one row or column
if($rowNumber == 1) $read = array_merge($read, $matrix[0]);
if($colNumber == 1) for($i=0; $i<$rowNumber; $i++) array_push($read, $matrix[$i][0]);
#Check if array has 2 rows or columns
if($rowNumber == 2 || ($rowNumber == 2 && $colNumber == 2))
{
$read = array_merge($read, $matrix[0], array_reverse($matrix[1]));
}
if($colNumber == 2 && $rowNumber != 2)
{
#First read left to right for the first row
$read = array_merge($read, $matrix[0]);
#Then read down on right column
for($i=1; $i<$rowNumber; $i++) array_push($read, $matrix[$i][1]);
#..and up on left column
for($i=($rowNumber-1); $i>0; $i--) array_push($read, $matrix[$i][0]);
}
#If more than 2 rows or columns, pick up all the edge values by spiraling around the matrix
if($rowNumber > 2 && $colNumber > 2)
{
#Move left to right
for($i=0; $i<$colNumber; $i++) array_push($read, $matrix[0][$i]);
#Move top to bottom
for($i=1; $i<$rowNumber; $i++) array_push($read, $matrix[$i][$colNumber-1]);
#Move right to left
for($i=($colNumber-2); $i>-1; $i--) array_push($read, $matrix[$rowNumber-1][$i]);
#Move bottom to top
for($i=($rowNumber-2); $i>0; $i--) array_push($read, $matrix[$i][0]);
}
#Now remove these edge read values to create a new reduced matrix for the next read
$unreadMatrix = remove_top_row($unreadMatrix);
$unreadMatrix = remove_right_column($unreadMatrix);
$unreadMatrix = remove_bottom_row($unreadMatrix);
$unreadMatrix = remove_left_column($unreadMatrix);
return array('new_source'=>$unreadMatrix, 'read_list'=>$read);
}
function remove_top_row($matrix)
{
$removedRow = array_shift($matrix);
return $matrix;
}
function remove_right_column($matrix)
{
$neededCols = count($matrix[0]) - 1;
$finalMatrix = array();
for($i=0; $i<count($matrix); $i++) $finalMatrix[$i] = array_slice($matrix[$i], 0, $neededCols);
return $finalMatrix;
}
function remove_bottom_row($matrix)
{
unset($matrix[count($matrix)-1]);
return $matrix;
}
function remove_left_column($matrix)
{
$neededCols = count($matrix[0]) - 1;
$finalMatrix = array();
for($i=0; $i<count($matrix); $i++) $finalMatrix[$i] = array_slice($matrix[$i], 1, $neededCols);
return $finalMatrix;
}

// Program to print a matrix in spiral order
#include <stdio.h>
int main(void) {
// your code goes here
int m,n,i,j,k=1,c1,c2,r1,r2;;
scanf("%d %d",&m,&n);
int a[m][n];
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
scanf("%d",&a[i][j]);
}
}
r1=0;
r2=m-1;
c1=0;
c2=n-1;
while(k<=m*n)
{
for(i=c1;i<=c2;i++)
{
k++;
printf("%d ",a[r1][i]);
}
for(j=r1+1;j<=r2;j++)
{
k++;
printf("%d ",a[j][c2]);
}
for(i=c2-1;i>=c1;i--)
{
k++;
printf("%d ",a[r2][i]);
}
for(j=r2-1;j>=r1+1;j--)
{
k++;
printf("%d ",a[j][c1]);
}
c1++;
c2--;
r1++;
r2--;
}
return 0;
}

Related

Problem: Shortest path in a grid between multiple point with a constraint

Problem description:
I'm trying to solve a problem on the internet and I wasn't able to pass all testcases, well, because my logic is flawed and incorrect. The flaw: I assumed starting to the closest 'F' point will get me to the shortest paths always, at all cases.
Thinks I thought of:
Turning this into a graph problem and solve it based on it. > don't think this would work because of the constraint?
Try to obtain all possible solution combinations > does not scale, if !8 combination exist.
#include <iostream>
#include <utility>
#include <string>
#include <vector>
#include <queue>
using namespace std;
#define N 4
#define M 4
int SearchingChallenge(string strArr[], int arrLength) {
int n = arrLength, m = n, steps = 0, food = 0;
// initial position of charlie
int init_j = 0;
int init_i = 0;
queue<pair<int,int>> q;
// directions
vector<int> offsets = {0,-1,0,1,0};
vector<pair<int,int>> food_nodes;
//store visited nodes, no need for extra work to be done.
int visited_nodes[4][4] = {{0}};
// get number of food pieces
for(int i = 0; i < m; i++){
for(int j = 0; j < n ; j++){
if(strArr[i][j] == 'F')
{
food++;
}
if(strArr[i][j] == 'C')
{
strArr[i][j] = 'O';
food_nodes.push_back({i,j});
}
}
}
while(food_nodes.size()>0){
food_nodes.erase(food_nodes.begin());
int break_flag=0;
q.push(food_nodes[0]);
while(!q.empty()){
int size = q.size();
while(size-->0){
pair<int,int> p = q.front();
q.pop();
for(int k = 0; k < 4; k++){
int ii = p.first + offsets[k], jj = p.second + offsets[k+1];
/* if(ii == 0 && jj == 3)
printf("HI"); */
if(jj >= 0 && jj < 4 && ii < 4 && ii >=0){
if(strArr[ii][jj] == 'F'){
strArr[ii][jj] = 'O';
while(!q.empty())
q.pop();
break_flag=1;
food--;
food_nodes.push_back({ii,jj});
break;
}
if(strArr[ii][jj] == 'O')
q.push({ii,jj});
if(strArr[ii][jj] == 'H' && food == 0)
return ++steps;
}
}
if(break_flag==1)
break;
}
steps++;
if(break_flag==1)
break;
}
}
return 0;
}
int main(void) {
// keep this function call here
/* Note: In C++ you first have to initialize an array and set
it equal to the stdin to test your code with arrays. */
//passing testcase
//string A[4] = {"OOOO", "OOFF", "OCHO", "OFOO"};
//failing testcase
string A[4] = {"FOOF", "OCOO", "OOOH", "FOOO"}
int arrLength = sizeof(A) / sizeof(*A);
cout << SearchingChallenge(A, arrLength);
return 0;
}
Your help is appreciated.
I have wrote the javascript solution for the mentioned problem..
function SearchingChallenge(strArr) {
// create coordinate array
const matrix = [
[0, 0], [0, 1], [0, 2], [0, 3],
[1, 0], [1, 1], [1, 2], [1, 3],
[2, 0], [2, 1], [2, 2], [2, 3],
[3, 0], [3, 1], [3, 2], [3, 3]
]
// flatten the strArr
const flattenArray = flatten(strArr)
// segreagate and map flattenArray with matrix to get coordinate of food,charlie and home
const segregatedCoordinates = flattenArray.reduce((obj, char, index) => {
if (char === 'F') obj['food'].push(matrix[index])
else if (char === 'C') obj['dog'] = matrix[index]
else if (char === 'H') obj['home'] = matrix[index]
return obj
}, { "food": [], dog: null, home: null })
// construct possible routes by permutating food coordinates
let possibleRoutes = permuate(segregatedCoordinates['food'])
// push dog and home in possibleRoutes at start and end positions
possibleRoutes = possibleRoutes.map((route) => {
return [segregatedCoordinates['dog'], ...route, segregatedCoordinates['home']]
})
// Calculate distances from every possible route
const distances = possibleRoutes.reduce((distances, route) => {
let moveLength = 0
for (let i = 0; i < route.length - 1; i++) {
let current = route[i], next = route[i + 1]
let xCoordinatePath = current[0] > next[0] ? (current[0] - next[0]) : (next[0] - current[0])
let yCoordinatePath = current[1] > next[1] ? (current[1] - next[1]) : (next[1] - current[1])
moveLength += xCoordinatePath + yCoordinatePath
}
distances.push(moveLength)
return distances
}, [])
return Math.min(...distances);
}
function permuate(arr) {
if (arr.length <= 2) return (arr.length === 2 ? [arr, [arr[1], arr[0]]] : arr)
return arr.reduce((res, ele, index) => {
res = [...res, ...permuate([...arr.slice(0, index), ...arr.slice(index + 1)]).map(val => [ele, ...val])]
return res
}, [])
}
function flatten(inputtedArr) {
return inputtedArr.reduce((arr, row) => {
arr = [...arr, ...row]
return arr
}, [])
}
console.log(SearchingChallenge(['FOOF', 'OCOO', 'OOOH', 'FOOO']));
You can write a DP solution where you have a 4x4x8 grid. The first two axis represent the x and y coordinate. The third one represent the binary encoding of which food item you picked already.
Each cell in the grid stores the best number of moves to get at this cell having eaten the specified foods. So for example, grid[2][2][2] is the cost of getting to cell (2,2) after having eaten the second piece of food only.
Then you set the value of the start cell, at third index 0 to 0, all the other cells to -1. You keep a list of the cells to propagate (sorted by least cost), and you add the start cell to it.
Then you repeatedly take the next cell to propagate, remove it and push the neighboring cell with cost +1 and updated food consume. Once you reach the destination cell with all food consumed, you're done.
That should take no more than 4x4x8 updates, with about the same order of priority queue insertion. O(n log(n)) where n is xy2^f. As long as you have few food items this will be almost instant.
C++ solution
I used both dfs and bfs for this problem
TIME COMPLEXITY - (4^(N×M))+NO_OF_FOODS×N×M
#include <bits/stdc++.h>
using namespace std;
//It is a dfs function it will find and store all the possible steps to eat all food in toHome map
void distAfterEatingAllFood(vector<vector<char>> &m, int countOfFood, int i, int j, int steps, map<pair<int,int>,int>&toHome){
if(i<0 || j<0 || i>=4 || j>=4 || m[i][j]=='*') return;
if(m[i][j]=='F') countOfFood--;
if(countOfFood==0){
if(!toHome.count({i,j}))
toHome[{i,j}] = steps;
else if(toHome[{i,j}]>steps)
toHome[{i,j}] = steps;
return;
}
char temp = m[i][j];
m[i][j] = '*';
distAfterEatingAllFood(m, countOfFood, i+1, j, steps+1, toHome);
distAfterEatingAllFood(m, countOfFood, i-1, j, steps+1, toHome);
distAfterEatingAllFood(m, countOfFood, i, j+1, steps+1, toHome);
distAfterEatingAllFood(m, countOfFood, i, j-1, steps+1, toHome);
m[i][j] = temp;
return;
}
//It is a bfs function it will iterate over the toHome map and find the shortest distance between the last food position to home
int lastFoodToHome(vector<vector<char>> &m, int i, int j, int steps){
queue<pair<pair<int, int>,int>>q;
vector<vector<int>> vis(4, vector<int>(4, 0));
q.push({{i, j}, steps});
vis[i][j] = 1;
int dirX[] = {0, 1, 0, -1};
int dirY[] = {1, 0, -1, 0};
while (!q.empty())
{
int x = q.front().first.first;
int y = q.front().first.second;
int steps = q.front().second;
q.pop();
if (m[x][y] == 'H')
return steps;
for (int k = 0; k < 4; k++)
{
int ni = x + dirX[k];
int nj = y + dirY[k];
if (ni >= 0 && nj >= 0 && ni < 4 && nj < 4 && !vis[ni][nj])
{
if(m[ni][nj] == 'H') return steps + 1;
q.push({{ni, nj}, steps + 1});
vis[i][j] = 1;
}
}
}
return INT_MAX;
}
int main()
{
vector<vector<char>> m(4, vector<char>(4));
int countOfFood = 0, x, y;
for (int i = 0; i < 4; i++){
for (int j = 0; j < 4; j++){
cin >> m[i][j];
if (m[i][j] == 'C'){
x = i;
y = j;
}
if (m[i][j] == 'F')
countOfFood++;
}
}
map<pair<int,int>,int>toHome;
distAfterEatingAllFood(m, countOfFood, x, y, 0, toHome);
int ans = INT_MAX;
for(auto &i:toHome){
ans = min(ans, lastFoodToHome(m, i.first.first, i.first.second, i.second));
}
cout<<ans;
return 0;
}

Print Sum of int > 0

Given a number S ( int > 0 ) and n (int > 0), print all the different subsets of len n which sum to S.
For S = 7 and n = 3, the output is the following, the output must be descending order:
5 + 1 + 1
4 + 2 + 1
3 + 3 + 1
3 + 2 + 2
Here is what I've tried so far:
vector<vector<int> > partitions(int X, int Y)
{
vector<vector<int> > v;
if (X <= 1 && X <= X - Y + 1)
{
v.resize(1);
v[0].push_back(X);
return v;
}
for (int y = min(X - 1, Y); y >= 1; y--)
{
vector<vector<int> > w = partitions(X - y, y);
for (int i = 0; i<w.size(); i++)
{
w[i].push_back(y);
v.push_back(w[i]);
}
}
return v;
}
int main()
{
vector<vector<int> > v = partitions(7, 3);
int i;
for (i = 0; i<v.size(); i++)
{
int x;
for (x = 0; x<v[i].size(); x++)
printf("%d ", v[i][x]);
printf("\n");
}
}
the first element in the matrix is s- n + 1 and full of 1 till the sum is reached, or if the s-n+1 is equal to s, then n is 1, so only s will be the solution.
p.s.: I don t know if this problem has a particular name
This may not be the best solution for your problem, since it's not a dynamic programming based solution. In this case, I'm using recursion to fill an array until I reduce the desired number to 0. In this solution, every combination will be stored in the increasing order of the elements so we prevent permutations of a already calculated solution.
#include <iostream>
void findCombinationGivenSize(int numbersArray[], int index, int num, int reducedNum, int maxNum){
if (reducedNum < 0)
return; // this is our base case
if (reducedNum == 0 && index == maxNum){ // both criteria were attended:
//the sum is up to num, and the subset contain maxNum numbers
for (int i = index - 1; i>=0; i--)
std::cout<< numbersArray[i] << " + ";
// here we will have a problem with an extra '+' on the end, but you can figure out easily how to remove it :)
std::cout<<std::endl;
return;
}
// Find the previous number stored in arrayNumber[]
int prev;
if(index == 0)
prev = 1;
else
prev = numbersArray[index-1];
for (int k = prev; k <= num; k++){
// next element of array is k
numbersArray[index] = k;
// call recursively with reduced number
findCombinationGivenSize(numbersArray, index + 1, num,reducedNum - k, maxNum);
}
}
void findCombinations(int number, int maxSubset){
int arrayNumbers[number];
findCombinationGivenSize(arrayNumbers, 0, number, number, maxSubset);
}
int main(){
int number = 7;
int maxPartitions = 3;
findCombinations(number, maxPartitions);
return 0;
}

generate a 2d array of integers from given sums of its rows and columns

I want to generate an array of integers where the total sum of each row and column in the array is known , for example if I create a 4 by 4 array in c++ and then populate it pseudo randomly with numbers between 1 and 100:
int array[4][4] = {} ;
for(int x = 0 ; x<4 ; x++){
for(int y = 0 ; y<4 ; y++){
array[x][y] = rand() % 100 + 1 ;
}
}
the array would be :
8, 50, 74, 59
31, 73, 45, 79
24, 10, 41, 66
93, 43, 88, 4
then if I sum each row and each column by :
int rowSum[4] = {} ;
int columnSum[4] = {} ;
for(int x = 0 ; x < 4; x++){
for(int y = 0 ; y < 4; y++){
rowSum[x] += array[x][y] ;
columnSum[y] += array[x][y] ;
}
}
the rowSum would be {191,228,141,228} and the columnSum = {156,176,248,208}
what I'm trying to do at this point is to generate any random 4x4 1~100 array that will satisfy rowSum and columnSum I understand there is thousands of different arrays that will sum up to the same row and column sum ,and I've been trying to write the part of the code that will generate it , I would really appreciate it if anyone can give me a clue .
It is very easy to find some solution.
Start with generating row that sum to given values. It could be as simple as making all values in each row approximately equal to rowSum[i]/n, give or take one. Of course sums of columns will not match at this point.
Now fix the columns from the leftmost to the rightmost. To fix i th column, distribute the difference between the desired sum and the actual sum equally between column entries, and then fix each row by distributing the added value equally between items i+1...n of the row.
It is easier done than said:
void reconstruct (int array[4][4], int rows[4], int cols[4])
{
// build an array with each row adding up to the correct row sum
for (int x = 0; x < 4; x++){
int s = rows[x];
for(int y = 0; y < 4 ; y++){
array[x][y] = s / (4 - y);
s -= array[x][y];
}
}
// adjust columns
for(int y = 0; y < 4 ; y++){
// calculate the adjustment
int s = 0;
for (int x = 0; x < 4; x++){
s += array[x][y];
}
int diff = s - cols[y];
// adjust the column by diff
for (int x = 0; x < 4; x++){
int k = diff / (4 - x);
array[x][y] -= k;
diff -= k;
// adjust the row by k
for (int yy = y + 1; yy < 4; ++yy)
{
int corr = k / (4 - yy);
array[x][yy] += corr;
k -= corr;
}
}
}
}
This array won't be random of course. One can randomise it by selecting x1, x2, y1, y2 and d at random and executing:
array[x1][y1] += d
array[x1][y2] -= d
array[x2][y1] -= d
array[x2][y2] += d
taking care that the resulting values won't spill out of the desired range.
Here's the quick and dirty brute force search mentioned in comments. It ought to give you a starting point. This is C, not C++.
You never said it, but I'm assuming you want the matrix elements to be non-negative. Consequently, this searches the space where each element a[i][j] can have any value in [0..min(rowsum[i], colsum[j])] with the search cut off when assigning the next array element value would admit no possible future solution.
#include <stdio.h>
int a[4][4] = {
{-1, -1, -1, -1},
{-1, -1, -1, -1},
{-1, -1, -1, -1},
{-1, -1, -1, -1}};
int rs[] = {191, 228, 141, 228};
int cs[] = {156, 176, 248, 208};
long long n_solutions = 0;
void research(int i, int j, int ii, int jj, int val);
void print_a(void);
void search(int i, int j) {
if (j < 3) {
if (i < 3) {
int m = rs[i] < cs[j] ? rs[i] : cs[j];
for (int val = 0; val <= m; ++val) research(i, j, i, j + 1, val);
} else {
if (rs[3] >= cs[j]) research(i, j, i, j + 1, cs[j]);
}
} else {
if (i < 3) {
if (cs[j] >= rs[i]) research(i, 3, i + 1, 0, rs[i]);
} else {
if (rs[3] == cs[3]) {
a[3][3] = rs[i];
if (++n_solutions % 100000000 == 0) {
printf("\n%lld\n", n_solutions);
print_a();
}
a[3][3] = -1;
}
}
}
}
void research(int i, int j, int ii, int jj, int val) {
a[i][j] = val; rs[i] -= val; cs[j] -= val;
search(ii, jj);
rs[i] += val; cs[j] += val; a[i][j] = -1;
}
void print_a(void) {
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j)
printf("%4d", a[i][j]);
printf("\n");
}
}
int main(void) {
search(0, 0);
printf("Total solutions: %lld\n", n_solutions);
return 0;
}
For example, if you replace the simple for loop with this, you won't get so many zeros in the upper left hand corner:
int b = m / 2; // m/2 can be replaced with any int in [0..m], e.g. a random value.
research(i, j, i, j + 1, b);
for (int d = 1; b + d <= m || b - d >= 0; ++d) {
if (b + d <= m) research(i, j, i, j + 1, b + d);
if (b - d >= 0) research(i, j, i, j + 1, b - d);
}
Here's the 2-billionth solution:
78 56 28 29
39 20 84 85
28 34 61 18
11 66 75 76
The problem becomes interesting if we place condition that the matrix elements must be non-negative integers. Here's an O(mn) JAVA solution based on greedy algorithm.
int m=rowSum.length;
int n=colSum.length;
int mat[][] = new int[m][n];
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
int tmp=Math.min(rowSum[i],colSum[j]);
mat[i][j]=tmp;
rowSum[i]-=tmp;
colSum[j]-=tmp;
}
}
return mat;

Find path with sum of numbers is maximum

I'm trying to find path with sum of numbers is maximum. It's only allowed to move right and down through the matrix.
I've coded it but it doesn't give me the maximum sum, and I can't figure out why it does so!.
Thanks in advance.
Here's my code
/*Given grid of positive numbers, strat from (0,0) ad end at (n,n).
Move only to RIGHT and DOWN. Find path with sum of numbers is maximum. */
#include<iostream>
using namespace std;
int grid[2][3] = { { 5, 1, 2 }, { 6, 7, 8 } };
int max(int x, int y){
if (x >= y){
return x;
}
else if (x < y){
return y;
}
}
bool valid(int r, int c){
if (r + 1 == 2 || c + 1 == 3)
return false;
else
return true;
}
int maxPathSum(int row, int column){
if (!valid(row, column))
return 0;
if (row == 1 && column == 2) //base condition
return grid[row][column];
int path1 = maxPathSum(row, column + 1); //Right
int path2 = maxPathSum(row + 1, column); //Down
return grid[row][column] + max(path1, path2);
}
int main()
{
cout << maxPathSum(0, 0) << endl;
return 0;
}
the correct answer should be 26, but the output is 6.
Your function Valid should be
bool valid (int r, int c)
{
return r < 2 && c < 3;
}
and then you got 26 (Live example).
BTW, you may use dynamic programming for this problem.
You can also use dynamic programming to solve the problem
Here is the code:
#include <bits/stdc++.h>
using namespace std;
int grid[2][3] = { { 5, 1, 2 }, { 6, 7, 8 } };
int dp[3][4];
int main()
{
for(int i=0;i<4;i++)
dp[0][i] = 0;
for(int i=0;i<3;i++)
dp[i][0] = 0;
for(int i=1;i<3;i++)
{
for(int j=1;j<4;j++)
{
dp[i][j] = grid[i-1][j-1] + max(dp[i][j-1], dp[i-1][j]);
}
}
cout << dp[2][3];
return 0;
}
Live example
Apart from DP, you can also use simple (n,m) Matrix based solution. The good part is this approach wont need recursion as DP does which can cause memory issues if matrix is bigger and space complexity is just O(n x m) i.e. input array itself. And the time complexity is also O(n x m). Following code in java illustrate the approach -
package com.company.dynamicProgramming;
import static java.lang.Integer.max;
public class MaxSumPathInMatrix {
public static void main (String[] args)
{
int mat[][] = { { 10, 10, 2, 0, 20, 4 },
{ 1, 0, 0, 30, 2, 5 },
{ 200, 10, 4, 0, 2, 0 },
{ 1, 0, 2, 20, 0, 4 }
};
System.out.println(findMaxSum2(mat));
}
/*
Given a matrix of N * M. Find the maximum path sum in matrix.
Find the one path having max sum - originating from (0,0) with traversal to either right or down till (N-1, M-1)
*/
static int findMaxSum2(int mat[][])
{
int M = mat[0].length;
int N = mat.length;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < M; j++)
{
if(i==0 && j!=0){
mat[i][j]+=mat[i][j-1];
}
else if(i!=0 && j==0){
mat[i][j]+=mat[i-1][j];
}
else if (i!=0 && j!=0){
mat[i][j]+= max(mat[i-1][j], mat[i][j-1]);
}
}
}
return mat[N-1][M-1];
}
}
Run it as -
251
Process finished with exit code 0
Further Even if you are using Dynamic Programming(DP) then use Memoization concept to reduce the time complexity.. Here is the code with DP plus memoization along complexity calculation -
package com.company.dynamicProgramming;
import java.util.HashMap;
import java.util.Map;
import static java.lang.Integer.max;
public class MaxSumPathInMatrix {
static int complexity = 0;
public static void main (String[] args)
{
int mat[][] = { { 10, 10, 2, 0, 20, 4 },
{ 1, 0, 0, 30, 2, 5 },
{ 200, 10, 4, 0, 2, 0 },
{ 1, 0, 2, 20, 0, 4 }
};
System.out.println("Max Sum : " + findMaxSum2_dp(mat, 0, 0, new HashMap<>()));
System.out.println("Time complexity : " +complexity);
}
/*
~~~> solve via ~dp~ and ~memoization~
Given a matrix of N * M. Find the maximum path sum in matrix.
Find the one path having max sum - originating from (0,0) with traversal to either right or down till (m-1, n-1)
*/
static int findMaxSum2_dp(int mat[][], int i, int j, Map<String, Integer> memo){
int M = mat[0].length;
int N = mat.length;
Integer sum = memo.get(i+"-"+j);
if(sum!= null){
return sum;
}
complexity++;
if(i==N-1 && j<M-1){
mat[i][j] += findMaxSum2_dp(mat, i, j+1, memo);
memo.put(i+"-"+j, mat[i][j]);
return mat[i][j];
}
else if(i<N-1 && j==M-1){
mat[i][j] += findMaxSum2_dp(mat, i+1, j, memo);
memo.put(i+"-"+j, mat[i][j]);
return mat[i][j];
}
else if (i<N-1 && j<M-1){
int s1 = findMaxSum2_dp(mat, i+1, j, memo);
int s2 = findMaxSum2_dp(mat, i, j+1, memo);
mat[i][j] += max(s1, s2);
memo.put(i+"-"+j, mat[i][j]);
return mat[i][j];
}
return mat[N-1][M-1] += max(mat[N-1][M-2], mat[N-2][M-1]);
}
}
Two important points to note in above code -
I am storing max sum of any sub matrix [i][j] in a store(HashMap), whenever it's max sum is ready. And in further steps if this sub matrix [i][j] reappears then I take it from store instead of processing again. As a illustration - you can see [N-1][M-1] appears 2 times in below diagram of recursion -
[N][M] = max([N][M-1]) , [N-1][M]
/ \
/ \
/ \
[N][M-1] = max ([N-1][M-1], [N][M-2]) [N-1][M] = max ([N-2][M], [N-1][M-1])
Connected with Point 1 : I have provisioned a complexity variable which I increment if I have to calculate max sum for matrix [i][j] i.e. wont find in the store. If you see the result it shows 25 in 6x4 matrix i.e. the time complexity is just O(NxM).

Merge Sort Implementation using C++

I am having trouble with trying to implement the merge sort algorithm. I would appreciate it if someone can help me out. Here is what I have.
#include <iostream>
#include <deque>
using size_type = std::deque<int>::size_type;
void print(std::deque<int> &v)
{
for(const auto &ref:v)
std::cout << ref << " ";
std::cout << std::endl;
}
void merge(std::deque<int> &vec, size_type p, size_type q, size_type r)
{
int n_1 = q - p;
int n_2 = r - q;
std::deque<int> left, right;
for(auto i = 0; i != n_1; i++)
left.push_back(vec[p + i]);
for(auto j = 0; j != n_2; j++)
right.push_back(vec[q + j]);
int i = 0, j = 0;
std::cout << "left = ";
print(left);
std::cout << "right = ";
print(right);
for(auto k = p; k != r; k++) {
if(i < n_1 && left[i] <= right[j]) {
vec[k] = left[i];
i++;
}
else if(j < n_2){
vec[k] = right[j];
j++;
}
}
}
void merge_sort(std::deque<int> &A, size_type p, size_type r)
{
int q;
if(p < r) {
q = (p + r)/2;
merge_sort(A, p, q);
merge_sort(A, q + 1, r);
merge(A, p, q, r);
}
}
int main()
{
std::deque<int> small_vec = {1, 6, 2, 10, 5, 2, 12, 6};
std::deque<int> samp_vec = {2, 9, 482, 72, 42, 3, 4, 9, 8, 73, 8, 0, 98, 72, 473, 72, 3, 4, 9, 7, 6, 5, 6953, 583};
print(small_vec);
merge_sort(small_vec, 0, small_vec.size());
print(small_vec);
return 0;
}
The output from the program is:
left =
right = 1
left = 1
right = 6
left =
right = 10
left = 1 6
right = 2 10
left =
right = 2
left =
right = 6
left = 2
right = 12 6
left = 1 2 6 10
right = 5 2 12 6
1 2 5 2 6 10 12 6
There are a few issues with your sort. Firstly the merge step is wrong. Second how you call merge is wrong. Ill suggest a few steps to improve the implementation to a correct solution, and maybe itll help you.
First my code for merge:
void merge(std::deque<int> &vec, size_type p, size_type q, size_type r)
{
std::deque<int> left, right;
int i = p, j = q+1;
while(i <= q) //change 1: to a while loop. expresses it a little simpler but
//you weren't inserting the correct left elements here
left.push_back(vec[i++]);
while(j <= r) //change 2: same thing, lets get the correct right values
right.push_back(vec[j++]);
i = 0; j = 0;
for(auto k = p; k <= r; k++) {
//change 3: alter this case to include the left over left elements! this is the main error
if(i < left.size() && left[i] <= right[j] || j >= right.size())
vec[k] = left[i++];
else if(j < right.size())
vec[k] = right[j++];
}
}
Then to change how you call merge_sort to:
merge_sort(small_vec, 0, small_vec.size()-1); //change 4: initialized r wrong
This made the sort work for me. As a review of the problems I found: 1) not grabbing the correct subarrays of left and right. 2) didn't handle merge correctly - forgot to grab all the left elements after right is gone. 3) didn't call merg_sort correctly, initializing the r parameter incorrectly.