please help me to solve the below problem in java to rotate the outer ring of matrix in anticlockwise by k element and inner ring in clockwise by k element in java and the middle element remains constant. The sample input is
m=5,n=6,k=1 where m is no of rows,n is no of column and k is the number of required shift and the input matrix is
1 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
and the expected output is
2 3 4 5 6 12
1 14 8 9 10 18
7 20 15 16 11 24
13 21 22 23 17 30
19 25 26 27 28 29
Can someone tell how to proceed for this problem as we need to do clockwise and anticlockwise both.
My solution copies one ring of matrix cells at a time. The rings are traversed step by step. For every step a case number is calculated by checking row and columns against the borders of the ring:
package ak.matrixTurn;
public class Main {
public static void main(String[] args) {
int rows = 5;
int cols = 6;
int delta = 1;
int[][] matrix = new int[rows][cols];
int[][] turned = new int[rows][cols];
// fill matrix
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
matrix[r][c] = r * cols + c + 1;
}
}
// copy 1:1 (not turned yet)
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
turned[r][c] = matrix[r][c];
}
}
ringTurn(matrix, turned, 0, delta);
ringTurn(matrix, turned, 1, -delta);
ShowMatrix(matrix);
ShowMatrix(turned);
System.out.println("Ciao!");
}
// helper class represents a row/col pair
static class RowCol {
int row;
int col;
int left;
int top;
int right;
int bottom;
RowCol(int ring, int rows, int cols) {
row = ring;
col = ring;
left = ring;
top = ring;
right = ring + cols - 1;
bottom = ring + rows - 1;
}
// one step anti-clockwise along our ring
void Advance() {
switch(GetCase())
{
case LEFT: // left col
case TOP+LEFT: // top-left corner
row++; break;
case RIGHT: // right col
case BOTTOM+RIGHT: // bottom-right corner
row--; break;
case BOTTOM: // bottom row
case BOTTOM+LEFT: // bottom-left corner
col++; break;
case TOP: // top row
case TOP+RIGHT: // top-right corner
col--; break;
}
}
// cryptic but shorter version of Advance()
void Advance2() {
row += PlusMinus("+- - + ");
col += PlusMinus(" ++ - -");
}
// return -1 for "-", +1 for "+"
// at 1-based string position r
int PlusMinus(String s) {
int r = GetCase();
char c = s.charAt(r - 1);
return "- +".indexOf(c) - 1;
}
// one step back on our ring
void Retract() {
switch(GetCase())
{
case LEFT: // left col
case BOTTOM+LEFT: // bottom-left corner
row--; break;
case RIGHT: // right col
case TOP+RIGHT: // top-right corner
row++; break;
case BOTTOM: // bottom row
case BOTTOM+RIGHT: // bottom-right corner
col--; break;
case TOP: // top row
case TOP+LEFT: // top-left corner
col++; break;
}
}
// cryptic but shorter version of Retract()
void Retract2() {
row += PlusMinus("-+ - +");
col += PlusMinus(" - - ++ ");
}
private int b2x(boolean b, int x) {
return b ? x : 0;
}
static final int LEFT = (1 << 0);
static final int RIGHT = (1 << 1);
static final int BOTTOM = (1 << 2);
static final int TOP = (1 << 3);
// determine where we are on the ring
int GetCase() {
int r = b2x(col == left, LEFT)
+ b2x(col == right, RIGHT)
+ b2x(row == bottom, BOTTOM)
+ b2x(row == top, TOP);
// we have to stay on our ring
assert r != 0;
return r;
}
} // end of class RowCol
// copy all cells in ring from src to dest
// apply delta offset (> 0 if anti-clockwise)
static void ringTurn(int[][] src, int[][] dest, int ring, int delta) {
int cols = src[0].length - 2 * ring;
int rows = src.length - 2 * ring;
// in-place turns are forbidden
assert dest != src;
// matrices have to match in their size
assert dest[0].length == src[0].length;
assert dest.length == src.length;
if ((rows > 1) && (cols > 1)) {
RowCol srcRC = new RowCol(ring, rows, cols);
RowCol destRC = new RowCol(ring, rows, cols);
// position the destination location
for (int i = 0; i < Math.abs(delta); i++) {
if (delta > 0) {
destRC.Advance2();
} else {
destRC.Retract2();
}
}
// perform the copy operation
// by moving both locations along the ring
int steps = 2 * (rows + cols - 2);
for (int step = 0; step < steps; step++) {
dest[destRC.row][destRC.col] = src[srcRC.row][srcRC.col];
destRC.Advance2();
srcRC.Advance2();
}
}
}
static void ShowMatrix(int[][] matrix) {
int cols = matrix[0].length;
System.out.println();
for (int[] ints : matrix) {
StringBuilder s = new StringBuilder();
for (int col = 0; col < cols; col++) {
s.append(String.format("%3d", ints[col]));
}
System.out.println(s);
}
}
}
Output:
1 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
2 3 4 5 6 12
1 14 8 9 10 18
7 20 15 16 11 24
13 21 22 23 17 30
19 25 26 27 28 29
Related
I am learning c and encountered maximum cost path question in which
Rules:
matrix is n x n size
Starting from the cell (bottommost leftmost cell), you want to go to the topmost
rightmost cell in a sequence of steps. In each step, you can go either right or up from
your current location.
I tried to solve using dynamic programming and this is the function I have written
computecost(int *utr,int n)//utr is the input matrix
{
int *str;
int i,j;
str=(int *)malloc(n*n*sizeof(int));
for(j=0;j<n;j++)//intialization of bottom row
{
str[n*(n-1)+j]=utr[n*(n-1)+j];
}
for(i=n-2;i>=0;i--)
{
for(j=0;j<n;j++)
{
str[n*i+j]=utr[n*i+j]+max(str[n*(i+1)+j],str[n*(i+1)+(j+1)]);
}
}
printf("%d",str[n*0+0]);
return 0;
}
and this is the input
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf("%d",&str[n*i+j]);
}
}
but
for the matrix 5 x5
1 4 8 2 9
32 67 18 42 1
4 86 12 7 1
8 4 12 17 44
1 43 11 45 2
the desired output is 272 but I am getting 211.
the output matrix for my case
1 43 11 45 2
51 47 57 62 46
55 143 74 69 47
175 210 92 111 52
211 214 119 113 64
Can anyone help me?
You don't need dynamic programming for this since there are no overlapping sub-problems. Just use a simple recursion.
const int n = 5;
int mat[n][n] = {
{1,4,8,2,9},
{32,67,18,42,1},
{4,86,12,7,1},
{8,4,12,17,44},
{1,43,11,45,2}
}; // input matrix
int f(int x, int y, int sum){
if(x == 0 && y == 4)
return sum;
int p = 0, q = 0;
if(x - 1 >= 0)
p = f(x-1, y, sum + mat[x-1][y]);
if(y + 1 <= 4)
q = f(x, y+1, sum+mat[x][y+1]);
return max(p,q);
}
int main(){
int maxSum = f(4,0, mat[4][0]);
printf("%d\n", maxSum);
}
You were not very far to succeed.
In practice, you did not initialize correctly the bottom row.
Moreover, there was a little mistake in the iteration calculation.
This is the corrected code.
As said in a comment, it could be further simplified, by avoiding the use of a new array, simply updating the input array.
#include <stdio.h>
#include <stdlib.h>
int max (int a, int b) {
return (a > b) ? a : b;
}
int computecost(int *utr,int n) { //utr is the input matrix
int *str;
str = malloc (n*n*sizeof(int));
str[n*n - 1] = utr[n*n - 1];
for (int j = n-2; j >= 0; j--) { //intialization of bottom row {
str[n*(n-1)+j] = utr[n*(n-1)+j] + str[n*(n-1)+j+1]; // corrected
}
for (int i=n-2; i>=0; i--) {
str[n*i+n-1] = utr[n*i+n-1] + str[n*(i+1)+n-1];
for(int j = n-2; j >= 0; j--) {
str[n*i+j] = utr[n*i+j] + max(str[n*(i+1)+j],str[n*i + j+1]); // corrected
}
}
int cost = str[0];
free (str);
return cost;
}
int main() {
int A[25] = {
1,43,11,45,2,
8,4,12,17,44,
4,86,12,7,1,
32,67,18,42,1,
1,4,8,2,9
};
int ans = computecost (A, 5);
printf ("%d\n", ans);
return 0;
}
I want to create a spiral matrix consisted of numbers. Number 1 should be in the last row at the right side and other numbers should just follow the spiral path. The output of my code is different from the wanted result, and it also doesn't separate rows. I hope that you could help me solve these problems.
\\ Expected result: Output of my code: 1 2 3 4 5 10 15 20 25 24 23 22 21
16 11 6 7 8 9 14 19 18 17 12 13
9 10 11 12 13
8 21 22 23 14
7 20 25 24 15
6 19 18 17 16
5 4 3 2 1
#include <stdio.h>
void spiral(int n,int m,int arr[][m])
{
int top = 0,
right = m - 1,
bottom = n - 1,
left = 0,
k;
while( top <= bottom && left <= right )
{
//print top row
for ( k = left; k <= right; k++ )
{
printf("%d ",arr[top][k]);
}
++top;
//print right column
for( k = top; k <= bottom; k++ )
{
printf("%d ",arr[k][right]);
}
--right;
//print bottom row
for( k = right; k >= left; k-- )
{
printf("%d ",arr[bottom][k]);
}
--bottom;
//print left column
for( k = bottom; k >= top; k-- )
{
printf("%d ",arr[k][left]);
}
++left;
}
}
int main(void) {
int rows = 5, cols = 5;
int board[rows][cols];
printf("\nSpiral printing:\n");
spiral(rows,cols,board);
return 0;
}
I'm just not able to see where's the error on my code, I am getting 26249 (or 26247 if I go back one spiral level), but it should be 26241.
Obviously, there must be a problem with my logic, but I can't point out where.
Spiral Primes, Project Euler Problem 58
Starting with 1 and spiralling anticlockwise in the following way, a square spiral with side length 7 is formed.
37 36 35 34 33 32 31
38 17 16 15 14 13 30
39 18 05 04 03 12 29
40 19 06 01 02 11 28
41 20 07 08 09 10 27
42 21 22 23 24 25 2643 44 45 46 47 48 49
It is interesting to note that the odd squares lie along the bottom right diagonal, but what is more interesting is that 8 out of the 13 numbers lying along both diagonals are prime; that is, a ratio of 8/13 ≈ 62%.
If one complete new layer is wrapped around the spiral above, a square spiral with side length 9 will be formed. If this process is continued, what is the side length of the square spiral for which the ratio of primes along both diagonals first falls below 10%?
#include <stdio.h>
#define print(ref) printf(#ref" = %d\n",ref);
#define printl(ref) printf(#ref" = %ld\n",ref);
#define NUM_OF_PRIMES 5000
int primesOnThisLevel(int);
void generatePrimes();
int isPrime(int);
int canBeExpressedAsPrime(int);
int primes[NUM_OF_PRIMES] = {2,3,5};
int primesFound = 3;
int main(){
int numbersInDiagonal = 1;
int primesInDiagonal = 0;
int level;
generatePrimes();
for (level = 2 ; numbersInDiagonal/10 <= primesInDiagonal ; level++){
primesInDiagonal += primesOnThisLevel(level);
numbersInDiagonal += 4;
}
print(numbersInDiagonal)
print(primesInDiagonal)
int sideLenght = (2*level)-1;
print(sideLenght*sideLenght);
print(sideLenght);
return 0;
}
int primesOnThisLevel(int level){
int primesCount = 0;
int sideLenght = (2*level)-1;
int differenceBetweenCorners = 2*(level-1);
int cornerValue = sideLenght*sideLenght;
for (int i = 0 ; i < 3 ; i++){
cornerValue -= differenceBetweenCorners;
primesCount += isPrime(cornerValue);
}
return primesCount;
}
void generatePrimes(){
for (int i = 7 ; primesFound < NUM_OF_PRIMES ; i +=2 ){
if ( isPrime(i) ){
primes[primesFound++] = i;
}
}
print(primes[primesFound-1]);
}
int isPrime(int prospect){
if ( prospect == 3 || prospect == 5 ) return 1;
if ( !canBeExpressedAsPrime(prospect) ) return 0;
for (int i = 0 ; primes[i]*primes[i] <= prospect ; i++)
if ( prospect%primes[i] == 0 ) return 0;
return 1;
}
int canBeExpressedAsPrime(int prospect){
if ( prospect%6 == 1 ) return 1;
if ( prospect%6 == 5 ) return 1;
return 0;
}
Special Thanks to Roberto Trani whom pointed out the error which was regarding boundaries, the previous limit included 10% which was not supposed to happen, here it is the ammended main function, which is the perfect situation to use a do-while loop.
int main(){
int numbersInDiagonal = 1;
int primesInDiagonal = 0;
int level = 2;
generatePrimes();
do {
primesInDiagonal += primesOnThisLevel(level);
numbersInDiagonal += 4;
level++;
} while ( numbersInDiagonal < primesInDiagonal*10 );
int sideLenght = (2*(--level))-1;
print(sideLenght);
return 0;
}
I'm developing a system that can explore entirely a simple heuristic map of this gender (which can have different numbers of branches, and different depths) :
Simple heuristic map
So, I'm saving the positions explored in an int array of the size of the depth of the map. The goal is to explore all nodes of the map, so to have this output : 0 2 6, 0 2 7, 0 3 8, 0 3 9, 1 4 10 etc.. But actually with my code (which needs to be called several times because it can update just one time the array), i have this : 0 2 6, 0 2 7, 0 3 8, **1** 3 9, 1 4 10 etc..
This is my code, I don't know how to solve this problem..
void get_next_branch(int *s, int nbr_branch, int size)
{
int a;
a = 0;
while (a < size)
{
condition = (size - a)/(nbr_branch - 1);
if (condition)
{
if (s[size - 1] % (condition) + 1 == condition)
s[a]++;
}
a++;
}
}
And this is the main example who call this function.
int main(void)
{
int id[3] = {0, 2, 6};
while (id[2] < 13)
{
printf("%d %d %d\n", id[0], id[1], id[2]);
get_next_branch(id, 2, 3);
}
return (0);
}
I thank you in advance!
You might want to use a closed formula for this problem
b being the number of branches
d the depth you want to find the numbers in (d >= 0)
we get immediately
Number of nodes at depth d = bd+1
(since at depth 0 we have already two nodes, there is no "root" node used).
The number of the first node at depth d is the sum of the number of nodes of the lower levels. Basically,
first node number at depth 0 = 0
first node number at depth d > 0 = b1 + b2 + b3 + ... + bd
This is the sum of a geometric series having a ratio of b. Thanks to the formula (Wolfram)
first node number at depth d = b * (1 - bd) / (1 - b)
E.g. with b == 2 and d == 2 (3rd level)
Number of nodes: 2 ^ 3 = 8
Starting at number: 2 * (1 - 2^2) / (1 - 2) = 6
A program to show the tree at any level can be done from the formulas above.
To print a number of levels of a tree with b branches:
Utility power function
int power(int n, int e) {
if (e < 1) return 1;
int p=n;
while (--e) p *= n;
return p;
}
The two formulas above
int nodes_at_depth(int branches, int depth) {
return power(branches, depth+1);
}
int first_at_depth(int branches, int depth) {
return (branches * (1 - power(branches, depth))) / (1 - branches);
}
Sample main program, to be called
./heuristic nb_of_branches nb_of_levels
that calls the two functions
int main(int argc, char **argv)
{
if (argc != 3) return 1;
int b = atoi(*++argv);
int d = atoi(*++argv);
if (b < 2) return 2;
int i,j;
for (i=0 ; i<d ; i++) {
int n = nodes_at_depth(b, i); // number of nodes at level i
int s = first_at_depth(b, i); // first number at that level
for (j=0 ; j<n ; j++) printf(" %d", s+j);
printf("\n");
}
return 0;
}
Calling
./heuristic 2 4
gives
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 25 26 27 28 29
I have c program problem to print the ring type output.
When user enter the number 5, then program output is look like;
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
I use following logic but i really failed i not have any idea.
int main()
{
int a[50],i,j=0,n,k;
printf("Enter the number=");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
if(i>n)
{
j=j+5;
}
else if(i>((2*n)-1))
{
j--;
}
else if(i>((3*n)-2))
{
j=j-5;
}
else if(i>(4*n-4))
{
j++;
}
}
}
Sorry for asking whole program logic but
,I really dont have any idea,Please help me.....
here's what you are looking for
#include <stdio.h>
#define max 25
int main()
{
int spiral[max][max] = {{0}}; // initializing array with 0
int r, c, i = 0, j = -1, count = 1;
printf("\nEnter the row and column for spiral matrix:\n");
scanf("%d%d", &r, &c);
while (count <= r * c) // this loop executes till all the blocks of
{
// array r*c are filled with 0
while (j < c - 1) // Filling the location from left to right
{
// with value of variable count
if(spiral[i][j+1]!=0) // Here we are checking if that location
break; // is already occupied
spiral[i][++j] = count++;
}
while (i < r - 1) // Filling the location from top to bottom
{
if (spiral[i+1][j] != 0)
break;
spiral[++i][j] = count++;
}
while (j > 0) // Filling the location from right to left
{
if(spiral[i][j-1] != 0)
break;
spiral[i][--j] = count++;
}
while (i > 0) // Filling the column from bottom to top
{
if (spiral[i-1][j] != 0)
break;
spiral[--i][j] = count++;
}
}
for (i = 0 ; i < r ; i++)
{
for (j = 0 ; j < c ; j++)
{
printf("%3d",spiral[i][j]); // print the matrix
}
printf("\n");
}
return 0;
}
reference is here from more details
A simple way to solve this problem is to allocate an array of size N*N and to populate it with a straight forward loop that follows the spiral. Then you can print the array contents N elements per row.