Accessing out of bounds cells in a 2D array - c

I can't really see what's wrong with my check neighbors function in my game of life. It checks all the 8 neighbours then depending on the living count assigns the cell being checked to living or dead, then updates the board.
void check_neighbours (int board[][COL])
{
int living = 0, i, j, k, l;
int new_board[ROW][COL];
for (i = 0; i < ROW; i++)
{
for (j = 0; j < COL; j++)
{
if ((board[i + 1 % ROW][j % COL]) == '#')
{
living++;
}
if ((board[i - 1 % ROW ][j % COL]) == '#')
{
living++;
}
if ((board[i % ROW][j + 1 % COL]) == '#')
{
living++;
}
if ((board[i % ROW][j - 1 % COL]) == '#')
{
living++;
}
if ((board[i + 1 % ROW][j + 1 % COL]) == '#')
{
living++;
}
if ((board[i - 1 % ROW ][j + 1 % COL ]) == '#')
{
living++;
}
if ((board[i + 1 % ROW ][j - 1 % COL ]) == '#')
{
living++;
}
if ((board[i - 1 % ROW ][j - 1 % COL ]) == '#')
{
living++;
}
if (living == 3)
{
new_board[i][j] = '#';
}
if (living <= 2)
{
new_board[i][j] = '-';
if (living < 3)
{
new_board[i][j] = '-';
}
}
}
for (k = 0; k < ROW; k++)
{
for (l = 0; l < COL; l++)
{
board[k][l] = new_board[k][l];
}
}
}
}
edit: Added parentheses but still prints the same

Try sticking some brackets into your math:
board[(i + 1) % ROW]
is much safer than
board[i + 1 % ROW]

Test edge conditions before doing the living count.
for (i = 0; i < ROW; i++) {
for (j = 0; j < COL; j++) {
int living = 0;
for (int drow = -1; drow <= 1; drow++) {
int row = i+drow;
if (row < 0 || row >= ROW) continue; // over the edge
for (int dcol = -1; dcol <= 1; dcol++) {
int col = j+dcol;
if (col < 0 || col >= COL) continue; // over the edge
if (row==0 && col==0) continue;
if (board[row][col] == '#') {
living++;
}
} // endfor dcol
} // endfor drow
// This section may need review - GOL rules are unclear in post -see below
if (living == 3) {
new_board[i][j] = '#';
}
...
} // endfor j
} // endfor i
If rules follow:
Any live cell with fewer than two live neighbors dies, as if caused by under-population.
Any live cell with two or three live neighbors lives on to the next generation.
Any live cell with more than three live neighbors dies, as if by over-population.
Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction.
#define ALIVE ('#')
#define DEAD ('-')
#define POP_MIN 2
#define POP_MAX 3
#define POP_REPRO 3
new_board[i][j] = board[i][j];
if (board[i][j] == ALIVE) {
if (living < POP_MIN) new_board[i][j] = DEAD;
else if (living > POP_MAX) new_board[i][j] = DEAD;
} else {
if (living == POP_REPRO) new_board[i][j] = ALIVE;
}

Isn't this:
board[i + 1 % ROW]
going out of bounds? Try fixing these issues.
As Paul R suggested, you could use parentheses, in order to catch up with the higher precedence of % operator in comparison to the + operator. So change the code to this:
board[(i + 1) % ROW]
Assuming ROW = 5 and i = 4, you get:
(4 + 1) % 5 = 0 // yeah!
4 + 1 % 5 = 5 // oh dear...

Related

confused about dynamic programming state

I was trying to solve the problem where if I was given an array of int which allows duplicate,
I need to find the count of how many permutation of this array there are such that each adjacent pair of integer in the array whose sum is a perfect square. I have derived the dp solution, but it was wrong, I looked at the solution, it was very similar to mine but with slight difference, can someone please look at it and tell me why mines won't work but the sample answer does?
My train of thought is, if I have g[i][j] == 1 telling me i and j forms a pair whose sum is a perfect square, 0 otherwise. And I have a dp[s][j] tells me if my node visited state is s, whose binary representation tells me all the node index that I have visited, and it ends in node with index j, I need DP for hamitonian path in a graph to calculate all possible ways to reach state s that ends in node index j, then the answer will be the sum of state s where all node is visited and it ends in node from 0 to n - 1. In terms of avoiding duplicate, I sort the input array of number and if in same layer of search, if we have nums[i - 1] == nums[i] but we have not visited nums[i], it means we just back out from an earlier dfs that visited the same number, we will not do that again.
I will paste the code here
The below is my answer, which will fail if the array contains duplicate
int n = nums.length;
int[][] dp = new int[1 << n][n];
int[][] g = new int[n][n];
Arrays.sort(nums);
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if(i != j && (Math.ceil(Math.sqrt(nums[i] + nums[j])) ==
Math.sqrt(nums[i] + nums[j]))) {
g[i][j] = 1;
}
}
}
for(int s = 0; s < (1 << n); s++) {
for(int j = 0; j < n; j++) {
if(s == (1 << j)) {
dp[1 << j][j] = (j == 0 || nums[j - 1] != nums[j]) ? 1 : 0;
continue;
}
if((s & (1 << j)) == 0) continue;
for(int i = 0; i < n; i++) {
if(g[i][j] == 0) continue;
if((s & (1 << i)) == 0) continue;
if(i > 0 && nums[i - 1] == nums[i] && ((s & (1 << (i - 1))) == 0)) continue;
dp[s][j] += dp[s & ~(1 << j)][i];
}
}
}
int res = 0;
int finish = (1 << n) - 1;
for(int i = 0; i < n; i++) {
res += dp[finish][i];
}
return res;
The below is the sample answer:
int n = nums.length;
boolean[][] g = new boolean[n][n];
int[][] dp = new int[1 << n][n];
Arrays.sort(nums);
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if(Math.floor(Math.sqrt(nums[i] + nums[j])) * Math.floor(Math.sqrt(nums[i] + nums[j])) == nums[i] + nums[j]) {
g[i][j] = g[j][i] = true;
}
}
}
for(int i = 0; i < nums.length; i++) {
if(i == 0 || (i > 0 && nums[i - 1] != nums[i]))
dp[1 << i][i] = 1;
}
for(int s = 0; s < (1 << n); s++) {
for(int j = 0; j < n; j++) {
if((s & (1 << j)) == 0) continue;
for(int i = 0; i < n; i++) {
if(g[i][j]) {
if((s & (1 << i)) != 0) continue;
if(i > 0 && nums[i] == nums[i - 1] && ((s & (1 << (i - 1))) == 0)) continue;
dp[s | (1 << i)][i] += dp[s][j];
}
}
}
}
int ans = 0;
for(int l = 0; l < n; l++) {
ans += dp[(1 << n) - 1][l];
}
return ans;

program to add one to each digit of a number

As new to competitive programming, I was solving this practice question. The goal is to write a program to display numbers whose digits are 1 greater than the corresponding digits of the entered number. So if the number input is 12345 then the output number should be 23456. I have figured out how to separate each number and add them, but I was unable able to take a number of test cases in the following program.
The question is as follows
Input
First line of input will contain a number N = number of test cases. Next N lines will contain number n as test case where 1<=n<=99999.
Output
For each input case, add one to each digit of n, and print the new number.
As a beginner in competitive programming would be helpful if you give some tips to optimize the code.
here is the code that I have written.
#include<stdio.h>
void main()
{
int n, t, sum = 0;
scanf("%d", &t);
int a[t];
for (int j = 0; j < t; j++)
{
for (int i = 0; i < t; i++)
{
scanf("%d", &n);
a[i] = n;
if (t == 1) {
if (i == 0) {
a[i] = (a[i] + 1) * 1;
}
}
else if (t == 2) {
if (i == 0) {
a[i] = (a[i] + 1) * 10;
}
else if (i == 1) {
a[i] = (a[i] + 1) * 1;
}
}
else if (t == 3) {
if (i == 0) {
a[i] = (a[i] + 1) * 100;
}
else if (i == 1) {
a[i] = (a[i] + 1) * 10;
}
else if (i == 2) {
a[i] = (a[i] + 1) * 1;
}
}
else if (t == 4) {
if (i == 0) {
a[i] = (a[i] + 1) * 1000;
}
else if (i == 1) {
a[i] = (a[i] + 1) * 100;
}
else if (i == 2) {
a[i] = (a[i] + 1) * 10;
}
else if (i == 3) {
a[i] = (a[i] + 1) * 1;
}
}
else if (t == 5) {
if (i == 0) {
a[i] = (a[i] + 1) * 10000;
}
else if (i == 1) {
a[i] = (a[i] + 1) * 1000;
}
else if (i == 2) {
a[i] = (a[i] + 1) * 100;
}
else if (i == 3) {
a[i] = (a[i] + 1) * 10;
}
else if (i == 4) {
a[i] = (a[i] + 1) * 1;
}
}
else if (t == 6) {
if (i == 0) {
a[i] = (a[i] + 1) * 100000;
}
else if (i == 1) {
a[i] = (a[i] + 1) * 10000;
}
else if (i == 2) {
a[i] = (a[i] + 1) * 1000;
}
else if (i == 3) {
a[i] = (a[i] + 1) * 100;
}
else if (i == 4) {
a[i] = (a[i] + 1) * 10;
}
else if (i == 4) {
a[i] = (a[i] + 1) * 1;
}
}
}
}
for (int i = 0; i < t; i++)
{
sum = sum + a[i];
}
printf("%d\n", sum);
}
I've reworked on the code from beginning and I've made a solution for you:
#include <stdio.h>
int main(void)
{
int num, sum, remainder, check; // check used as a boolean expression
sum = check = 0;
printf("Enter the sequence: ");
scanf("%d", &num);
while (num > 0)
{
remainder = num % 10; // each time num is reduced
if (remainder != 9)
{
if (check == 0)
sum = (10 * sum) + (remainder + 1);
else
{
sum = (10 * sum) + (remainder + 2);
check = 0;
}
}
else
{
sum = (10 * sum) + 0;
check = 1;
}
num /= 10; // will divide and execute in each iteration until it's true
}
num = sum; // final number will be equal to the sum
sum = 0;
// Summing up the results
while (num > 0)
{
remainder = num % 10;
sum = (10 * sum) + remainder;
num /= 10;
}
printf("Result: %d\n", sum);
return 0;
}
Test Output
Enter the sequence: 23456
Result: 34567
It's just all about the sum & remainder. Hope it helps you understand better.
import java.util.Scanner;
class Main
{
public static void main(String[] args)
{
int num,i=1,j;
Scanner scan=new Scanner(System.in);
int numo=scan.nextInt();num=numo;
for(;numo>0;numo=numo/10,i=i*10)
{
num=num+i;
if(numo%10==9)
num=num-i*10;
}
System.out.println(num);
}
}
The below solution uses the basic remainder and reverse approach:
int addOne(int n)
{
int rem, ans=0, p=1 ;
while(n>0)
{
rem = n%10;
(rem == 9)?rem = 0:rem+=1;
ans+=p*rem;
p*=10;n/=10;
}
return ans;
}
int main() {
int n;
cin>>n;
cout<<addOne(n);
return 0;
}

give the location of matrix cell with 0 around

i need to input 6 on 6 matrix and to out put the location of the
cell that all the cells around him has the value 0.
let's say:
1 1 1 1 1 1
1 1 1 1 1 1
0 0 1 1 1 1
2 0 1 1 1 1
0 0 1 1 1 1
1 1 1 1 1 1
the out put will be row 3 col 0
this is the code i made.. how i solve this ?
i tried a lot please help me
#include<stdio.h>
#define N 6
int main()
{
int arr[N][N] = { 0 }, i = 0, j = 0, x = 0, y = 0, counter = 0;
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)//input//
{
scanf("%5d", &arr[i][j]);
}
printf("\n");
}
for (i = 0; i < N; i++)//output//
{
for (j = 0; j < N; j++)
{
printf("%5d", arr[i][j]);
}
printf("\n");
}
for (i = 0; i < N; j++)
{
for (j = 0; j < N; j++)
{
for (x = i - 1; x <= i + 1; x + 2)
{
for (y = j - 1; y <= j + 1; y + 2)
{
if (x >= 0 && x < N &&y >= 0 && y < N&&arr[x][y] == 0)
{
counter++;
}
}
}
if (i == 0 && j == 0 || i == 0 && j == N - 1 || i == N - 1 && j == 0
|| i == N - 1 && j == N - 1)
{
if (counter == 3)
{
printf("the row is %d the col is %d\n", i, j);
}
}
else if (i == 0 && j >= 1 && j < N - 1 || i == N - 1 && j >= 1 && j
< N - 1 && j == 0 && i >= 1 && i <= N - 1 && j == N - 1 && i >= 1 && i<N -1)
{
if (counter == 5)
{
printf("the row is %d the col is %d\n ", i, j);
}
}
else
{
if (counter == 8)
{
printf("the row is %d the col is %d\n ", i, j);
}
}
}
}
}
There are problems with your x and y loops:
for (x = i - 1; x <= i + 1; x + 2)
{
for (y = j - 1; y <= j + 1; y + 2)
{
You aren't incrementing x or y in these loops. The expression x + 2 merely evaluates the value x + 2. It doesn't do anything with it. If you want to actually set x to x + 2, then you need to use x = x + 2, or more concisely, x += 2.
Incrementing x and y by 2 is incorrect. It will only examine 4 points: (i-1,i-1), (i-1,i+1), (i+1,i-1), and (i+1,i+1). It will skip the following 4 points: (i-1,i), (i,i-1), (i,i+1), (i+1,i). You need to increment x and y by 1 each time, i.e. use x++ and y++ in the loop incremement instead of adding 2. The, inside the loop, add an additional test for x == i && y == i and skip that point (the center point).
I believe this is what you want (note that you can do eveything in two loops if you nest the conditionals in a smart way to avoid checking areas outside the matrix):
#include <stdio.h>
#define ROWS 5
#define COLS 5
void printBlockeds(int M[ROWS][COLS])
{
int i, j;
for(i = 0; i < ROWS; ++i)
{
for(j = 0; j < COLS; ++j)
{
int isBlocked = 1;
if(i > 0)
{
isBlocked = isBlocked && !M[i-1][j];
if(j > 0) isBlocked = isBlocked && !M[i-1][j-1];
if(j < COLS-1) isBlocked = isBlocked && !M[i-1][j+1];
}
if(j > 0) isBlocked = isBlocked && !M[i][j-1];
if(j < COLS-1) isBlocked = isBlocked && !M[i][j+1];
if(i < ROWS-1)
{
isBlocked = isBlocked && !M[i+1][j];
if(j > 0) isBlocked = isBlocked && !M[i+1][j-1];
if(j < COLS-1) isBlocked = isBlocked && !M[i+1][j+1];
}
if(isBlocked) printf("(%d, %d)\n", i, j);
}
}
}
int main()
{
int M[ROWS][COLS] = {{1, 1, 1, 0, 1},
{1, 0, 0, 0, 0},
{1, 0, 1, 0, 1},
{1, 0, 0, 0, 1},
{1, 0, 1, 0, 1}};
printBlockeds(M);
return 0;
}
Output for the case above:
(0, 4)
(2, 2)
(4, 2)

How can I implement the knapsack algorithm where the index of the array represent the weight of the item

I am trying to implement an algorithm to solve the Knapsack problem:
cst = 1;
for (j = 0; j < 200; j++) {
if (kk - cst < 0) {
continue;
cst++;
}
for (i = kk - cst; i >= 0; --i) {
C[i + cst] = max(C[i + cst], C[i] + index[cst]);
}
cst++;
}
The index array has the values of respective items represented by index of the array. I want to know where I'm going wrong.
In your code
if(kk-cst < 0)
{
continue;
cst++;
}
is wrong. the cst++ will never be executed. Please check and change your logic accordingly.
The increment to cst is unreachable code here. Swap the two lines
if (kk - cst < 0) {
cst++;
continue;
}
A simple dynamic programming knapsack implementation would be
int KnapSack(int W, int wt[], int val[], int n) {
int i, w;
int K[n + 1][W + 1];
for (i = 0; i <= n; i++) {
for (w = 0; w <= W; w++) {
if (i == 0 || w == 0) K[i][w] = 0;
else if (wt[i - 1] <= w)
K[i][w] = max(val[i - 1] + K[i - 1][w - wt[i - 1]], K[i - 1][w]);
else K[i][w] = K[i - 1][w];
}
}
return K[n][W];
}
as listed in http://www.geeksforgeeks.org/dynamic-programming-set-10-0-1-knapsack-problem/

Minesweeper revealing cells in C

I am trying to write a minesweeper program in C.
What I am trying to achieve here is when user steps on one cell, the cells near without bombs and hint numbers will be revealed.
For example, if x is the cell stepped on, o is an empty but concealed square, . is an empty but revealed cell and * is the bomb (hidden when playing of course):
x o o o o
o o o * o
o o o o o
will result in:
. . 1 o o
. . 1 * o
. . 1 o o
Here is part of the code:
while (1)
{
printf("Row? ");
scanf("%d", &row);
printf("column? ");
scanf("%d", &clos);
if (row < 9 && row >= 0 && clos < 8 && clos >= 0)
break;
printf("\nInvalid Location\n\n");
}
if (real_map[row][clos] =='*')
{
print_map_win(display_map,real_map);
printf("\n");
printf("Flags Left = %d\n\n\n", flag_left);
printf("Game Over\n");
exit(0);
}
else
{
if (real_map[row][clos] == ' ')
{
display_map[row][clos] = real_map[row][clos];
bonos_reveal(display_map, real_map, clos, row);
// [[[bonos_reveal is the function I am asking for]]]
printf("\n");
}
else
{
display_map[row][clos] = real_map[row][clos];
}
}
in which real_map has the hint number and bombs in it, and display_map is the current state of the map.
edit: I have the following code, and it only reveals in one direction:
int bonos_reveal(int disp_map[MAP_ROWS][MAP_COLS], int real_map[MAP_ROWS][MAP_COLS], int clos, int row)
{
disp_map[row][clos] = real_map[row][clos];
if (row < 9 && row >= 0 && clos < 8 && clos >= 0)
{
if (real_map[row][clos+1] == ' ')
{
bonos_reveal(disp_map, real_map, clos + 1, row);
}
else
{
disp_map[row][clos+1] = real_map[row][clos+1];
return 1;
}
}
else
{
return 1;
}
return 1;
}
I have no idea how to loop through the cells.
Okay, here's an example implementation. It uses the following values for tiles:
0 to 8: an unmined tile; the number represents the pre-calculated number of adjacent mines
9: a mine; this special value is defined as BOMB.
Covered tiles have 10 added to that, flagged tiles (not used here) have 20 added to that. You can test whether a tile is mined with:
board[row][col] % 10 == BOMB
I'll let the code do the explaining:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define ROWS 12
#define COLS 20
#define BOMBS 8
#define BOMB 9
void inc(int board[ROWS][COLS], int row, int col)
{
if (row < 0 || row >= ROWS) return;
if (col < 0 || col >= COLS) return;
if (board[row][col] % 10 == BOMB) return;
board[row][col]++;
}
/*
* Set up board and pre-calculate adjacent bombs
*/
void board_init(int board[ROWS][COLS])
{
int i, j, n;
for (j = 0; j < ROWS; j++) {
for (i = 0; i < COLS; i++) {
board[j][i] = 10;
}
}
n = 0;
while (n < BOMBS) {
j = rand() % ROWS;
i = rand() % COLS;
if (board[j][i] % 10 != BOMB) {
board[j][i] = 19;
inc(board, j - 1, i - 1);
inc(board, j - 1, i);
inc(board, j - 1, i + 1);
inc(board, j, i - 1);
inc(board, j, i + 1);
inc(board, j + 1, i - 1);
inc(board, j + 1, i);
inc(board, j + 1, i + 1);
n++;
}
}
}
/*
* Reveal tile and propagate revelation
*/
void board_reveal(int board[ROWS][COLS], int row, int col)
{
if (row < 0 || row >= ROWS) return; /* skip off-board tiles */
if (col < 0 || col >= COLS) return;
if (board[row][col] < 10) return; /* already revealed, skip */
if (board[row][col] >= 20) return; /* must remove flag first, skip */
if (board[row][col] % 10 == BOMB) {
int i, j;
printf("Bang!\n");
for (j = 0; j < ROWS; j++) {
for (i = 0; i < COLS; i++) {
if (board[j][i] % 10 == BOMB) board[j][i] = BOMB;
}
}
} else {
board[row][col] %= 10;
if (board[row][col] == 0) {
board_reveal(board, row - 1, col);
board_reveal(board, row, col - 1);
board_reveal(board, row, col + 1);
board_reveal(board, row + 1, col);
}
}
}
void board_print(int board[ROWS][COLS])
{
int i, j;
for (j = 0; j < ROWS; j++) {
putchar(' ');
for (i = 0; i < COLS; i++) {
const char *tile = ".12345678*##########PPPPPPPPPP";
int k = board[j][i];
putchar(tile[k]);
}
putchar('\n');
}
}
int main()
{
int board[ROWS][COLS];
srand(time(NULL));
board_init(board);
board_reveal(board, 0, 0);
board_print(board);
return 0;
}

Resources