Cant get a Diamond Shape in C right - c

I'm doing a c exercise to do a diamond shape with '#' using a funcion.
My code :
#include <stdio.h>
//Declare function
void losangle(int n);
//main
int main(void){
int n;
do {
printf("Altura do triangulo: ");
scanf("%d", &n );
} while( n % 2 == 0);
losangle(n);}
//function
void losangle(int n){
int i, hashtag, spaces, j, spaces1, hashtag1;
//triangle
for(i = 0; i < n; i++){
for(spaces = 0; spaces < (n-i); spaces++){
printf(" ");}
for(hashtag = 0; hashtag < (i+1);hashtag++){
printf("# ");}
printf("\n");}
//inverted triangle
for(j = 0; j < (n - 1); j++){
for(spaces1 = 0; spaces1 < (j+2); spaces1++){
printf(" ");}
//not working !!!
for(hashtag1 = (n-1); hashtag1 > 0; hashtag1--){
printf("# ");}
printf("\n");
}}
The output is this :
Losangle: 5
#
# #
# # #
# # # #
# # # # #
# # # #
# # # #
# # # #
# # # #
What is making the '#' not decrementing in the bottom part ? Is this line wrong (for(hashtag1 = (n-1); hashtag1 > 0; hashtag1--)) ?? Btw i also accept tips to improve the code efficiency.

Issue:
The inverted triangle for loop iterates from n-1 to 0 every time, regardless of j's value.
Solution:
Iterating between n-1 to j will cause the number of hash symbols to decrease every iteration.
Change this line:
for(hashtag1 = (n-1); hashtag1 > 0; hashtag1--){
to
for(hashtag1 = (n-1); hashtag1 > j; hashtag1--){

Milestone 1
What's the high level logic of the program?
void getInutAndDrawDiamond()
int getTriangleHeight();
void drawDiamond(int height);
int main()
{
getInutAndDrawDiamond();
return 0;
}
void getInutAndDrawDiamond()
{
int height = getTriangleHeight();
drawDiamond(height);
}
with dummy implementations of getTriangleHeight and drawDiamond.
int getTriangleHeight()
{
return 0;
}
void drawDiamond(int height)
{
}
Milestone 2
Add a proper implementation of getTriangleHeight.
int getTriangleHeight()
{
int height;
int c;
char const* prompt = "Enter the height of the triangle: ";
printf("%s", prompt);
while ( scanf("%d", &height) != 1 )
{
// Error reading the input.
// Ignore rest of the line
while ( (c = fgetc(stdin)) != '\n' && c != EOF );
// If EOF is reached, exit.
if ( c == EOF )
{
exit(EXIT_FAILURE);
}
// Try reading again.
printf("%s", prompt);
}
return height;
}
Milestone 3
Add the next level implementation of drawDiamond, using couple of helper functions that have dummy implementations.
void drawUpperHalfOfDiamond(int height);
void drawLowerHalfOfDiamond(int height);
void drawDiamond(int height)
{
drawUpperHalfOfDiamond(height);
drawLowerHalfOfDiamond(height);
}
void drawUpperHalfOfDiamond(int height)
{
}
void drawLowerHalfOfDiamond(int height)
{
}
Milestone 4
Add the next level implementation of drawUpperHalfOfDiamond and drawLowerHalfOfDiamond, using dummy implementations of couple of helper functions.
void drawUpperHalfRowOfDiamond(int row);
void drawLowerHalfRowOfDiamond(int row);
void drawUpperHalfOfDiamond(int height)
{
for (int row = 0; row < height; ++row )
{
drawUpperHalfRowOfDiamond(row);
}
}
void drawLowerHalfOfDiamond(int height)
{
for (int row = 0; row < height; ++row )
{
drawLowerHalfRowOfDiamond(row);
}
}
void drawUpperHalfRowOfDiamond(int row)
{
}
void drawLowerHalfRowOfDiamond(int row);
{
}
Milestone 5
Add the next level implementation of drawUpperHalfRowOfDiamond and drawLowerHalfRowOfDiamond, using dummy implementations of a few helper functions.
int getNumberOfColumsForUpperHalfRow(int row);
void drawUpperHalfCell(int row, int col);
int getNumberOfColumsForLowerHalfRow(int row);
void drawLowerHalfCell(int row, int col);
void drawUpperHalfRowOfDiamond(int row)
{
int cols = getNumberOfColumsForUpperHalfRow(row);
for (int col = 0; col < cols; ++col )
{
drawUpperHalfCell(row, col);
}
}
void drawLowerHalfRowOfDiamond(int row)
{
int cols = getNumberOfColumsForLowerHalfRow(row);
for (int col = 0; col < cols; ++col )
{
drawLowerHalfCell(row, col);
}
}
int getNumberOfColumsForUpperHalfRow(int row)
{
return 0;
}
void drawUpperHalfCell(int row, int col)
{
}
int getNumberOfColumsForLowerHalfRow(int row)
{
return 0;
}
void drawLowerHalfCell(int row, int col)
{
}
Milestone 5
Add proper implementations of the last four functions -- left as an exercise to the reader.
Complete program
#include <stdio.h>
#include <stdlib.h>
void getInutAndDrawDiamond();
int getTriangleHeight();
void drawDiamond(int height);
void drawUpperHalfOfDiamond(int height);
void drawLowerHalfOfDiamond(int height);
void drawUpperHalfRowOfDiamond(int row);
void drawLowerHalfRowOfDiamond(int row);
int getNumberOfColumsForUpperHalfRow(int row);
void drawUpperHalfCell(int row, int col);
int getNumberOfColumsForLowerHalfRow(int row);
void drawLowerHalfCell(int row, int col);
int main()
{
getInutAndDrawDiamond();
return 0;
}
void getInutAndDrawDiamond()
{
int height = getTriangleHeight();
drawDiamond(height);
}
int getTriangleHeight()
{
int height;
int c;
char const* prompt = "Enter the height of the triangle: ";
printf("%s", prompt);
while ( scanf("%d", &height) != 1 )
{
// Error reading the input.
// Ignore rest of the line
while ( (c = fgetc(stdin)) != '\n' && c != EOF );
// If EOF is reached, exit.
if ( c == EOF )
{
exit(EXIT_FAILURE);
}
// Try reading again.
printf("%s", prompt);
}
return height;
}
void drawDiamond(int height)
{
drawUpperHalfOfDiamond(height);
drawLowerHalfOfDiamond(height);
}
void drawUpperHalfOfDiamond(int height)
{
for (int row = 0; row < height; ++row )
{
drawUpperHalfRowOfDiamond(row);
}
}
void drawLowerHalfOfDiamond(int height)
{
for (int row = 0; row < height; ++row )
{
drawLowerHalfRowOfDiamond(row);
}
}
void drawUpperHalfRowOfDiamond(int row)
{
int cols = getNumberOfColumsForUpperHalfRow(row);
for (int col = 0; col < cols; ++col )
{
drawUpperHalfCell(row, col);
}
}
void drawLowerHalfRowOfDiamond(int row)
{
int cols = getNumberOfColumsForLowerHalfRow(row);
for (int col = 0; col < cols; ++col )
{
drawLowerHalfCell(row, col);
}
}
int getNumberOfColumsForUpperHalfRow(int row)
{
// TODO a proper implementation
return 0;
}
void drawUpperHalfCell(int row, int col)
{
// TODO a proper implementation
}
int getNumberOfColumsForLowerHalfRow(int row)
{
// TODO a proper implementation
return 0;
}
void drawLowerHalfCell(int row, int col)
{
// TODO a proper implementation
}
Concluding Remarks
After implementing the last four functions properly, the program is very well structured to be able to diagnose problems easily by changing what gets called from main.

Some crazy complicated answers have been posted.
Here it is in one loop, one printf, and one variable (other than the Width input).
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int w = 9;
int l;
for(l=0; l < w; ++l)
{
printf("%*.*s\n",
abs(w/2 - l)+abs((2*l+1)-(2*l+1>w)*2*w),
abs((2*l+1)-(2*l+1>w)*2*w),
"# # # # # # # # # # # # # # # # # # ");
}
return 0;
}
Link to IDEOne Code

Related

Generating Sudoku Puzzle

I'm trying to write a piece of code which generates for me a valid sudoku puzzle.
My algorithm:
initiate all fields with 0
respect the rules and set 20 random values from 1-9 to random fields
solve the puzzle with the back tracking algorithm
My problems:
Sometimes it generates a valid sudoku puzzle in under 1 second.
Sometimes it can't generate a valid sudoku and I get an error, which is ok because I can go back to step 1 in my algorithm.
Sometimes it can't generate a valid sudoku and I get an error but it takes about 2-3Minutes, which is not ok.
How can I solve my problems?
Especially problem 3.
Can I just count the seconds and if it takes more than 5 seconds just go back to step 1 of my algorithm?
Or does anyone have a better idea?
thanks in advance.
this is my code:
#include <stdio.h>
#include <stdlib.h>
#define N 9
#define UNASSIGNED 0
typedef enum {false, true} bool;
typedef struct {
char number;
bool editable;
} GRID;
void print_sudoku(GRID **g){
char row=0, col=0;
for(row=0; row<N; row++){
for(col=0; col<N; col++){
printf("%d ", g[row][col].number);
}
printf("\n");
}
}
GRID ** create_sudoku_grid(){
char i, row, col;
GRID **g = (GRID **) malloc(N * sizeof(GRID *));
for (i=0; i<N; i++) {
g[i] = (GRID *) malloc(N * sizeof(GRID));
}
for(row=0; row<N; row++){
for(col=0; col<N; col++){
g[row][col].number = UNASSIGNED;
g[row][col].editable = true;
}
}
return g;
}
bool find_unassigned_field(GRID **g, int *row, int *col){
for (*row = 0; *row < N; (*row)++) {
for (*col = 0; *col < N; (*col)++) {
if (g[*row][*col].number == UNASSIGNED){
return true;
}
}
}
return false;
}
bool validate_row(GRID **g, int row, int num) {
for (int col = 0; col < N; col++) {
if (g[row][col].number == num) {
return false;
}
}
return true;
}
bool validate_col(GRID **g, int col, int num) {
for (int row = 0; row < N; row++) {
if (g[row][col].number == num) {
return false;
}
}
return true;
}
bool validate_box(GRID **g, int row, int col, int num) {
for (int r = 0; r < 3; r++) {
for (int c = 0; c < 3; c++) {
if (g[r+row][c+col].number == num) {
return false;
}
}
}
return true;
}
bool validate_field(GRID **g, int row, int col, int num){
bool valrow, valcol, valbox, valunassigned;
valrow = validate_row(g, row, num);
valcol = validate_col(g, col, num);
valbox = validate_box(g, row - row%3 , col - col%3, num);
valunassigned = g[row][col].number==UNASSIGNED;
return (valrow && valcol && valbox && valunassigned);
}
bool generate_sudoku(GRID **g) {
int row, col;
// If there is no unassigned location, we are done
if (!find_unassigned_field(g, &row, &col)) {
return true; // success!
}
// consider digits 1 to 9
for (int num = 1; num <= 9; num++) {
// if looks promising
if (validate_field(g, row, col, num)) {
// make tentative assignment
g[row][col].number = num;
// return, if success, yay!
if (generate_sudoku(g)) {
return true;
}
// failure, unmake & try again
g[row][col].number = UNASSIGNED;
}
}
return false; // this triggers backtracking
}
void random_init_grid(GRID **g){
int row, col, num;
srand(time(0));
for(int cntr=0; cntr<20;){
row = rand() % N;
col = rand() % N;
num = rand() % N + 1;
if(g[row][col].number == UNASSIGNED){
if(validate_field(g, row, col, num)){
g[row][col].number = num;
cntr++;
}
}
}
}
int main(int argc, char *argv[]) {
GRID **g = create_sudoku_grid();
random_init_grid(g);
if(generate_sudoku(g)){
printf("OK\n\n");
} else {
printf("\nNOT OK\n\n");
}
print_sudoku(g);
}
Sudoko is a computationally hard problem possibly in the order of 10^100 using brute force and ignorance. It could take a lot longer than 2-3 minutes! Sometimes, because of number layout, it is easier than that.
In one approach, you could count your iterations, and give up if it exceeds them. Your key bit is the block where you recursively call generate_soduko() -- if you end up in here too many times you are in trouble.
To that end, I changed your program put a 1s alarm on its execution, counter the number of times in that block; and if the alarm expires, print the counter and exit; if it doesn't print the counter for reference at the end. On my machine, 1s == 500,000 iterations.
*** sud.c~ 2019-12-06 14:30:21.000000000 -0500
--- sud.c 2019-12-06 14:30:57.000000000 -0500
***************
*** 1,10 ****
#include <stdio.h>
#include <stdlib.h>
#define N 9
#define UNASSIGNED 0
-
typedef enum {false, true} bool;
typedef struct {
char number;
--- 1,21 ----
#include <stdio.h>
#include <stdlib.h>
+ #include <signal.h>
+ #include <unistd.h>
+ #include <time.h>
+
+ volatile long counter;
+ void alrm(int signo) {
+ char buf[64];
+ int n;
+ n = sprintf(buf, "failed after %ld iter\n", counter);
+ write(2, buf, n);
+ _exit(1);
+ }
#define N 9
#define UNASSIGNED 0
typedef enum {false, true} bool;
typedef struct {
char number;
***************
*** 106,111 ****
--- 117,123 ----
for (int num = 1; num <= 9; num++) {
// if looks promising
if (validate_field(g, row, col, num)) {
+ counter++;
// make tentative assignment
g[row][col].number = num;
***************
*** 139,145 ****
}
int main(int argc, char *argv[]) {
! GRID **g = create_sudoku_grid();
random_init_grid(g);
if(generate_sudoku(g)){
--- 151,161 ----
}
int main(int argc, char *argv[]) {
!
! GRID **g;
! signal(SIGALRM, alrm);
! alarm(1);
! g = create_sudoku_grid();
random_init_grid(g);
if(generate_sudoku(g)){
***************
*** 148,151 ****
--- 164,168 ----
printf("\nNOT OK\n\n");
}
print_sudoku(g);
+ printf("iter = %ld\n", counter);
}

How to stop replacing chars with a replacement character �?

I'm writing a tic-tac-toe game with some additional features.
Sometimes when I try to print the array of chars (which is the board) it replaces some of the characters with a black diamond with a white question mark(�) or an empty square box.
What do I need to do to solve this?
void print_board(char board[N][N], int n)
{
printf("\nCurrent board:\n");
for (int i = 0; i < n; i++)
{
printf("|");
for (int j = 0; j < n; j++)
{
printf("%c|", board[i][j]);
}
printf("\n");
}
printf("\n");
}
I expect a normal board with x's and o's but some of these get replaced by � or an empty box.
void change_board(char board[N][N], int moves_history[TWO][N], int row, int column, int player_index, int turns_num, int board_size)
{
char player_sign = (player_index == FIRST_PLAYER) ? FIRST_PLAYER_SIGN : SECOND_PLAYER_SIGN;
board[row][column] = player_sign;
moves_history[0][turns_num-1] = row;
moves_history[1][turns_num-1] = column;
print_board(board, board_size);
if (did_anyone_win(board,player_index, player_sign,board_size,row,column))
{
exit(0);
}
player_index = (player_index == FIRST_PLAYER) ? SECOND_PLAYER : FIRST_PLAYER;
player_turn(board,board_size,turns_num,player_index,moves_history);
}
void Undo(char board[N][N], int moves_history[TWO][N], int undo, int board_size, int turns_num, int player_index)
{
for (int i = turns_num-TWO; i >= turns_num+undo-1; i--)
{
board[moves_history[0][i]][moves_history[1][i]] = EMPTY_CELL;
moves_history[0][i] = 0;
moves_history[1][i] = 0;
}
print_board(board,board_size);
player_index = player_index == FIRST_PLAYER ? SECOND_PLAYER : FIRST_PLAYER;
player_turn(board,board_size,turns_num+undo-1,player_index,moves_history);
}
These are the only places where I change the board, I don't think there's any bug here but I put them just for reference.
I noticed based on your variable names that you have an NxN matrix for your board. But your move history is an array of size N. Could that be the issue?

send non-const matrix to function that use const matrix warnings in C

I have tried to write in C two functions.
The first, a function that gets two matrices (and their size) and returns their multiple matrix.
The second, a function that gets a matrix and her size and prints it.
Both of the function doesn't change the input matrices, so I want to get them as a const in the functions (but at the main theme, not const matrices).
The output fine, but the compiler throw me warnings(as shown below), all those, when I delete the const declaration in the function, it doesn't throw me any warnings.
is someone know why it throws me those warnings? and how can I fix this? (should I need to fix it?)
thank you
#include <stdio.h>
#include <stdlib.h>
int** multiple_matrix(int row1, int column1, int row2, int column2 ,const int mat1[][column1], const int mat2[][column2])
{
if((mat1 == NULL) || (mat2 == NULL))
{
printf("matrix equal to NULL, can't multiple!!!\n");
return NULL;
}
if (row2 != column1)
{
printf("number of columns in the first matrix is not equal to number of rows in second matrix, can't multiple!!! \n");
return NULL;
}
int i,k,j,sum;
int** res_mat = malloc (sizeof(int*) * row1);
for (i = 0; i<row1; ++i)
{
res_mat[i] = malloc (sizeof(int) * column2);
for (j = 0; j < column2; ++j)
{
sum = 0;
for (k = 0; k < column1; ++k)
{
sum += mat1[i][k] * mat2[k][j];
}
res_mat[i][j] = sum;
}
}
return res_mat;
}
void print_matrix( int** mat,size_t row, size_t column)
{
if(mat != NULL)
{
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
printf("%d ",mat[i][j]);
}
printf("\n");
}
}
else
{
printf("matrix is Null\n");
}
}
int main()
{
int matrix1[][3] ={{1,2,9},{3,4,9},{5,6,9}};
int matrix2[][3] = {{7,8,9},{10,11,12},{1,1,1}};
int matrix3[][1] ={{20},{30}};
int ** matrix4 =NULL;
size_t row1 = sizeof(matrix1)/sizeof(matrix1[0]);
size_t column1 = sizeof(matrix1[0])/sizeof(matrix1[0][0]);
size_t row2 = sizeof(matrix2)/sizeof(matrix2[0]);
size_t column2 = sizeof(matrix2[0])/sizeof(matrix2[0][0]);
size_t row3 = sizeof(matrix3)/sizeof(matrix3[0]);
size_t column3 = sizeof(matrix3[0])/sizeof(matrix3[0][0]);
printf("matrix1 is: %zu X %zu\n" ,row1,column1);
printf("matrix2 is: %zu X %zu\n" ,row2,column2);
printf("matrix3 is: %zu X %zu \n\n" ,row3,column3);
int** res1_matrix = multiple_matrix(row1,column1,row2,column2, matrix1, matrix2);
printf("Matrix1 X Matrix2:\n");
print_matrix(res1_matrix, row1, column2);
printf("\n\n");
int** res2_matrix = multiple_matrix(row1,column1,row3,column3, matrix1, matrix3);
printf("Matrix1 X Matrix3:\n");
print_matrix(res2_matrix, row1, column3);
printf("\n\n");
return 0;
}
the warnings that I get when I use the const in the functions

Drawing a Vertical Graph of # based on stdin in C

I've written a program that reads integer values from stdin, separated by one or more spaces or newlines, until reaching EOF. The input will contain no more than 80 values.
On standard output, I want to create a simple vertical column graph based the input values, in order left to right, using hash # characters. The number of hashes printed in each column is be equal to the corresponding input value.
The area above a completed column is filled with space characters.
I have this so far and it works correctly for inputs that are 4 numbers or greater, but when I input 2 or 3 numbers I get a seg fault. Can anyone see why?
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char*argv) {
int arr[80];
int count=0;
int i,j;
while(1) {
if((scanf("%d", &arr[count++]))==EOF) {
break;
}
}
int max=arr[0];
for(i=0; i<count; i++) {
if(max<arr[i]) {
max=arr[i];
}
}
char **matrix;
matrix=(char**)malloc(max*sizeof(char*));
for(i=0;i<count;i++) {
matrix[i]=(char*)malloc(sizeof(char)*max);
}
for(i=0;i<count-1;i++) {
for(j=max-1;j>=0;j--) {
if(max-j<=arr[i]) {
matrix[j][i]='#';
}
else {
matrix[j][i]=' ';
}
}
}
for(i=0;i<max;i++) {
for(j=0;j<count;j++) {
printf("%c", matrix[i][j]);
}
printf("\n");
}
return 0;
}
The problem is that OP is allocating enough memory to store max * max characters (where max is the maximum value entered), while what they need is max * count (where count is number of values entered) if only positive numbers are allowed.
Moreover, the program leaks memory, as the proper free calls are missing.
An easier way to deal with memory managment (if OP can compile with a C99 compliant compiler) is using a Variable Length Array:
char matrix[rows][cols]; // where rows and cols aren't known at compile time
If VLA aren't an option, the memory can still be allocated contiguously:
#include <stdlib.h>
char **matrix = malloc(rows * sizeof(*matrix));
if ( !matrix )
exit(EXIT_FAILURE);
matrix[0] = malloc(rows * cols * sizeof(**matrix));
if ( !matrix[0] ) {
free(matrix);
exit(EXIT_FAILURE);
}
for ( int i = 1; i < rows; ++i )
matrix[i] = matrix[i - 1] + cols;
// do something with 'matrix'...
free(matrix[0]);
free(matrix);
Another potential issue is that the loop responsible for the input doesn't limit the number of values entered to the size of the buffer (80) nor checks if those values are really numbers.
The following is a complete working implementation (with some helper functions):
#include "stdio.h"
#include "limits.h"
#define MAX_ARR_SIZE 80
int min (int a, int b) {
return a < b ? a : b;
}
int max (int a, int b) {
return a > b ? a : b;
}
void draw_bar_chart (FILE *out_stream, char fill_char,
int *arr, int size,
int bottom, int top);
int read_ints (FILE *in_stream,
int *arr, int size,
int *min, int *max);
int main(void) {
int min_value, max_value;
int values[MAX_ARR_SIZE];
int n_values = read_ints(stdin, values, MAX_ARR_SIZE,
&min_value, &max_value);
// Avoid clipping the chart
int top_view = max(max_value, 0);
int bottom_view = min(min_value, 0);
draw_bar_chart(stdout, '#', values, n_values, bottom_view, top_view);
}
int read_ints (FILE *in_stream,
int *arr, int size,
int *min, int *max) {
int count = 0;
*min = INT_MAX;
*max = INT_MIN;
// Reads up to 'size' values to avoid buffer overflow.
while ( count < size && fscanf(in_stream, "%d", &arr[count]) == 1 )
{ // note that it stops when the read fails (EOF or not an int) ^^^^
if ( arr[count] > *max )
*max = arr[count];
if ( arr[count] < *min )
*min = arr[count];
++count;
}
return count;
}
void tidy_up (int a, int b, int *min, int *max) {
if ( a > b ) {
*min = b;
*max = a;
} else {
*min = a;
*max = b;
}
}
void draw_bar_chart (FILE *out_stream, char fill_char,
int *arr, int size,
int bottom, int top) {
int draw_height = top - bottom;
int i, j, start, end;
// VLA, requires a C99 compliant compiler
char canvas[draw_height][size + 1];
// null-terminates every row to make output easier
for ( i = 0; i < draw_height; ++i )
canvas[i][size] = '\0';
// The "drawing" can be done in many ways...
for ( j = 0; j < size; ++j ) {
tidy_up(top, top - arr[j], &start, &end);
for ( i = 0; i < start; ++i )
canvas[i][j] = ' ';
for ( ; i < end; ++i )
canvas[i][j] = fill_char;
for ( ; i < draw_height; ++i )
canvas[i][j] = ' ';
}
for ( i = 0; i < draw_height; ++i ) {
fprintf(out_stream, "%s\n", canvas[i]);
}
}
Which, given for example those inputs
1 5 6 9 8 7 3 2 0 -3 -8 -5 -4 1 1 2 0 1 q
Outputs:
#
##
###
####
#####
#####
######
####### #
######## ### #
####
####
####
###
##
#
#
#
It's worth noting that for this particular task, we don't need to use a temporary 2D array at all. The function responsible for printing the chart can be implemented like this:
void draw_bar_chart (FILE *out_stream, char fill_char,
int *arr, int size,
int bottom, int top) {
int start, end;
// "draws" the chart by determining if the current position is inside a bar
for ( int i = top - 1; i >= bottom; --i ) {
for ( int j = 0; j < size; ++j ) {
tidy_up(0, arr[j], &start, &end);
putc((i >= start && i < end ? fill_char : ' '), out_stream);
}
puts("");
}
}

N queens using backtracking

I have implemented a solution for the N queens problem by using backtracking.
I am checking whether the position of every queen is safe or not by checking its top left, top right and top and then placing it in the row, otherwise I backtrack.
It is giving a correct solution for some values of N, such as 4 and 8, but incorrect for others, such as 6.
I don't know what I am missing. Any help would be highly appreciated.
Here's the code:
int S;
static int cnt=0;
int safepos(int board[][S+1],int i,int j)
{
if(i==1)
return 1;
int a,b;
a=i-1;
b=j-1;
//checking for top-left side
while(a>0 && b>0 )
{
if(board[a--][b--]==1)
return 0;
}
a=i-1;
b=j+1;
//checking for top-right side
while(a>0 && b<=S )
{
if(board[a--][b++]==1)
return 0;
}
//checking for the same column
for(a=1;a<i;a++)
if(board[a][j]==1)
return 0;
return 1;
}
void Nqueens(int board[][S+1],int N,int n) //n is the number of the rows
{
if(n==N+1) //for those which reaches the last position we will have a solution
{
cnt++;
return;
}
int i;
for(i=1;i<=N;i++) //for every column
{
if( safepos(board,n,i) )
{
board[n][i]=1;
Nqueens(board,N,n+1); //checking for next row
}
board[n][i]=0;
}
}
int main()
{
int N=6;
S=N;
int board[N+1][N+1];
Nqueens(board,N,1);
printf("%d",cnt);
return 0;
}
Your implementation of the backtracking idea is correct, the problem comes from the fact that the values of the array 'board' have to be initialized to zero manually, by default the array comes with undefined values. If you do that, you should get the correct answer, I tested the code. For more information related to array initialization, see http://www.fredosaurus.com/notes-cpp/arrayptr/array-initialization.html
I know this has an accepted answered but wanted to share my implementation that uses a vector initialized to -1 and not zero as to not interfere with zero offset for row = 0
#include <iostream>
#include <vector>
const int GRID_SIZE = 8;
bool isValid ( int queenNum, int col, std::vector<int>& cols )
{
// check for other queen number that collide with this one
for ( int queenRow = 0; queenRow < queenNum; ++queenRow )
{
int queenCol = cols[queenRow];
if ( col == queenCol )
return false; // same col
if ((queenNum - queenRow) == abs( queenCol-col))
return false; // same diagonal
}
return true;
}
void solve( int queenNum, std::vector<int>& cols, std::vector<std::vector<int> >& results )
{
if ( queenNum == GRID_SIZE)
{
// we have a solution
results.push_back (cols);
}
for ( int i = 0; i < GRID_SIZE; ++ i)
{
if ( isValid(queenNum,i,cols) )
{
cols[queenNum] = i;
solve(queenNum + 1,cols, results);
}
}
}
void drawLine() {
std::string line;
for (int i=0;i<GRID_SIZE*2+1;i++)
line.append("-");
std::cout << line << std::endl;
}
void printBoard(std::vector<int>& cols)
{
drawLine();
for(int i = 0; i < GRID_SIZE; i++){
std::cout << "|";
for (int j = 0; j < GRID_SIZE; j++){
if (cols[i] == j) {
std::cout << "Q|";
} else {
std::cout << " |";
}
}
std::cout << std::endl;
drawLine();
}
std::cout << "" << std::endl;;
}
void printBoards(std::vector<std::vector<int> >& boards) {
for (int i = 0; i < (int)boards.size(); i++)
{
printBoard(boards[i]);
}
}
int main ()
{
std::vector<int> cols ( GRID_SIZE, -1);
std::vector<std::vector<int> > results;
solve(0, cols, results );
printBoards(results);
std::cout << results.size() << std::endl;
return 0;
}

Resources