Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I try to write a sudoku solver
I always get a segmentation fault after calling getPossibleElements in solveSudoku.
If I delete this line the error doesnt appear.
My Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SUDOKU_X 8
#define SUDOKU_Y 8
#define MAX_FILENAME 50
#define MAX_POSSIBILITIES 8
typedef enum bool {false, true} bool;
void printPossibilities (bool numbers[], const int pos_x, const int pos_y) {
int i = 0;
for (i = 0; i <= MAX_POSSIBILITIES; i++) {
if (numbers[i]) {
printf("%d ", (i+1));
}
}
}
void getPossibleElements (bool numbers[],int a[][SUDOKU_Y], const int pos_x, const int pos_y) {
int x = 0;
int y = 0;
int i = 0;
int j = 0;
int tmp = 0;
for (x = 0; x <= MAX_POSSIBILITIES; x++) {
numbers[x] = true;
}
/* row */
for (x = 0; x <= SUDOKU_X; x++) {
if (a[pos_y][x] > 0) {
printf("ROW->a[%d][%d]\n",pos_y,x);
printf("ROW->%d\n",a[pos_y][x]-1);
numbers[a[pos_y][x]-1] = false;
}
}
/* coloumn */
for (y = 0; y <= SUDOKU_Y; y++) {
if (a[y][pos_x] > 0) {
printf("coloumn->a[%d][%d]\n",y,pos_x);
printf("coloumn->%d\n",a[y][pos_x]-1);
numbers[a[y][pos_x]-1] = false;
}
}
/* field */
if (pos_x <= 2 && pos_y <= 2) {
x = 0;
y = 0;
}
else if (pos_x <= 5 && pos_y <= 2) {
x = 3;
y = 0;
}
else if (pos_x <= 8 && pos_y <= 2) {
x = 6;
y = 0;
}
else if (pos_x <= 2 && pos_y <= 5) {
x = 0;
y = 3;
}
else if (pos_x <= 5 && pos_y <= 5) {
x = 3;
y = 3;
}
else if (pos_x <= 8 && pos_y <= 5) {
x = 6;
y = 3;
}
else if (pos_x <= 2) {
x = 0;
y = 6;
}
else if (pos_x <= 5) {
x = 3;
y = 6;
}
else if (pos_x <= 8) {
x = 6;
y = 6;
}
printf("DB!!! x=%d y=%d\n", x,y);
for (j = y; j < (y+3); j++) {
for (i = x; i < (x+3); i++) {
if (a[j][i] > 0) {
printf("FIELD->a[%d][%d]\n",j,i);
printf("FIELD->%d\n",(a[j][i])-1);
numbers[(a[j][i])-1] = false;
}
}
}
printf("db");
}
void printSudoku (int a[][SUDOKU_Y]) {
int i = 0;
int j = 0;
printf("-------------------------------\n");
for (j = 0; j <= SUDOKU_X; j++)
{
for (i = 0; i <= SUDOKU_Y; i++) {
if (i == 0) {
printf("|");
}
printf(" %d ",a[j][i]);
if (i == 2 || i == 5 || i == 8) {
printf("|");
}
}
printf("\n");
if (j == 2 || j == 5) {
printf("|-----------------------------|\n");
}
}
printf("-------------------------------\n");
}/* printSudoku */
bool solveSudoku (int a [][SUDOKU_Y]) {
bool numbers[MAX_POSSIBILITIES];
int x = 0;
int y = 0;
printSudoku(a);
getPossibleElements(numbers,a,x,y);
printPossibilities(numbers,x,y);
return true;
}
void readFiletoArray (const char * fileName, int a[][SUDOKU_Y])
{
FILE *fp = fopen(fileName,"r");
int i = 0;
int j = 0;
int val0 = 0;
int val1 = 0;
int val2 = 0;
if( fp == NULL ) {
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
while(fscanf(fp, "%d %d %d", &val0, &val1, &val2) > 0) {
a[j][i++] = val0;
a[j][i++] = val1;
a[j][i++] = val2;
if (i >= 8) {
i = 0;
j++;
}
}
fclose(fp);
} /* readFiletoArray */
int main (int argc, char * argv []) {
int a[SUDOKU_X][SUDOKU_Y];
char fileName[MAX_FILENAME];
bool numbers[MAX_POSSIBILITIES];
bool success = false;
if(argc == 2) {
strncpy(fileName, argv[1], MAX_FILENAME-1);
fileName[MAX_FILENAME] = '\0';
}
else {
printf("ERROR: Invalid Parameter\n");
exit(EXIT_FAILURE);
}
readFiletoArray(fileName, a);
success = solveSudoku(a);
printf("DB");
exit(EXIT_SUCCESS);
} /* Main */
sudoku.txt (Program Parameter)
0 5 9 0 4 0 2 0 0
0 1 0 0 5 0 0 0 7
4 0 0 3 2 9 0 1 5
3 2 0 1 0 0 9 0 0
0 0 7 4 0 6 5 0 0
0 0 4 0 0 5 0 7 8
6 9 0 5 0 3 0 0 4
5 0 0 0 6 0 0 3 0
0 0 8 0 1 0 6 5 0
Thx
At a glance, this is because you are running off the end of the array in various places.
for (x = 0; x <= MAX_POSSIBILITIES; x++) { // 0,1,2...8
See that <= you have there? That's your problem.
numbers is declared as bool numbers[MAX_POSSIBILITIES];, and array indices in C start at 0 and go to length - 1. Zero through seven in this case, but you are trying to access numbers[8].
You have the same issue elsewhere. a is declared as
int a[SUDOKU_X][SUDOKU_Y]; // int a[8][8];
and in getPossibleElements you are iterating from 0 to 8 inclusive, like so:
for (x = 0; x <= SUDOKU_X; x++) {
...
for (y = 0; y <= SUDOKU_Y; y++) {
...thus running off the end of your array again.
Same deal in printPossibilities.
Change MAX_POSSIBILITIES, SUDOKU_X and SUDOKU_Y to be 9 in your #defines and iterate from 0 to 8 by doing
for (x = 0; x < SUDOKU_X; x++) { // 0,1,2...8
One more thing. You should fix your fileName stuff too. Same deal. The last index in an array is length - 1, not length. If you had warnings cranked up when you compiled, it probably would have mentioned this one.
if (argc == 2) {
strncpy(fileName, argv[1], MAX_FILENAME - 2); // was MAX_FILENAME - 1
fileName[MAX_FILENAME - 1] = '\0'; // was [MAX_FILENAME]
}
Related
I have a problem in my C program. I need to write a histogram of numbers. If the number on the input will be outside the interval [1, 9], consider such a number as the value 1. I don't understand why it doesn't work.
#include <stdio.h>
#include <stdlib.h>
void printHistogram_vertical(int *hist, int n);
int main()
{
int i, j;
int inputValue;
scanf("%d", &inputValue);
int hist[inputValue];
for (i = 0; i < inputValue; ++i)
{
scanf("%d", &hist[i]);
}
int results[10] = {0};
for (i = 0; i < 10; ++i)
{
for (j = 0; j < inputValue; ++j)
{
if (hist[j] >= 10 && hist[j] < 1)
{
results[j] == 1;
}
if (hist[j] == i)
{
results[i]++;
}
}
}
return 0;
}
void printHistogram_vertical(int *hist, int n)
{
int i, j;
for (i = 1; i < n; i++)
{
printf(" %d ", i);
for (j = 0; j < hist[i]; ++j)
{
printf("#");
}
printf("\n");
}
}
Input:
9
3 3 2 3 7 1 1 4 10
My Output:
1 ##
2 #
3 ###
4 #
5
6
7 #
8
9
The correct output:
1 ###
2 #
3 ###
4 #
5
6
7 #
8
9
If the number is bigger than 10 and smaller than 1 it should count this number as 1. I write this function:
for (i = 0; i < 10; ++i)
{
for (j = 0; j < inputValue; ++j)
{
if (hist[j] >= 10 && hist[j] < 1)
{
results[j] == 1;
}
if (hist[j] == i)
{
results[i]++;
}
}
}
There are 2 problems with following condition:
if (hist[j] >= 10 && hist[j] < 1)
{
results[j] == 1;
}
The comparison is broken. Value cannot be above 9 AND below 1 at the same time. It should be OR instead.
What should be increment of index 1, is actually comparison == of wrong index.
Replacement:
if (hist[j] >= 10 || hist[j] < 1)
{
results[1]++;
}
But double for loop construction is more complicated than it needs to be. It could be replaced with single for loop:
for (j = 0; j < inputValue; ++j) {
int value = hist[j];
if(value >= 1 && value <= 9) {
results[value]++;
}
else {
results[1]++;
}
}
To preface what I'm trying to do - I'm trying to make a Shortest Job First (SJF), the OS algo in C.
And to handle the sort-by-burst-time, I'm pushing all the ready processes in a stack, and then sorting that stack in a descending order. So for example - if the stack looks like 3,5,1,2 with "2" on top, I'm trying to sort it as: 5,3,2,1 with "1" on top. So when I start using pop, I'll get elements in the order I require.
But the problem with the code I'm going to show is, it orders 1,1,5,3 as 5,1,1,3. The last process "3" is never sorted.
Code for Sorting:
void sortByBurst() {
int size = top;
struct fcfs temp;
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < (size - 1 - i); j++) {
if (stack[j].burst < stack[j + 1].burst) {
temp = stack[j];
stack[j] = stack[j + 1];
stack[j + 1] = temp;
}
}
}
}
And in case you want to see where I'm handling the rest of the logic i.e making decisions on what to push - this is the for loop for that:
for (i = 0; i < numOfProc; i++) {
if (first_process == 1 && p[i].arrival <= current_time && p[i].completed == 0) {
min_index = i;
} else if (first_process == 0 && last_index != -1) {
for (int k = 0; k < numOfProc; k++) {
if (p[k].completed == 0 && p[k].arrival <= p[last_index].max_slot && p[k].inQ != 1) {
push(p[k]);
p[k].inQ = 1;
critical_case = 1;
} else if (p[k].completed == 0 && p[k].arrival > finalp[last_index].max_slot && p[k].inQ != 1) {
min_index = k;
}
}
if (critical_case == 1) {
sortByBurst();
struct fcfs compare = pop();
for (int l = 0; l < numOfProc; l++) {
if (compare.pid == p[l].pid) {
min_index = l;
break;
}
}
}
break;
}
}
The input I'm testing my code with is:
1. Process 1 | 2 (Arrival) | 1 (Burst)
2. Process 2 | 1 (Arrival) | 5 (Burst)
3. Process 3 | 4 (Arrival) | 1 (Burst)
4. Process 4 | 0 (Arrival) | 6 (Burst)
5. Process 5 | 2 (Arrival) | 3 (Burst)
Required Output:
1. Process 4 | 0 (Arrival) | 6 (Burst)
2. Process 1 | 2 (Arrival) | 1 (Burst)
3. Process 3 | 4 (Arrival) | 1 (Burst)
4. Process 5 | 2 (Arrival) | 3 (Burst)
5. Process 2 | 1 (Arrival) | 5 (Burst)
Output I'm Getting:
1. Process 4 | 0 (Arrival) | 6 (Burst)
2. Process 5 | 2 (Arrival) | 3 (Burst)
3. Process 3 | 4 (Arrival) | 1 (Burst)
4. Process 1 | 2 (Arrival) | 1 (Burst)
5. Process 2 | 1 (Arrival) | 5 (Burst)
As you can see, the Process 5 should be at 4th place in the list. But because in Stack - it's still on Top even after sorting, the algo is not working as it should. Kindly look into what I'm doing wrong here.
Complete Code:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
struct fcfs {
int pid, arrival, burst, min_slot, max_slot, wait_time, completed, inQ;
};
struct fcfs stack[10];
int top = -1;
void push(struct fcfs process);
struct fcfs pop();
void sortByBurst();
void pline(int x);
void main() {
int i, numOfProc, j;
int counter = 0;
int current_time = 0;
int completed = 0;
struct fcfs p[10], finalp[10];
int first_process = 1;
int prevMaxSlot = 0;
int last_index = -1;
int critical_case = 0;
printf("Enter total number of Processes \n");
scanf("%d", &numOfProc);
for (i = 0; i < numOfProc; i++) {
printf("Enter Arrival Time & Burst Time for Process %d: \n", i + 1);
scanf("%d %d", &p[i].arrival, &p[i].burst);
p[i].pid = i + 1;
p[i].wait_time = 0;
p[i].completed = 0;
p[i].inQ = 0;
}
int prev = 0;
while (completed != numOfProc) {
int min_index = -1;
for (i = 0; i < numOfProc; i++) {
if (first_process == 1 && p[i].arrival <= current_time && p[i].completed == 0) {
min_index = i;
} else if (first_process == 0 && last_index != -1) {
for (int k = 0; k < numOfProc; k++) {
if (p[k].completed == 0 && p[k].arrival <= p[last_index].max_slot && p[k].inQ != 1) {
push(p[k]);
p[k].inQ = 1;
critical_case = 1;
} else if (p[k].completed == 0 && p[k].arrival > finalp[last_index].max_slot && p[k].inQ != 1) {
min_index = k;
}
}
if (critical_case == 1) {
sortByBurst();
struct fcfs compare = pop();
for (int l = 0; l < numOfProc; l++) {
if (compare.pid == p[l].pid) {
min_index = l;
break;
}
}
}
break;
}
}
if (min_index == -1) {
current_time++;
} else {
if (p[min_index].arrival == prevMaxSlot) {
p[min_index].min_slot = prevMaxSlot;
p[min_index].max_slot = p[min_index].arrival + p[min_index].burst;
} else if (p[min_index].arrival < prevMaxSlot || p[min_index].arrival == prevMaxSlot) {
p[min_index].min_slot = prevMaxSlot;
p[min_index].max_slot = p[min_index].min_slot + p[min_index].burst;
} else if (p[min_index].arrival > prevMaxSlot) {
p[min_index].min_slot = p[min_index].arrival;
p[min_index].max_slot = p[min_index].arrival + p[min_index].burst;
}
p[min_index].wait_time = (first_process == 1) ? 0 : abs(p[i].min_slot - prev);
p[min_index].completed = 1;
prev = current_time;
prevMaxSlot = p[min_index].max_slot;
finalp[counter++] = p[min_index];
first_process = 0;
last_index = min_index;
completed++;
}
}
pline(44);
printf("Slot\tPID\tArrival\t\tBurst\n");
pline(44);
for (i = 0; i < numOfProc; i++) {
if ((finalp[i].min_slot - finalp[i - 1].max_slot) > 0 && i > 0) {
printf("%d - %d\tNONE\tNONE\t\tNONE\n", finalp[i - 1].max_slot, finalp[i].min_slot);
} else if ((abs(0 - finalp[i].min_slot) > 0 && i == 0)) {
printf("0 - %d\tNONE\tNONE\t\tNONE\n", finalp[i].min_slot);
}
printf("%d - %d\t%d\t%d\t\t%d\n", finalp[i].min_slot, finalp[i].max_slot, finalp[i].pid, finalp[i].arrival,
finalp[i].burst);
}
pline(44);
}
void pline(int x) {
for (int i = 0; i < x; i++) {
printf("-");
}
printf("\n");
}
void push(struct fcfs process) {
if (top == 10)
printf("\n Overflow");
else {
top = top + 1;
stack[top] = process;
}
}
struct fcfs pop() {
struct fcfs process;
if (top == -1)
printf("Underflow");
else {
process = stack[top];
top = top - 1;
}
return process;
}
void sortByBurst() {
int size = top + 1;
struct fcfs temp;
for (int i = 1; i < size - 1; i++) {
for (int j = 0; j < (size - 1 - i); j++) {
if (stack[j].burst < stack[j + 1].burst) {
temp = stack[j];
stack[j] = stack[j + 1];
stack[j + 1] = temp;
}
}
}
}
The issue was with top & i = 1;
In the sorting function, int size = top + 1 and initializing the for loop with i = 0 fixed it.
Thanks a lot to all who contributed.
I am trying to implement Dijkstras algorithm in c and I almost have the right output. Something is happening it the dist array. It is giving extremely large and small numbers.
Link to site I'm basing most of my algorithm code on: https://www.geeksforgeeks.org/dijkstras-shortest-path-algorithm-greedy-algo-7/ this also explains the algorithm if you're not familiar.
Here is the code:
#include <limits.h>
#include <stdio.h>
#include<stdbool.h>
#define N 10 /* max matrix size is 10 x 10 */
#define INF INT_MAX /* infinity? */
int src; /* global */
void getdata(int amtrx[3][N], int *n, int *src) {
int i, j, nsz, nedg, fr, to, vtx, wt;
scanf("%d %d %d", &nsz, &nedg, &vtx);
for (i = 0; i < nsz; i++)
for (j = 0; j < nsz; j++)
amtrx[i][j] = INF;
for(i=0; i < nedg; i++) {
scanf("%d %d %d", &fr, &to, &wt);
amtrx[fr][to] = wt;
}
*n = nsz;
*src = vtx;
}
void printpaths(int dist[], int n) {
int i;
for (i = 0; i < n; i++)
if(i == src);
else if (dist[i] < INF) {
printf("%d %d %d\n", src, i, amtrx[i]);
} else {
printf("%d %d INF (no path)\n", src, i);
}
}
void dijkstras(int amtrx[][N], int n) {
int dist[n], v;
bool spt[n];
int min = INF, u;
for (v = 0; v < n; v++)
if (spt[v] == false && dist[v] <= min) {
min = dist[v], u = v;
spt[u] = true;
}
for (v = 0; v < n; v++)
if (!spt[v] && amtrx[u][v] != INF && dist[u] != INF && dist[u] + amtrx[u][v] < dist[v])
dist[v] = dist[u] + amtrx[u][v];
printpaths(dist, n);
}
int main() {
int amtrx[N][N];
int n;
getdata(amtrx, &n, &src);
dijkstras(amtrx, n);
return 0;
}
Here is the input:
6 11 0
0 1 50
0 2 10
0 4 45
1 2 15
1 4 10
2 0 20
2 3 15
3 1 20
3 4 35
4 3 30
5 4 03
Output:
0 1 32701
0 2 -1996178040
0 3 -1996178014
0 4 -1996178044
0 5 32765
Expected output:
0 1 45
0 2 10
0 3 25
0 4 45
0 5 INF (no path)
Thanks for the help in advance! I'm hoping it's just a simple fix that I can't seem to see :)
update
I think the algorithm was wrong and I worked on it a little, the output is still wrong but i think this is more right than before:
void dijkstras(int amtrx[][N], int n) {
int dist[n], v, q;
bool spt[n];
int min = INF, u;
for (v = 0; v < n; v++) {
dist[v] = INF;
spt[v] = false;
}
dist[n] = 0;
for (v = 0; v < n - 1; v++) {
for (q = 0; q < n; q++) {
if (spt[v] == false && dist[v] <= min) {
min = dist[v], u = v;
}
spt[u] = true;
}
for (v = 0; v < n; v++)
if (!spt[v] && amtrx[u][v] != INF && dist[u] != INF && dist[u] + amtrx[u][v] < dist[v])
dist[v] = dist[u] + amtrx[u][v];
}
printpaths(dist, n);
}
Output now:
0 1 INF (no path)
0 2 INF (no path)
0 3 INF (no path)
0 4 INF (no path)
0 5 INF (no path)
update 2
void dijkstras(int amtrx[][N], int n) {
int min = INF, dist[N], count, v, u;
bool spt[N];
for (v = 0; v < N; v++) {
dist[v] = INF;
spt[v] = false;
}
dist[src] = 0;
for (count = 0; count < N - 1; count++) {
for (v = 0; v < N; v++)
if (spt[v] == false && dist[v] <= min)
min = dist[v], u = v;
spt[u] = true;
for (v = 0; v < N; v++)
if (!spt[v] && amtrx[u][v] && dist[u] != INF && dist[u] + amtrx[u][v] < dist[v])
dist[v] = dist[u] + amtrx[u][v];
}
printpaths(dist, n);
}
output:
0 1 50
0 2 10
0 3 INF (no path)
0 4 45
0 5 INF (no path)
I'm so close I can taste it! Any help is appreciated!
void dijkstras(int amtrx[][N], int n) {
int min = INF, dist[n], count, v, u;
bool spt[n];
for (v = 0; v < n; v++) {
dist[v] = INF;
spt[v] = false;
}
dist[src] = 0;
for (count = 0; count < n - 1; count++) {
min=INF;
for (v = 0; v < n; v++)
if (spt[v] == false && dist[v] <= min)
min = dist[v], u = v;
spt[u] = true;
for (v = 0; v < n; v++)
if (!spt[v] && amtrx[u][v] != INF && dist[u] != INF && dist[u] + amtrx[u][v] < dist[v])
dist[v] = dist[u] + amtrx[u][v];
}
printpaths(dist, n);
}
I'm doing program where I enter the number from keyboard. Then 2d array is created, and it's filled in spiral order till this number. All elements after the number will be equal to 0; The function fills the array in spiral order (to right -> down -> left -> up).
Code is:
#include <stdio.h>
#include <time.h>
void spiral(int array[100][100], int m, int n, int s)
{
int size, b, x = 0, y = 1, num = 1;
size = m*n;
for (num=1;num<=size+1;num++)
{
for (b = x; b < n; b++)
{
if (num <=s) {
array[x][b] = num;
num++;
}
else array[x][b] = 0;
}
if (num == size + 1)
{
break;
}
for (b = y; b < m; b++)
{
if (num <=s) {
array[b][n - 1] = num;
num++;
}
else array[b][n - 1] = 0;
}
if (num == size + 1)
{
break;
}
y++;
n--;
for (b = n - 1; b > x; b--)
{
if (num <= s) {
array[m - 1][b] = num;
num++;
}
else array[m - 1][b] = 0;
}
if (num == size + 1)
{
break;
}
for (b = m - 1; b > x; b--)
{
if (num <= s) {
array[b][x] = num;
num++;
}
else array[b][x] = 0;
}
x++;
m--;
}
}
int main()
{
int m, n, s, array[100][100];
srand(time(NULL));
//m=3;
// n=4;
m = 2 + rand() % 5;
n = 2 + rand() % 5;
//memset(array, 0, sizeof(array[0][0]) * 10 * 10);
printf("enter the number \n");
scanf("%i", &s);
spiral(array, m, n, s);
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
printf("%i\t", array[i][j]);
}
printf("\n");
}
return (0); }
However it doesn't work always correctly.
For example when i enter 15 and the program generates 4*3 array the output is`
1 2 3
10 12 4
9 -858993460 5
8 7 6`
However expected output is
1 2 3
10 11 4
9 12 5
8 7 6
Or when i enter 15 and the program generates 4*5 array the output is
1 2 3 4 5
14 0 0 0 6
13 0 0 0 7
12 11 10 9 8
And the expected output is
1 2 3 4 5
14 15 0 0 6
13 0 0 0 7
12 11 10 9 8
I can't find whats wrong with this code.
Try this:
void printArray(int array[10][10], int m, int n) {
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
printf("%i\t", array[i][j]);
}
printf("\n");
}
printf("\n");
}
void spiral(int array[10][10], int m, int n, int s)
{
int size, b, x = 0, y = 1, num = 1;
size = m*n;
while ( num <= s )
{
for (b = x; b < n; b++)
{
if (num <= s) {
array[x][b] = num;
num++;
} else array[x][b] = 0;
}
if (num == size + 1)
{
break;
}
for (b = y; b < m; b++)
{
if (num <= s) {
array[b][n - 1] = num;
num++;
} else array[b][n - 1] = 0;
}
if (num == size + 1)
{
break;
}
y++;
n--;
for (b = n - 1; b > x; b--)
{
if (num <= s) {
array[m - 1][b] = num;
num++;
} else array[m - 1][b] = 0;
}
if (num == size + 1)
{
break;
}
for (b = m - 1; b > x; b--)
{
if (num <= s) {
array[b][x] = num;
num++;
} else array[b][x] = 0;
}
x++;
m--;
}
}
int main()
{
int m, n, s, array[10][10];
srand(time(NULL));
m = 2 + rand() % 5;
n = 2 + rand() % 5;
memset(array, 0, sizeof(array[0][0]) * 10* 10);
printf("enter the number \n");
scanf("%i", &s);
spiral(array, m, n, s);
printArray(array, m, n);
return (0);
}
Before you had some weird for loop on top of your spiral function. The num++ in it interfered with the fact that you already increased num by one and made it skip the number the next time it would write in the uppermost line.
I changed it to a while loop that runs until num>s and it seems to work for me now.
Note that I just added printArray for easier debugging.
I wanted to build a spiral square matrix using recursion. I am able to build spiral square matrix using iterative method as below:
void main()
{
int initial_direction = UP , n = MAX , p = 1 ; /* intial_direction
is set to UP because we need to start moving right */
int r ,c , a[MAX][MAX];
int row_right = 0 , column_down = n-1 , row_left = n-1 , column_up = 0 ;
clrscr ();
//Set all elements of the matrix to 0
for(r = 0 ; r < MAX ; r++)
{
for(c = 0 ; c < MAX ; c++)
a[r][c] = 0 ;
}
//Generate elements of the spiral matrix
while(p != n*n+1)
{
if(initial_direction == UP)
{
//Move RIGHT
r = row_right++ ;
for(c = 0 ; c < n ; c++)
{
if(a[r][c] == 0)
a[r][c] = p++;
}
initial_direction = RIGHT ;
}
else if(initial_direction == RIGHT)
{
//Move down
c = column_down-- ;
for(r = 0 ; r < n ; r++)
{
if(a[r][c] == 0)
a[r][c] = p++;
}
initial_direction = DOWN ;
}
else if(initial_direction == DOWN)
{
//Move left
r = row_left-- ;
for(c = n-1 ; c >= 0 ; c--)
{
if(a[r][c] == 0)
a[r][c] = p++;
}
initial_direction = LEFT ;
}
else if(initial_direction == LEFT)
{
//Move up
c = column_up++;
for(r = n-1 ; r >= 0 ; r--)
{
if(a[r][c] == 0)
a[r][c] = p++;
}
initial_direction = UP ;
}
}
//Print the matrix
printf("\n\n");
for(r = 0 ; r < MAX ; r++)
{
for(c = 0 ; c < MAX ; c++)
printf("%4d ",a[r][c]);
printf("\n");
}
}
I wanted to create the same matrix using recursion:
Here is the code i used:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
bool s[5][5] = {0};
int counter;
typedef enum {
right = 0,
down,
left,
up
}c_flag;
c_flag flag;
int last;
int build_matrix(int a[5][5],int i,int j, c_flag flag)
{
int ret;
if (i < 0 || i>=5 || j < 0 || j >= 5)
{
if (last == right)
{
flag = down;
last = flag;
}
if (last == down)
{
flag = left;
last = flag;
}
if (last == left)
{
flag = up;
last = flag;
}
if (last == up)
{
flag = left;
last = flag;
}
return false;
}
if (s[i][j] == true)
{
if (last == right)
{
flag = down;
last = flag;
}
if (last == down)
{
flag = left;
last = flag;
}
if (last == left)
{
flag = up;
last = flag;
}
if (last == up)
{
flag = left;
last = flag;
}
return false;
}
if(s[i][j] == false)
{
s[i][j] = true;
a[i][j] = ++ counter;
}
if (flag == right)
{
ret = build_matrix(a,i,j+1,right);
//if (!ret)
// return false;
}
flag = down;
last = flag;
if (flag == down)
{
ret =build_matrix(a,i+1,j,down);
//if (!ret)
// return false;
}
flag = left;
last = flag;
if (flag == left)
{
ret = build_matrix(a,i,j-1,left);
//if (!ret)
// return false;
}
flag = up;
last = flag;
if (flag == up)
{
ret = build_matrix (a,i-1,j,up);
//if (!ret)
// return false;
}
flag = right;
last = flag;
return false;
}
int main()
{
int i, j, n = 5;
int k, ret;
//printf("Enter N to construct square matrix \n");
//scanf("%d",&n);
int a[5][5] = {0};
k = n/2 + n%2;
for (i = 0; i < k; i++)
{
ret = build_matrix(a,i,i,right);
}
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
printf("%d",a[i][j]);
printf("\n");
}
return 0;
}
I am getting out put for above as :
1 2 3 4 5
16 19 22 25 6
15 18 21 24 7
14 17 20 23 8
13 12 11 10 9
instead of
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
Problem is Flag is not setting proper, i dunno inside which recursion call flag is getting disturbed.
Please some one help implement using recursion.
#include <stdio.h>
void build_matrix(int msize, int a[msize][msize], int size, int value){
int i, row, col;
if(size < 1)
return;
row = col = (msize - size) / 2;
if(size==1){
a[row][col] = value;
return;
}
for(i=0;i<size-1;++i)
a[row][col++] = value++;//RIGHT
for(i=0;i<size-1;++i)
a[row++][col] = value++;//DOWN
for(i=0;i<size-1;++i)
a[row][col--] = value++;//LEFT
for(i=0;i<size-1;++i)
a[row--][col] = value++;//UP
build_matrix(msize, a, size-2, value);
}
int main(){
int size;
printf("input size : ");
scanf("%d", &size);
int a[size][size];
build_matrix(size, a, size, 1);
for(int r=0;r<size;++r){
for(int c=0;c<size;++c)
printf("%3d ", a[r][c]);
printf("\n");
}
return 0;
}
Working Code, without divide and Just recurse:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define N 20
bool s[N][N] = {0};
int counter;
typedef enum {
right = 0,
down,
left,
up
}c_flag;
c_flag flag;
int build_matrix(int a[N][N],int i,int j, c_flag flag)
{
int ret;
if (i < 0 || i>=N || j < 0 || j >= N || s[i][j] == true)
return false;
if(s[i][j] == false && a[i][j] == 0)
{
s[i][j] = true;
a[i][j] = ++ counter;
}
if (flag == right)
ret = build_matrix(a,i,j+1,right);
flag = down;
if (flag == down)
ret =build_matrix(a,i+1,j,down);
flag = left;
if (flag == left)
ret = build_matrix(a,i,j-1,left);
flag = up;
if (flag == up)
ret = build_matrix (a,i-1,j,up);
flag = right;
if (flag == right)
ret = build_matrix(a,i,j+1,right);
return false;
}
int main()
{
int i, j;
int k, ret;
//printf("Enter N to construct square matrix \n");
//scanf("%d",&n);
int a[N][N] = {0};
k = N/2 + N%2;
build_matrix(a,i,i,right);
for(i = 0; i < N; i++)
{
for(j = 0; j < N; j++)
{
if (!(a[i][j] < 100))
printf("%3d ",a[i][j]);
else if(a[i][j] < 10)
printf("00%d ",a[i][j]);
else
printf("0%d ",a[i][j]);
}
printf("\n");
}
return 0;
}