Coast length, kattis - c

I'm trying to solve one problem, which I found on website https://open.kattis.com/problems/coast. Tl;dr version of problem is, that for given map of landscape, I should print out length of coastline (without inner islands).
I receive 0/26 mark, but I have no idea why, I've tested, and as far as i checked, it worked. I assume it doesn't compile, but if that is the case, why is that? It compiles for me perfectly fine.
#include <stdio.h>
int edgeCount(int, int, char*);
int topToBottomCount(int, int, char*);
int leftToRightCount(int, int, char*);
int removingInsides(int, int, char*);
int main()
{
int n = 0; // number of strings
int m = 0; // strings lenghts
//printf("Enter N(number of strings) x M(strings lenght): ");
scanf("%d", &n);
scanf("%d", &m);
char coast[1024];
for(int i = 0; i < n; i++){
scanf("%s", coast+i*m); // adding strings to char coast[1024], making array of ones and zeroes // e.g we are adding 3x4 strings - 111100001111
} // it can also be looked as 1111
// 0000 - matrix
int coasts = edgeCount(n, m, coast); // 1111
coasts += topToBottomCount(n, m, coast);
coasts += leftToRightCount(n, m, coast);
coasts -= removingInsides(n, m, coast);
printf("%d - coasts\n", coasts);
return 0;
}
int edgeCount(int n, int m, char *coast){ // if 1 is placed at the edge of the "map", it is 1 coast (2 if it is at corner)
int edgeCoast = 0;
for(int i = 0; i < m; i++){ // top edges
if(coast[i] == '1')
edgeCoast++;
}
for(int i = m*n - m; i < m*n; i++){ // bottom edges (m*n - m = first char in the last string, it can be also looked as the last row in matrix)
if(coast[i] == '1')
edgeCoast++;
}
for(int i = 0; i <m*n; i+=m){ // left side edges (first column in matrix)
if(coast[i] == '1')
edgeCoast++;
}
for(int i = m-1; i < m*n; i+=m){ // right side edges (last column in matrix)
if(coast[i] == '1')
edgeCoast++;
}
return edgeCoast;
}
int topToBottomCount(int n, int m, char *coast){
int coasts = 0;
for(int i = 0; i < m*n - m; i++){ // we start from first char in "matrix", and move to the (m*n - m = 2nd last "row")
if(coast[i] ^ coast[i+m]) // we are checking if zero is placed above one or via versa
coasts++;
}
return coasts;
}
int leftToRightCount(int n, int m, char* coast){
int coasts = 0;
int p = m-1;
for(int i = 0; i < n*m; i++){ // we start from the first charr, and we are going trough whole matrix, but the last column
if(i == p){ // p = m - 1 (last char in first row)
p+=m; // p+=m (last char in next column, and so on)
continue; // we move to next iteration
}
if(i == m*n - 1) //if we are at last char in matrix, we break out from loop
break;
if(coast[i] ^ coast[i+1])
coasts++;
}
return coasts;
}
int removingInsides(int n, int m, char* coast){ // Lakes and islands in lakes are not contributing to the sea coast. we are checking if they exist.
int innerCoasts = 0;
for(int i = m + 1; i < n*m - m - 1; i ++){
if( coast[i] == '0' && coast[i] ^ coast[i-1] && coast[i] ^ coast[i+1] && coast[i] ^ coast[i-m] && coast[i] ^ coast[i+m]) // char has to be 0, and to hist left, right, above and under there has to be 1
innerCoasts++;
}
return innerCoasts * 4; // *4 because we added 4 coasts before for each island.
}

I tried compiling your code using the GCC C++ compiler (4.9.2). It compiled fine and I tested it using the sample problem in the link you provided. It spit out the right answer.
However, when I tried compiling using the GCC C compiler (also v 4.9.2), it fails with 'for' loop initial declarations are only allowed in C99 or C11 mode, which is explained by this SO question. I think your assignment was graded using a C compiler and the compilation of your program failed due to this error.

Related

How to replace a recursive function to using stack or iteration?

I have a recursive function that I wrote in C that looks like this:
void findSolutions(int** B, int n, int i) {
if (i > n) {
printBoard(B, n);
} else {
for (int x = 1; x <= n; x++) {
if (B[i][x] == 0) {
placeQueen(B, n, i, x);
findSolutions(B, n, i + 1);
removeQueen(B, n, i, x);
}
}
}
}
The initial call is (size is an integer given by user and B is a 2D array):
findSolutions(B, size, 1);
I tried to convert it into a iteration function but there is another function called removeQueen after findSolutions. I got stuck on where to put this function call. How to solve this problem? Stack is also fine but I'm also having trouble doing that.
I'm going to assume that placeQueen(B, n, i, x) makes a change to B and that removeQueen(B, n, i, x) undoes that change.
This answer shows how to approach the problem generically. It doesn't modify the algorithm like Aconcagua has.
Let's start by defining a state structure.
typedef struct {
int **B;
int n;
int i;
} State;
The original code is equivalent to the following:
void _findSolutions(State *state) {
if (state->i >= state->n) {
printBoard(state->B, state->n);
} else {
for (int x = 1; x <= state->n; ++x) {
if (state->B[state->i][x] == 0) {
State *state2 = State_clone(state); // Deep clone.
placeQueen(state2);
++state2->i;
findSolutions(state2);
}
}
}
State_free(state); // Frees the board too.
}
void findSolutions(int** B, int n, int i) {
State *state = State_new(B, n, i); // Deep clones B.
_findSolutions(state);
}
Now, we're in position to eliminate the recursion.
void _findSolutions(State *state) {
StateStack *S = StateStack_new();
do {
if (state->i >= state->n) {
printBoard(state->B, state->n);
} else {
for (int x = state->n; x>=1; --x) { // Reversed the loop to maintain order.
if (state->B[state->i][x] == 0) {
State *state2 = State_clone(state); // Deep clone.
placeQueen(state2);
++state2->i;
StateStack_push(S, state2);
}
}
}
State_free(state); // Frees the board too.
} while (StateStack_pop(&state));
StateStack_free(S);
}
void findSolutions(int** B, int n, int i) {
State *state = State_new(B, n, i); // Deep clones B.
_findSolutions(state);
}
We can eliminate the helper we no longer need.
void findSolutions(int** B, int n, int i) {
StateStack *S = StateStack_new();
State *state = State_new(B, n, i); // Deep clones B.
do {
if (state->i >= state->n) {
printBoard(state->B, state->n);
} else {
for (int x = state->n; x>=1; --x) { // Reversed the loop to maintain order.
if (state->B[state->i][x] == 0) {
State *state2 = State_clone(state); // Deep clone.
placeQueen(state2);
++state2->i;
StateStack_push(S, state2);
}
}
}
State_free(state); // Frees the board too.
} while (StateStack_pop(S, &state));
StateStack_free(S);
}
Functions you need to implement:
StateStack *StateStack_new(void)
void StateStack_free(StateStack *S)
void StateStack_push(StateStack *S, State *state)
int StateStack_pop(StateStack *S, State **p)
State *State_new(int **B, int n, int i) (Note: Clones B)
State *State_clone(const State *state) (Note: Clones state->B)
void State_free(State *state) (Note: Frees state->B)
Structures you need to implement:
StateStack
Tip:
It would be best if you replaced
int **B = malloc((n+1)*sizeof(int*));
for (int i=1; i<=n; ++i)
B[i] = calloc(n+1, sizeof(int));
...
for (int x = 1; x <= n; ++x)
...
B[i][x]
with
char *B = calloc(n*n, 1);
...
for (int x = 0; x < n; ++x)
...
B[(i-1)*n+(x-1)]
What you get by the recursive call is that you get stored the location of the queen in current row before you advance to next row. You will have to re-produce this in the non-recursive version of your function.
You might use another array storing these positions:
unsigned int* positions = calloc(n + 1, sizeof(unsigned int));
// need to initialise all positions to 1 yet:
for(unsigned int i = 1; i <= n; ++i)
{
positions[i] = 1;
}
I reserved a dummy element so that we can use the same indices...
You can now count up last position from 1 to n, and when reaching n there, you increment next position, restarting with current from 1 – just the same way as you increment numbers in decimal, hexadecimal or octal system: 1999 + 1 = 2000 (zero based in this case...).
for(;;)
{
for(unsigned int i = 1; i <= n; ++i)
{
placeQueen(B, n, i, positions[i]);
}
printBoard(B, n);
for(unsigned int i = 1; i <= n; ++i)
{
removeQueen(B, n, i, positions[i]);
}
for(unsigned int i = 1; i <= n; ++i)
{
if(++positions[i] <= n)
// break incrementing if we are in between the numbers:
// 1424 will get 1431 (with last position updated already before)
goto CONTINUE;
positions[i] = 1;
}
// we completed the entire positions list, i. e. we reset very
// last position to 1 again (comparable to an overflow: 4444 got 1111)
// so we are done -> exit main loop:
break;
CONTINUE: (void)0;
}
It's untested code, so you might find a bug in, but it should clearly illustrate the idea. It's the naive aproach, always placing the queens and removing them again.
You can do it a bit cleverer, though: place all queens at positions 1 initially and only move the queens if you really need:
for(unsigned int i = 1; i <= n; ++i)
{
positions[i] = 1;
placeQueen(B, n, i, 1);
}
for(;;)
{
printBoard(B, n);
for(unsigned int i = 1; i <= n; ++i)
{
removeQueen(B, n, i, positions[i]);
++positions[i]
if(++positions[i] <= n)
{
placeQueen(B, n, i, positions[i]);
goto CONTINUE;
}
placeQueen(B, n, i, 1);
positions[i] = 1;
}
break;
CONTINUE: (void)0;
}
// cleaning up the board again:
for(unsigned int i = 1; i <= n; ++i)
{
removeQueen(B, n, i, 1);
}
Again, untested...
You might discover that now the queens move within first row first, different to your recursive approach before. If that disturbs you, you can count down from n to 1 while incrementing the positions and you get original order back...
At the very end (after exiting the loop), don't forget to free the array again to avoid memory leak:
free(positions);
If n doesn't get too large (eight for a typical chess board?), you might use a VLA to prevent that problem.
Edit:
Above solutions will print any possible combinations to place eight queens on a chess board. For an 8x8 board, you get 88 possible combinations, which are more than 16 millions of combinations. You pretty sure will want to filter out some of these combinations, as you did in your original solution as well (if(B[i][x] == 0)), e. g.:
unsigned char* checks = malloc(n + 1);
for(;;)
{
memset(checks, 0, (n + 1));
for(unsigned int i = 1; i <= n; ++i)
{
if(checks[positions[i]] != 0)
goto SKIP;
checks[positions[i]] = 1;
}
// place queens and print board
SKIP:
// increment positions
}
(Trivial approach! Including the filter in the more elaborate approach will get more tricky!)
This will even be a bit more strict than your test, which would have allowed
_ Q _
Q _ _
_ Q _
on a 3x3 board, as you only compare against previous column, whereas my filter wouldn't (leaving a bit more than 40 000 boards to be printed for an 8x8 board).
Edit 2: The diagonals
To filter out those boards where the queens attack each other on the diagonals you'll need additional checks. For these, you'll have to find out what the common criterion is for the fields on the same diagonal. At first, we have to distinguish two types of diagonals, those starting at B[1][1], B[1][2], ... as well as B[2][1], B[3][1], ... – all these run from top left to bottom right direction. On the main diagonal, you'll discover that the difference between row and column index does not differ, on next neighbouring diagonals the indices differ by 1 and -1 respectively, and so on. So we'll have differences in the range [-(n-1); n-1].
If we make the checks array twice as large and shift all differences by n, can re-use do exactly the same checks as we did already for the columns:
unsigned char* checks = (unsigned char*)malloc(2*n + 1);
and after we checked the columns:
memset(checks, 0, (2 * n + 1));
for(unsigned int i = 1; i <= n; ++i)
{
if(checks[n + i - positions[i]] != 0)
goto SKIP;
checks[n + i - positions[i]] = 1;
}
Side note: Even if the array is larger, you still can just memset(checks, 0, n + 1); for the columns as we don't use the additional entries...
Now next we are interested in are the diagonals going from bottom left to top right. Similarly to the other direction, you'll discover that the difference between n - i and positions[i] remains constant for fields on the same diagonal. Again we shift by n and end up in:
memset(checks, 0, (2 * n + 1));
for(unsigned int i = 1; i <= n; ++i)
{
if(checks[2 * n - i - positions[i]] != 0)
goto SKIP;
checks[2 * n - i - positions[i]] = 1;
}
Et voilà, only boards on which queens cannot attack each other.
You might discover that some boards are symmetries (rotational or reflection) of others. Filtering these, though, is much more complicated...

Rearranging an array with respect to another array

I have 2 arrays, in parallel:
defenders = {1,5,7,9,12,18};
attackers = {3,10,14,15,17,18};
Both are sorted, what I am trying to do is rearrange the defending array's values so that they win more games (defender[i] > attacker[i]) but I am having issues on how to swap the values in the defenders array. So in reality we are only working with the defenders array with respect to the attackers.
I have this but if anything it isn't shifting much and Im pretty sure I'm not doing it right. Its suppose to be a brute force method.
void rearrange(int* attackers, int* defenders, int size){
int i, c, j;
int temp;
for(i = 0; i<size; i++){
c = 0;
j = 0;
if(defenders[c]<attackers[j]){
temp = defenders[c+1];
defenders[c+1] = defenders[c];
defenders[c] = temp;
c++;
j++;
}
else
c++;
j++;
}
}
Edit: I did ask this question before, but I feel as if I worded it terribly, and didn't know how to "bump" the older post.
To be honest, I didn't look at your code, since I have to wake up in less than 2.30 hours to go to work, hope you won't have hard feelings for me.. :)
I implemented the algorithm proposed by Eugene Sh. Some links you may want to read first, before digging into the code:
qsort in C
qsort and structs
shortcircuiting
My approach:
Create merged array by scanning both att and def.
Sort merged array.
Refill def with values that satisfy the ad pattern.
Complete refilling def with the remaining values (that are
defeats)*.
*Steps 3 and 4 require two passes in my approach, maybe it can get better.
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char c; // a for att and d for def
int v;
} pair;
void print(pair* array, int N);
void print_int_array(int* array, int N);
// function to be used by qsort()
int compar(const void* a, const void* b) {
pair *pair_a = (pair *)a;
pair *pair_b = (pair *)b;
if(pair_a->v == pair_b->v)
return pair_b->c - pair_a->c; // d has highest priority
return pair_a->v - pair_b->v;
}
int main(void) {
const int N = 6;
int def[] = {1, 5, 7, 9, 12, 18};
int att[] = {3, 10, 14, 15, 17, 18};
int i, j = 0;
// let's construct the merged array
pair merged_ar[2*N];
// scan the def array
for(i = 0; i < N; ++i) {
merged_ar[i].c = 'd';
merged_ar[i].v = def[i];
}
// scan the att array
for(i = N; i < 2 * N; ++i) {
merged_ar[i].c = 'a';
merged_ar[i].v = att[j++]; // watch out for the pointers
// 'merged_ar' is bigger than 'att'
}
// sort the merged array
qsort(merged_ar, 2 * N, sizeof(pair), compar);
print(merged_ar, 2 * N);
// scan the merged array
// to collect the patterns
j = 0;
// first pass to collect the patterns ad
for(i = 0; i < 2 * N; ++i) {
// if pattern found
if(merged_ar[i].c == 'a' && // first letter of pattern
i < 2 * N - 1 && // check that I am not the last element
merged_ar[i + 1].c == 'd') { // second letter of the pattern
def[j++] = merged_ar[i + 1].v; // fill-in `def` array
merged_ar[i + 1].c = 'u'; // mark that value as used
}
}
// second pass to collect the cases were 'def' loses
for(i = 0; i < 2 * N; ++i) {
// 'a' is for the 'att' and 'u' is already in 'def'
if(merged_ar[i].c == 'd') {
def[j++] = merged_ar[i].v;
}
}
print_int_array(def, N);
return 0;
}
void print_int_array(int* array, int N) {
int i;
for(i = 0; i < N; ++i) {
printf("%d ", array[i]);
}
printf("\n");
}
void print(pair* array, int N) {
int i;
for(i = 0; i < N; ++i) {
printf("%c %d\n", array[i].c, array[i].v);
}
}
Output:
gsamaras#gsamaras:~$ gcc -Wall px.c
gsamaras#gsamaras:~$ ./a.out
d 1
a 3
d 5
d 7
d 9
a 10
d 12
a 14
a 15
a 17
d 18
a 18
5 12 18 1 7 9
The problem is that you are resetting c and j to zero on each iteration of the loop. Consequently, you are only ever comparing the first value in each array.
Another problem is that you will read one past the end of the defenders array in the case that the last value of defenders array is less than last value of attackers array.
Another problem or maybe just oddity is that you are incrementing both c and j in both branches of the if-statement. If this is what you actually want, then c and j are useless and you can just use i.
I would offer you some updated code, but there is not a good enough description of what you are trying to achieve; I can only point out the problems that are apparent.

C programming Pointer and String operations

So I have an assignment where I need to change certain functions by substituting pointer operations for array operations, and by substituting string operations for character operations. Now I have a basic understanding of pointers, arrays, strings, etc. but I cant understand what it is I have to do, and how I should go about doing it. Here is the code:
#include <stdio.h>
#pragma warning(disable: 4996)
// This program exercises the operations of pointers and arrays
#define maxrow 50
#define maxcolumn 50
char maze[maxrow][maxcolumn]; // Define a static array of arrays of characters.
int lastrow = 0;
// Forward Declarations
#define triple(x) x % 3 == 0
void initialization(int, int);
void randommaze(int, int);
void printmaze(int, int);
void initialization(int r, int c) {
int i, j;
for (i = 0; i < r; i++){
maze[i][0] = 'X'; // add border
maze[i][c - 1] = 'X'; // add border
maze[i][c] = '\0'; // add string terminator
for (j = 1; j < c - 1; j++)
{
if ((i == 0) || (i == r - 1))
maze[i][j] = 'X'; // add border
else
maze[i][j] = ' '; // initialize with space
}
}
}
// Add 'X' into the maze at random positions
void randommaze(int r, int c) {
int i, j, d;
for (i = 1; i < r - 1; i++) {
for (j = 1; j < c - 2; j++) {
d = rand();
if (triple(d))
{
maze[i][j] = 'X';
}
}
}
i = rand() % (r - 2) + 1;
j = rand() % (c - 3) + 1;
maze[i][j] = 'S'; // define Starting point
do
{
i = rand() % (r - 2) + 1;
j = rand() % (c - 3) + 1;
} while (maze[i][j] == 'S');
maze[i][j] = 'G'; // define Goal point
}
// Print the maze
void printmaze(int r, int c) {
int i, j;
for (i = 0; i < r; i++) {
for (j = 0; j < c; j++)
printf("%c", maze[i][j]);
printf("\n");
}
}
void main() {
int row, column;
printf("Please enter two integers, which must be greater than 3 and less than maxrow and maxcolomn, respectively\n");
scanf("%d\n%d", &row, &column);
while ((row <= 3) || (column <= 3) || (row >= maxrow) || (column >= maxcolumn)) {
printf("both integers must be greater than 3. Row must be less than %d, and column less than %d. Please reenter\n", maxrow, maxcolumn);
scanf("%d\n%d", &row, &column);
}
initialization(row, column);
randommaze(row, column);
printmaze(row, column);
//encryptmaze(row, column);
//printmaze(row, column);
//decryptmaze(row, column);
//printmaze(row, column);
}
Here are the questions I am struggling on:
Rewrite the function randommaze(row, column) by substituting pointer operations for all array operations. You may not use indexed operation like maze[i][j], except getting the initial value of the pointer.
Rewrite the function printmaze(row, column) by substituting string operations for all character operations.
If someone could please explain to me what I should be doing and how I should be doing it I would really appreciate it. Thanks!
Question 2.:
An array can be used as a pointer to it's first member. So, for example, array[0] and *array return the same thing - the value of the first element of the array. Since arrays are contiguous blocks of memory, if you increment (or add an offset to) a pointer that's pointing to the beginning of an array, you point to the next element of the array. That means that array[1] and *(array + 1) are the same thing.
If you a have a for loop that iterates indexing an array, you could just as well write it using pointer increments. Example:
/* Loop indexing an array */
int my_array [10];
int i = 0;
for(; i < 10; ++i) {
my_array[i] = 0;
}
/* Loop by offsetting a pointer */
int my_array [10];
int i = 0;
int *ptr = my_array; /* Make it point to the first member of the array*/
for(; i < 10; ++i) [
*(ptr + i) = 0;
}
/* Looping by incrementing the pointer */
int my_array [10];
int *ptr = my_array; /* Make it point to the first member of the array */
int *end_ptr = my_array + 10; /* Make a pointer pointing to one past the end of the array */
for(; ptr != end; ++ptr) [
*ptr = 0;
}
All these code examples do the same thing. Assign 0 to all members of the array. If you a have a multidimensional array, just remember that it's still just a contiguous block of memory.
Question 3.:
This question is not so clear to me, so my interpretation of what you're expected to do may be a bit off, but since you're just using printf to print single chars, I'm guessing that you should use a function to output a single char instead. Something like putchar.
Hopefully, this will steer you in the right direction.
It sounds as though you are engaged in a data structures course. The first challenge is to build an array mapping function. For example:
int main(int argc, char **argv)
{
int values[20][40];
values[0][0] = 1;
values[10][10] = 20;
/* Let's print these two ways */
printf("0,0: %d 10,10: %d\n", values[0][0], values[10][10]);
printf("0,0: %d 10,10: %d\n", *((*values) + (sizeof(int) * 0) + sizeof(int) * 0)), *((*values) + (sizeof(int) * 10) + sizeof(int) * 10)));
}
What we are doing is obtaining the address of the very first byte of memory in the 2d array (*values) and then adding a raw number of bytes as an offset to it to locate the value from the "array" that we'd like to access.
One of the main points of an exercise like this is to show you how the language actually works under the hood. This his how array mapping functions work generally and can be used as the basis, for example, for a language or compiler design course later, in addition to fast implementations of far more complex memory structures.
As to the second piece, I'm not super clear on this since there are no actual "string" operations built into C. I'd need a bit more detail there.

Wrong output with the N Queen

So I have to do a modified version of the N queen problem, where we are given an initial configuration of the chess board filled with pawns, and we need to find the maximum number of queens we can have so that they don't attack each other. The input consists of an integer in the first line giving the dimension of the board ( NxN) and n lines defining the setup of the chess board.The characters will be either a ‘p’ (meaning there is already a pawn in that location) or an ‘e’ (meaning that location is empty).
For example, for this input,
5
epepe
ppppp
epepe
ppppp
epepe
the output will be 9.
Here is my code, everything seems clear, but I don't see why it doesnt give the correct output
#include <stdio.h>
#include <malloc.h>
/* function headers */
void do_case(int);
int solve(char **,int,int);
int canPlace(char **,int,int,int);
/* Global vars */
int queens;
int main(void)
{
int n;
scanf("%d",&n);
getchar();
while( n != 0 )
{
do_case(n);
scanf("%d",&n);
getchar();
}
return 0;
}
void do_case(int n)
{
int i,j; //counters for input
//board configuration allocation
char **configuration = (char **)malloc(n*sizeof(char *));
for(i = 0 ; i < n ;i++ )
configuration[i] =(char *)malloc(n*sizeof(char));
queens = 0;
//get input
for( i = 0; i < n; i++ )
{
for( j = 0; j < n; j++ )
{
scanf("%c",&configuration[i][j]);
}
getchar();
}
//solve
solve(configuration,n,0);
printf("%d \n",queens);
}
//recursive solver
int solve(char **configuration,int N,int col)
{
int i,j;
//base case
if( col >= N )
return 1;
//consider this column
//try placing queen in non blocked spot in all rows
for(i = 0; i < N; i++)
{
if ( configuration[i][col] == 'e' && canPlace(configuration,N,i,col) )
{
//Place queen in configuration[i][col]
configuration[i][col] = 'q';
queens++;
//recursion on the rest
if( solve(configuration,N,col + 1) == 1 )
{
return 1;
}
//backtrack
configuration[i][col] = 'e';
queens--;
}
}
return 0;
}
//this function check if queen can be placed
int canPlace(char **configuration,int N, int row, int col)
{
int i, j;
/* Check this row on left side */
for (i = 0; i < col; i++)
{
if (configuration[row][i] == 'q')
{
return 0;
}
}
/* Check upper diagonal on left side */
for (i = row, j = col; i >= 0 && j >= 0; i--, j--)
{
if ( configuration[i][j] == 'q')
{
return 0;
}
}
/* Check lower diagonal on left side */
for (i = row, j = col; j >= 0 && i < N; i++, j--)
{
if (configuration[i][j] == 'q')
{
return 0;
}
}
return 1;
}
Basically, your code outputs 0 because it requires that we place exactly one queen in every column, which is not the case in your example.
That said, there are multiple problems with the algorithm (and I don't claim the list is complete, though it may be):
The code does not consider every possibility: it will only find the first possible arrangement, and then quit searching after a single "if( col >= N ) return 1;". Instead, it should go like "if( col >= N ) update the best possible value of queens in a separate variable, then return 0 to continue searching".
In the line "if( solve(configuration,N,col + 1) == 1 )", the code assumes there can not be two queens in a single column. The call should use col instead of col + 1, and somehow account for where we stopped at the current column.
To allow columns without queens, an unconditional call to "solve(configuration,N,col + 1)" should be placed somewhere in the solve function.
When we allow item 2, the function canPlace should be modified to also check the column.
The loops of canPlace should break whenever a pawn is found.
With pawns blocking the way, you shouldn't just move on to the next column because you can place more queens in the same column. You should modify your code to pass both a row and a column when you recurse, and only move to the next square, not the next column.
Also, it looks like your algorithm finds the first solution instead of the best solution. The original queens problem only cared about 1 possible solution, but with the modified problem, you need to make sure you check all solutions and remember the best one.
Also, your canPlace function is wrong. It doesn't account for pawns at all.

C Sorting an array by integer

So, I have to sort an array of integers so that every lesser number than some scanf'd integer is on the left, this set variable is in the middle, and every greater numbers on the right. I've got left and right part covered, but I am not sure how to make it so the variable is in the middle.. any ideas?
#include <stdio.h>
int main()
{
int y, i, k, temp;
printf("give integer\n");
scanf("%d", &y);
int x[10] = {5,8,9,4,2,3,2,4,5,6};
i=0;
k=1;
while(i<10)
{
while(x[i]>y&&k<10)
{
temp=x[k];
x[k]=x[i];
x[i]=temp;
k++;
}
i++;
k=i+1;
}
for(i=0; i<10; i++)
{
printf("x[%d]=%d\n", i, x[i]);
}
}
Example input/output:
input: x[i]={5,2,1,6,7,3,2,4,5,6} y=5
output: x[i]={2,1,4,3,2,5,5,7,6,6}
Instead of using one array you could use two arrays for reducing your code complexity.
Search for the numbers those are less than y and then store them in an array. Let's say A[ ]
Again search for the numbers those are greater than y and then store them in another array B[ ]
Like so..
Now you've got all of them. You could store them in another array which can be called as the sorted array. Or if you just want to print them, then
print all the elements of first array A[ ]
then print y
finally print the elements of second array B[ ]
That's all. Hope this idea will help you to code and solve this quickly.
You are looking for an algorithm similar to "partition" as in the quicksort algorithm. The idea is to have 2 indexes i and j where i is used to iterate through the array whereas j is the index of the first item that is greater or equal to y.
After that first loop, you have the numbers that are lesser than y on the left and the other numbers on the right. However, you actually want to group the values equal to y and have only the number greater than y on the right. So I'm suggesting to do the same on the interval [j,n] but now I'm also moving when it's equal.
// Function to exchange the values of 2 integer variables.
void swap(int *a, int *b) {
int buf = *a;
*a = *b;
*b = buf;
}
// Do the job, in place.
void partition(int *tab, int n, int y) {
// This first part will move every values strictly lesser than y on the left. But the right part could be "6 7 5 8" with y=5. On the right side, numbers are greater or equal to `y`.
int j = 0; // j is the index of the position of the first item greater or equal to y.
int i;
for (i = 0; i < n; i++) {
if (tab[i] < y) {
// We found a number lesser than y, we swap it with the first item that is greater or equal to `y`.
swap(&tab[i], &tab[j]);
j++; // Now the position of the first value greater or equal to y is the next one.
}
}
// Basically the same idea on the right part of the array.
for (i = j; i < n; i++) {
if (tab[i] <= y) {
swap(&tab[i], &tab[j]);
j++;
}
}
}
int main() {
int y;
printf("give integer\n");
scanf("%d", &y);
int x[10] = {5,8,9,4,2,3,2,4,5,6};
partition(x, 10, y);
int i;
for(i=0; i<10; i++)
{
printf("x[%d]=%d\n", i, x[i]);
}
return 0;
}
This code gives, with x = {5,2,1,6,7,3,2,4,5,6}; and y = 5:
x[0]=2
x[1]=1
x[2]=3
x[3]=2
x[4]=4
x[5]=5
x[6]=5
x[7]=7
x[8]=6
x[9]=6
The first 5 elements are lower than 5 and the others are greater or equal to 5.
This is a simple, straight forward way to sort the array x into another array y by partition. The numbers are sorted <= partition on left, and > partition on right:
[EDIT] to illustrate method according to OP clarification:
if array has 2 elements that are equal to p, then it should be arranged like this: xxxxxppyyyy where xp and p can't be mixed with either x's or y's.
Except that the example: xxxxxppyyyy is too long for the array, so I assume you meant xxxxppxxxx (10 elements, not 11).
int * partitionArr(int *z, int p);
int main(void)
{
int i, x[10] = {5,8,9,4,2,3,2,4,5,6};
//int i, x[10] = {3,3,3,3,3,8,8,8,8,8};
int *y;
int partition;
printf("enter a number from 0 to 10\n");
scanf("%d", &partition);
y = malloc(sizeof(int) * sizeof(x)/sizeof(x[0])+1); //+1 for inserting partition
y = partitionArr(x, partition);
printf("Partition is: %d\n\n", partition);
for(i=0;i<sizeof(x)/sizeof(x[0]);i++)
{
printf("y[%d] == %d\n", i, y[i]);
}
getchar();
getchar();
return 0;
}
int * partitionArr(int *z, int p)
{
int i=0,j=0;
int x[10];
//load y with x
for(i=0;i<sizeof(x)/sizeof(x[0]);i++) x[i] = z[i];
for(i=0;i<sizeof(x)/sizeof(x[0]);i++)
{
if(x[i]<p)
{
z[j] = x[i];
j++;
}
}
for(i=0;i<sizeof(x)/sizeof(x[0]);i++)
{
if(x[i]==p)
{
z[j] = x[i];
j++;
}
}
for(i=0;i<sizeof(x)/sizeof(x[0]);i++)
{
if(x[i]>p)
{
z[j] = x[i];
j++;
}
}
return z;
}
OUTPUT for following conditions: x < P; x== P; x< p (the only way to ensure P is in middle)
Simple algorithm, in case you want to work this through yourself:
partition entire array as [min..y][y+1..max], and take note of where the split is.
re-partition the first part only as [min..y-1][y..y].
Array should now be partitioned [min..y-1][y..y][y+1..max].
Simplest is to have a partition_helper function which does the partitioning and returns position of the split. Then the primary partition function calls this function twice, with right arguments.
You could also partition the other way, [min..y-1][y..max] first and then the re-partition the last part as [y..y][y+1..max], end result should be the same.

Resources