Solving a magic square using recursion in C - arrays

Hi I want to make a 3 x 3 magic square in C using backtracking (as in the 4 queens exercise) with recursivity.
In addition, I must enter the maximum value that this magic square will have inside, for example if I enter m = 26, my table should look something like this:
[22,8,21]
[16,17,18]
[13,26,12]
as it should be done by backtracking, that is one possible solution of many, currently I have a simple code of 3 loops to perform all the possible combinations by entering the value of M.
attached code:
#include <stdio.h>
#include <string.h>
#define N 10
void print (int * num, int n)
{
int i;
for (i = 0; i <n; i ++)
printf ("% d", num [i]);
printf ("\ n");
}
int main ()
{
int num [N];
int * ptr;
int temp;
int i, m, j;
int n = 3;
printf ("\ nlimite:");
scanf ("% d", & m);
for (int i = 1; i <= m; ++ i)
{
for (int j = 1; j <= m; ++ j)
{
for (int k = 1; k <= m; ++ k)
{
permutations ++;
printf ("%i,%i,%i\n", i, j, k);
}
}
}
}
How can I transform this code to be recursive? and without repeating the first values, for example [1,1,1] [16,16,16] since this will allow me to create the possible rows and columns to elaborate the magic square.
and finally to be able to print all the possible solutions that are correct.
solution 1 solution N
[4,9,2] [22,8,21]
[3,5,7] [16,17,18]
[8,1,6] ... [13,26,12]
for compilation I use MingGW - gcc on windows, in advance thanks a lot for the help

so, nowhere in your current code do you actually test that the solution is a perfect square. Let's rectify that.
Now this solution is realllllllly slow, but it does show how to advance recursively in this kind of problem.
#include <stdio.h>
void magic_square(int *grid, int next_slot, int max_value) {
// Maybe recurse
if (next_slot < 9) {
for (int i = 1; i < max_value; i++) {
grid[next_slot] = i;
magic_square(grid, next_slot + 1, max_value);
}
// Test magic square.
} else {
const int sum = grid[0] + grid[1] + grid[2];
// Horizontal lines
if (grid[3] + grid[4] + grid[5] != sum) return;
if (grid[6] + grid[7] + grid[8] != sum) return;
// Vertical lines
if (grid[0] + grid[3] + grid[6] != sum) return;
if (grid[1] + grid[4] + grid[7] != sum) return;
if (grid[2] + grid[5] + grid[8] != sum) return;
// Diagonal lines
if (grid[0] + grid[4] + grid[8] != sum) return;
if (grid[2] + grid[4] + grid[6] != sum) return;
// Guess it works
printf("%3d %3d %3d\n%3d %3d %3d\n%3d %3d %3d\n\n",
grid[0], grid[1], grid[2],
grid[3], grid[4], grid[5],
grid[6], grid[7], grid[8]);
}
}
int main(void) {
int grid[9];
int max_value = 5;
magic_square(grid, 0, max_value);
}
You'll also need to add the restriction that no number is used multiple times.

Related

Determine the three maximum and two minimum values of the array

Task:
Given a natural number N (set arbitrarily as a preprocessor constant) and one-dimensional array A0, A1, …, AN-1 of integers (generate positive and negative elements randomly, using the <stdlib.h> library function rand()). Perform the following actions: Determine the three maximum and two minimum values of this array.
Code with search for two minimum values:
#include <stdio.h>
#include <stdlib.h>
#define N 9
int main() {
int M[N], i, a[N], fbig, sbig, tbig, min, smin;
for (i = 0; i < N; i++) {
M[i] = rand() % 20 - 10;
printf("%i\t", M[i]);
}
printf("\n");
for (i = 0; i < N; i++) {
if (a[i] < min) {
smin = min;
min = a[i];
} else
if (a[i] < smin && a[i] != min)
smin = a[1];
}
printf("\nMinimum=%d \nSecond Minimum=%d", min, smin);
return 0;
}
I tried to compare array elements with each other but here is my result:
-7 -4 7 5 3 5 -4 2 -1
Minimum=0
Second Minimum=0
I would be very grateful if you could help me fix my code or maybe I'm doing everything wrong and you know how to do it right. Thank you for your time
I will revise my answer if op address what to do about duplicate values. My answer assume you want possible duplicate values in the minimum and maximum arrays, while other answers assume you want unique values.
The easiest solution would be to sort the input array. The minimum is the first 2 values and the maximum would be the last 3:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_N 3
#define MIN_N 2
#define N 9
void generate(size_t n, int a[n]) {
for(size_t i = 0; i < n; i++)
a[i] = rand() % 20 - 10;
}
void print(size_t n, int a[n]) {
for(size_t i = 0; i < n - 1; i++)
printf("%d, ", a[i]);
if(n) printf("%d\n", a[n-1]);
}
int cmp_asc(const void *a, const void *b) {
if(*(int *) a < *(int *) b) return -1;
if(*(int *) a > *(int *) b) return 1;
return 0;
}
int main() {
int t = time(0);
srand(t);
printf("%d\n", t); // essential for debugging
int a[N];
generate(N, a);
print(N, a);
qsort(a, N, sizeof *a, cmp_asc);
print(MIN_N, a);
print(MAX_N, a + (N - MAX_N));
}
If you cannot use sort then consider the following purpose built algorithm. It's much easier to use arrays (min and max) rather than individual values, and as a bonus this allows you to easily change how many minimum (MIN_N) and maximum (MAX_N) values you want. First we need to initialize the min and max arrays, and I use the initial values of the input array for that. I used a single loop for that. To maintain the invariant that the min array has the MIN_N smallest numbers we have seen so far (a[0] through a[i-1]) we have to replace() largest (extrema) of them if the new value a[i] is smaller. For example, if the array is min = { 1, 10 } and the value we are looking at is a[i] = 5 then we have to replace the 10 not the 1.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_N 3
#define MIN_N 2
#define N 9
void generate(size_t n, int a[n]) {
for(size_t i = 0; i < n; i++)
a[i] = rand() % 20 - 10;
}
void print(size_t n, int a[n]) {
for(size_t i = 0; i < n - 1; i++)
printf("%d, ", a[i]);
if(n) printf("%d\n", a[n-1]);
}
int cmp_asc(const void *a, const void *b) {
if(*(int *) a < *(int *) b) return -1;
if(*(int *) a > *(int *) b) return 1;
return 0;
}
int cmp_desc(const void *a, const void *b) {
return cmp_asc(b, a);
}
void replace(size_t n, int a[n], int v, int (*cmp)(const void *, const void *)) {
int *extrema = &a[0];
for(size_t i = 1; i < n; i++) {
if(cmp(extrema, &a[i]) < 0) {
extrema = &a[i];
}
}
if(cmp(extrema, &v) > 0)
*extrema = v;
}
void min_max(size_t n, int a[n], size_t min_n, int min[n], size_t max_n, int max[n]) {
for(size_t i = 1; i < n; i++) {
if(i < min_n)
min[i] = a[i];
else
replace(min_n, min, a[i], cmp_asc);
if(i < max_n)
max[i] = a[i];
else
replace(max_n, max, a[i], cmp_desc);
}
}
int main() {
int t = time(0);
srand(t);
printf("%d\n", t); // essential for debugging
int a[N];
generate(N, a);
print(N, a);
int min[MIN_N];
int max[MAX_N];
min_max(N, a, MIN_N, min, MAX_N, max);
print(MIN_N, min);
print(MAX_N, max);
}
and here is example output. The first value is a the seed in case you have to reproduce a run later. Followed by input, min and max values:
1674335494
-7, 0, -2, 7, -3, 4, 5, -8, -9
-9, -8
7, 5, 4
If MIN_N or MAX_N gets large, say, ~1,000+, then you want sort the min and max arrays and use binary search to figure out where to inserta[i]. Or use a priority queue like a heap instead of arrays.
There are multiple problems in your code:
min and smin are uninitialized, hence the comparisons in the loop have undefined behavior and the code does work at all. You could initialize min as a[0] but initializing smin is not so simple.
there is a typo in smin = a[1]; you probably meant smin = a[i];
Note that the assignment is somewhat ambiguous: are the maximum and minimum values supposed to be distinct values, as the wording implies, or should you determine the minimum and maximum elements of the sorted array?
For the latter, sorting the array, either fully or partially, is a simple solution.
For the former, sorting is also a solution but further testing will be needed to remove duplicates from the sorted set.
Here is a modified version to print the smallest and largest values:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 9
#define N_MIN 2
#define N_MAX 3
void swap(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
int main() {
int a[N], i, j, e, dup;
int smallest[N_MIN], nsmall = 0;
int largest[N_MAX], nlarge = 0;
srand(time(NULL));
for (i = 0; i < N; i++) {
a[i] = rand() % 20 - 10;
printf("%i\t", a[i]);
}
printf("\n");
for (i = 0; i < N; i++) {
e = a[i];
dup = 0;
for (j = 0; j < nsmall; j++) {
if (e == smallest[j]) {
dup = 1;
break;
}
if (e < smallest[j]) {
swap(&e, &smallest[j]);
}
}
if (!dup && nsmall < N_MIN) {
smallest[nsmall++] = e;
}
e = a[i];
dup = 0;
for (j = 0; j < nlarge; j++) {
if (e == largest[j]) {
dup = 1;
break;
}
if (e > largest[j]) {
swap(&e, &largest[j]);
}
}
if (!dup && nlarge < N_MAX) {
largest[nlarge++] = e;
}
}
printf("smallest values: ");
for (i = 0; i < nsmall; i++) {
printf(" %d", smallest[i]);
}
printf("\n");
printf("largest values: ");
for (i = nlarge; i --> 0;) {
printf(" %d", largest[i]);
}
printf("\n");
return 0;
}
As already noted, the most direct way to do this would be to simply sort the array. (In fact, if all you need is an output of five integers then your array only need be five elements long.) But I will presume that that is not the point of this homework.
Your goal isn’t super efficiency or a pretty algorithm. It is simply to solve the tasks. Do them one at a time.
First question: How would you find the largest value?
Answer: Loop through the array, keeping track of the largest element found so far.
int largest = array[0]; // why start with this value?
for (int n = 0; n < size; n++)
if (array[n] > largest)
largest = array[n];
Second question: How would you find the smallest value?
Answer: Almost the same way, with only a simple change: Instead of testing if (array[n] > largest) we want to test if (array[n] < smallest), right?
int smallest = largest; // why start with this value?
for (int n = 0; n < size; n++)
if (...) // new condition goes here
smallest = array[n];
Third question: How would you find the second smallest value?
Answer: It should not surprise you that you just need to change the if condition in that loop again. An element would be the second smallest if:
it is the smallest value greater than the smallest.
Think about how you would change your condition:
int second_smallest = largest; // why start with this value?
for (int n = 0; n < size; n++)
if (... && ...) // what is the new test condition?
second_smallest = array[n];
Remember, this time you are testing two things, so your test condition needs that && in it.
Fourth question: can you write another loop to find the second-largest? How about the third-largest?
At this point you should be able to see the variation on a theme and be able to write a loop that will get you any Nth largest or smallest value, as long as you already have the (N-1)th to work against.
Further considerations:
Is it possible that the third-largest is the same as the second-smallest?
Or the smallest?
Is it possible for there to not be a third-largest?
Does it matter?
Put all these loops together in your main() and print out the results each time and you are all done!
...
int main(void)
{
int array[SIZE];
// fill array with random numbers here //
int largest = array[0];
for (...)
if (...)
...
int smallest = largest;
for (...)
if (...)
...
int second_smallest = largest;
for (...)
if (...)
...
int second_largest = smallest;
for (...)
if (...)
...
int third_largest = smallest;
for (...)
if (...)
...
printf( "The original array = " );
// print original array here, then: //
printf( "largest = %d\n", largest );
printf( "2nd largest = %d\n", second_largest );
printf( "3nd largest = %d\n", third_largest );
printf( "2nd smallest = %d\n", second_smallest );
printf( "smallest = %d\n", smallest );
return 0;
}
Example outputs:
{ 1 2 3 4 }
smallest = 1
2nd smallest = 2
3rd largest = 2
2nd largest = 3
largest = 4
{ 5 5 5 5 5 }
smallest = 5
2nd smallest = 5
3rd smallest = 5
largest = 5
{ 1 2 }
smallest = 1
2nd smallest = 2
3rd smallest = 2
largest = 2
Bonus: be careful with variable names. There has been no need to use short abbreviations since before the early nineties. Prefer clarity over brevity.

N QUEENS problems

I try to solve the problem of N queens solution and manage to create an algorithm that gives me all possibilities and prints it (I try to understand everything but as backtracking is a little new to me, it is hard).
My program looks at every possibility and prints the position of the queens one by colones, it looks like it works well, even if I don't understand my stopping condition.
My problem is that I need to print the position in a certain a order (start from first queen position 0 - N), but it prints in a random way.
I could store it in an array and sort it, but it will take too much time, so i would like to know if people can look at my code and point out possible problems and give some tips or feedback.
#include <unistd.h>
#include <stdio.h>
#define N 10
void print(int tab[N][N])
{
int i;
int a;
char c;
i = -1;
while (++i < N)
{
a = -1;
while (++a < N)
if (tab[a][i])
{
c = '0' + a;
write(1, &c, 1);
}
}
write(1, "\n", 1);
}
int check(int tab[N][N] , int x, int y)
{
int i;
int j;
i = 0;
while (i < x)
if (tab[i++][y])
return (0);
i = x;
j = y;
while (j >= 0 && i >= 0)
if (tab[i--][j--])
return (0);
i = x;
j = y;
while (i >= 0 && j < N)
if (tab[i--][j++])
return (0);
return (1);
}
int backtrack(int tab[N][N],int x ,int y, int *nbr)
{
if (x >= N)
{
print(tab);
*nbr += 1;
}
while (++y < N)
if (check(tab, x, y))
{
tab[x][y] = 1;
if (backtrack(tab, x + 1, -1, nbr))
return (1);
tab[x][y] = 0;
}
return (0);
}
int ft_ten_queens_puzzle(void)
{
int tab[N][N];
int nbr;
int b;
nbr = -1;
while(++nbr < N)
{
b = -1;
while (++b < N)
tab[nbr][b] = 0;
}
nbr = 0;
backtrack(tab,0,-1, &nbr);
return (nbr);
}
int main()
{
printf("%d\n",ft_ten_queens_puzzle());
}
Your output is coming out random due to a couple of bugs in your print function :
a) If you are printing out a grid, then EVERY cell must be output, but you are not printing cells where tab[a][i] is 0
b) You need a newline at the end of EVERY line, but your write statement is in the wrong place
So the function should be like :
void print(int tab[N][N])
{
char c;
for (int i=0; i < N; i++)
{
for (int a=0; a < N; a++)
{
if (tab[a][i])
{
c = '0' + a;
}
else
{
c = ' ';
}
write(1, &c, 1);
}
write(1, "\n", 1);
}
}
A couple of tips/feedback :
Use full easy-to-understand variable names.
Don't use that awkward "int x = -1; while (++x < N) {" format - the standard for (int x=0; x < N; x++) { format is better
Indent your code correctly. for example, in print, you had the write for the newline out side of it's intended loop, which was easily missed due to indentation issues
Yes, the language allows you to skip the "{","}" for single-statement loops and if statements. I would STRONGLY recommend to never skip them, but always put them on all loops and ifs; It is so much easier to both prevent, and also to track down bugs (especially when indentation is not consistent)
Just my thoughts, I hope they help :)

Optimizing Conway's Game of life

I'm working on speeding up Conway's Game of Life. Right now, the code looks at a cell and then adds up the 3x3 area immediately surrounding the point, then subtracts the value at the point we're looking at. Here's the function that is doing that:
static int neighbors2 (board b, int i, int j)
{
int n = 0;
int i_left = max(0,i-1);
int i_right = min(HEIGHT, i+2);
int j_left = max(0,j-1);
int j_right = min(WIDTH, j+2);
int ii, jj;
for (jj = j_left; jj < j_right; ++jj) {
for (ii = i_left; ii < i_right; ii++) {
n += b[ii][jj];
}
}
return n - b[i][j];
}
And here is the code I've been trying to use to iterate through pieces at a time:
//Iterates through the first row of the 3x3 area
static int first_row(board b, int i, int j) {
int f = 0;
int i_left = max(0,i-1);
int j_left = max(0,j-1);
int j_right = min(WIDTH, j+2);
int jj;
for (jj = j_left; jj < j_right; ++jj) {
f += b[i_left][jj];
}
return f;
}
//Iterates and adds up the second row of the 3x3 area
static int second_row(board b, int i, int j) {
int g = 0;
int i_right = min(HEIGHT, i+2);
int j_left = max(0,j-1);
int j_right = min(WIDTH, j+2);
int jj;
if (i_right != i) {
for (jj = j_left; jj < j_right; ++jj) {
g += b[i][jj];
}
}
return g;
}
//iterates and adds up the third row of the 3x3 area.
static int third_row(board b, int i, int j) {
int h = 0;
int i_right = min(HEIGHT, i+2);
int j_left = max(0,j-1);
int j_right = min(WIDTH, j+2);
int jj;
for (jj = j_left; jj < j_right; ++jj) {
h += b[i_right][jj];
}
return h;
}
//adds up the surrounding spots
//subtracts the spot we're looking at.
static int addUp(board b, int i, int j) {
int n = first_row(b, i, j) + second_row(b, i, j) + third_row(b, i, j);
return n - b[i][j];
}
But, for some reason it isn't working. I have no idea why.
Things to note:
sometimes i == i_right, so we do not want to add up a row twice.
The three functions are supposed to do the exact same thing as neighbors2 in separate pieces.
min and max are functions that were premade for me.
sometimes sometimes j == j_right, so we do not want to add up something twice. I'm pretty confident the loop takes care of this however.
Tips and things to consider are appreciated.
Thanks all. I've been working on this for a couple hours now and have no idea what is going wrong. It seems like it should work but I keep getting incorrect solutions at random spots among the board.
In neighbors2, you set i_left and i_right so that the're limited to the rows of the grid. If the current cell is in the top or bottom row, you only loop through two rows instead of 3.
In first_row() and last_row() you also limit it to the rows of the grid. But the result is that these functions will add the cells on the same row as the current cell, which is what second_row does. So you end up adding those rows twice.
You shouldn't call first_row() when i = 0, and you shouldn't call third_row() when i == HEIGHT.
static int addUp(board b, int i, int j) {
int n = (i == 0 ? 0 : first_row(b, i, j)) +
second_row(b, i, j) +
(i == HEIGHT ? 0 : third_row(b, i, j));
return n - b[i][j];
}
Another option would be to do the check in the functions themselves:
function first_row((board b, int i, int j) {
if (i == 0) {
return 0;
}
int f = 0;
int j_left = max(0,j-1);
int j_right = min(WIDTH, j+2);
int jj;
for (jj = j_left; jj < j_right; ++jj) {
f += b[i][jj];
}
return f;
}
and similarly for third_row(). But doing it in the caller saves the overhead of the function calls.
BTW, your variable names are very confusing. All the i variables are for rows, which go from top to bottom, not left to right.
#include <stdio.h>
#include <stdlib.h>
#define ROWSDISP 50
#define COLSDISP 100
int rows=ROWSDISP+2, cols=COLSDISP+2;
This is to avoid illegal indexes when stepping over the neighbours.
struct onecell {char alive;
char neibs;} **cells;
This is the foundation of a (dynamic) 2D-array, of a small struct.
To create space for each row plus the space to hold an array of row pointers:
void init_cells()
{
int i;
cells = calloc(rows, sizeof(*cells));
for(i=0; i<=rows-1; i++)
cells[i] = calloc(cols, sizeof(**cells));
}
I skip the rand_fill() and glider() funcs. A cell can be set by
cells[y][x].alive=1.
int main(void) {
struct onecell *c, *n1, *rlow;
int i, j, loops=0;
char nbs;
init_cells();
rand_fill();
glider();
while (loops++ < 1000) {
printf("\n%d\n", loops);
for (i = 1; i <= rows-2; i++) {
for (j = 1; j <= cols-2; j++) {
c = &cells[ i ][ j ];
n1 = &cells[ i ][j+1];
rlow = cells[i+1];
nbs = c->neibs + n1->alive + rlow[ j ].alive
+ rlow[j+1].alive
+ rlow[j-1].alive;
if(c->alive) {
printf("#");
n1->neibs++;
rlow[ j ].neibs++;
rlow[j+1].neibs++;
rlow[j-1].neibs++;
if(nbs < 2 || nbs > 3)
c->alive = 0;
} else {
printf(" ");
if(nbs == 3)
c->alive = 1;
}
c->neibs = 0; // reset for next cycle
}
printf("\n");
}
}
return(0);
}
There is no iterating a 3x3 square here. Of the 8 neighbours,
only the 4 downstream ones are checked; but at the same time
their counters are raised.
A benchmark with 100x100 grid:
# time ./a.out >/dev/null
real 0m0.084s
user 0m0.084s
sys 0m0.000s
# bc <<<100*100*1000/.084
119047619
And each of these 100M cells needs to check 8 neighbours, so this is close to the CPU frequency (1 neighbour check per cycle).
It seems twice as fast as the rosetta code solution.
There also is no need to switch the boards. Thanks to the investment in the second field of a cell.

BUS Error : 10 While compiling C program

I am working on a class project to solve the wandering Salesman problem, which is basically the TSP, except you don't return to the source. I took the approach of finding all possible permutations of a set of vertices and then iteratively calculating the length and comparing them to find the smallest. I know it's not the best approach, but its what our professor wanted.
When I run the code below, it works fine and gives me the right answers when the input array is less than 7 X 7. But when its 7 X 7, it returns "Bus Error: 10", and if the size is 12 x 12, it returns "Segmentation Fault : 11". I looked up these problems for hours and couldn't figure out what's wrong. I'm not much of an expert in C programming, and I'm honestly really confused with pointers. Thank you so much for the help, I appreciate it greatly!
Oh, and sorry about the messy code.
#include <stdio.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include<stdlib.h>
int x = 0;
int a[];
void swap (int v[], int i, int j) {
int t;
t = v[i];
v[i] = v[j];
v[j] = t;
}
/* recursive function to generate permutations */
int* perm (int v[], int n, int i) {
/* this function generates the permutations of the array
* from element i to element n-1
*/
int j;
/* if we are at the end of the array, we have one permutation
* we can use (here we print it; you could as easily hand the
* array off to some other function that uses it for something
*/
if (i == n) {
for (j=0; j<n; j++){ a[x] = v[j]; x++;} // printf ("%d ", v[j]);
// printf ("\n");
}
else
/* recursively explore the permutations starting
* at index i going through index n-1
*/
for (j=i; j<n; j++) {
/* try the array with i and j switched */
swap (v, i, j);
perm (v, n, i+1);
/* swap them back the way they were */
swap (v, i, j);
}
return a;
}
int fact(int n){
if(n==1){
return 1;
}
else{
return n * fact(n-1);
}
}
int findShortestPath(int **v , int length){
int pathArrayMultiplier = 0;
int ShortestPathLength = 99999;
printf("Called");
int arrayOfVertices[length-1];
for(int i=0 ; i<length-1 ; i++){
arrayOfVertices[i] = i+2;
}
int n = fact(length-1);
bool doBreak = false;
int pathArray[length-1];
//printf(" Called 3");
printf(" %d" , n);
int* Answer;
Answer = malloc(sizeof(int *));
Answer = perm(arrayOfVertices , length-1 , 0);
printf("Called 4");
int j =-1;
for(int i=0 ; i< n*(length-1) ; i++){
doBreak = false;
j++;
printf("%d " , *(Answer + i));
pathArray[j] = *(Answer+i);
if(j == length-2)
{
j = -1;
// Check for negative values. If any value is negative, disregard path
int checklength = *((int *)v + 0 *length + (pathArray[0]-1));
if(checklength < 0){
printf("First check called");
continue;}
for(int i =0 ; i<length-2 ; i++){
if(*((int *)v + (pathArray[i]-1) * length + (pathArray[1 + i]-1)) < 0){
doBreak = true;
printf("Second Check called");
break;}
}
if(doBreak) { pathArrayMultiplier++; continue;}
printf("\n");
int pathLength = *((int *)v + 0 *length + (pathArray[0]-1));
for(int i =0 ; i<length-2 ; i++){
pathLength = pathLength + *((int *)v + (pathArray[i]-1) * length + (pathArray[1 + i]-1));}
printf("Path Length is %d\n" , pathLength);
if(pathLength < ShortestPathLength) { ShortestPathLength = pathLength;}
}
}
printf("\n\n Shortest Path Length is %d \n" , ShortestPathLength);
return ShortestPathLength;
}
int main () {
int len = 5;
printf("Array is initialized");
int v[7][7] = {0,7,-1,10,1,-1,-1,7,0,-1,-1,10 ,-1 ,1,-1,-1,0,10,1,10,-1,10,-1,10, 0,8,-1,-1,-1,10,1,8,0,10,-1,-1,-1,10,-1,10,0,70,-1,1,-1,-1,-1, 70 , 0};
printf("Array is initialized");
int **realArrayPointer = v;
findShortestPath(realArrayPointer, 7);
return 0;
}
Your code is a mess and practically unreadable. However, I took it upon myself as a challenge to see if I could spot your bug. What I saw is that you declare an empty array at the top:
int a[];
and then you write to this array:
a[x] = v[j];
x++;
You never even reset x back to 0, anywhere. So basically, right from the start you are writing to unallocated memory, but the bigger your input set, the more unallocated memory you write to.
There could be other problems with your code. I definitely saw a whole bunch of other things that indicated an incorrect understanding of pointers, but they wouldn't necessarily cause a fatal error. Please at the very least get some kind of auto-indent program to make your code readable.

Print the Cantor Set using recursion in C

I'm trying to print the Cantor Set to the console using 'x', but I'm stuck at the 2nd recursion which no matter what I do, just doesn't execute.
The Idea is to first initialize the matrix using clearP() so I don't have to worry about the whitespaces. After that I load the array with 'x' chars using the depth as a [y] value.
To remove the middle segment on each line I use secondLength and smallerLength. Now the reason to use 2 recursive calls is, that for example on depth 1 it removes the middle part once, on depth 2 twice, on depth 3 four times and so on. However I just can't get the 2nd recursion to execute, which is why my output looks like this.
Any advice where I'm making mistakes?
#include <stdio.h>
#include <math.h>
#define WIDTH 27
#define HEIGHT (int)(cbrt(WIDTH)+1)
void clearP(char p[WIDTH][HEIGHT]){
int x, y;
for(x = 0; x<WIDTH; x++){
for (y=0;y<HEIGHT;y++){
p[x][y] = ' ';
}
}
}
void printP(char p[WIDTH][HEIGHT]){
int x, y;
for(y = 0; y<HEIGHT; y++){
for (x=0;x<WIDTH;x++){
printf("%c",p[x][y]);
}
printf("\n");
}
}
void cantor(char p[WIDTH][HEIGHT],int start,int end, int depth){
int smallerLength = end / 3;
int secondStart = start + (smallerLength * 2);
for (int x = start; x<end ; x++){
p[x][depth] = 'x';
}
if (depth == HEIGHT){
return;
}
cantor(p, start, smallerLength, depth+1);
cantor(p, secondStart, smallerLength, depth+1);
}
int main(){
char canvas[WIDTH][HEIGHT];
clearP(canvas);
cantor(canvas, 0, WIDTH, 0);
printP(canvas);
}
I think you got your height and width mixed up in print.
try this
void printP(char p[WIDTH][HEIGHT]){
int x, y;
for(x = 0; x<HEIGHT; x++){
for (y=0;y<WIDTH;y++){
printf("%c",p[x][y]);
}
printf("\n");
}
}
A point in [0, 1] is in the Cantor set if it's ternary representation doesn't contain any 1's (that is, only 0's and 2's). This observation allows you to output the d-level representation by looking at the first d digits of the fractional part of i/n in base 3, without needing arrays.
#include <stdio.h>
void cantor(int n, int d) {
for (int i = 0; i < n; i++) {
int in = 1;
int x = i;
for (int j = 0; j < d; j++) {
in = in && !(3*x >= n && 3*x < 2*n);
x = (3*x)%n;
}
putchar(in ? 'x' : ' ');
}
putchar('\n');
}
int main(int argc, char *argv[]) {
for (int d = 0; d < 5; d++) {
cantor(81, d);
}
return 0;
}

Resources