Print the Cantor Set using recursion in C - 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;
}

Related

How to count occurrences of duplicates in array using binary search in C?

I must count the occurrence of an element in the array using binary search in C.
I have written the following code but when I use to give an input
Then the output is wrong. I have also tried to predefine the elements in the array & use this code and it works fine. But when I give custom input using scanf statement then the program does not omit the right ans. I have been implementing it in C for hours now. Any help/suggestions would be greatly appreciated.
#include <stdio.h>
int fun(int array[], int s, int x, int key)
{
int ss = 0, e = s - 1;
int n = -1;
while (ss <= e)
{
int middle = (ss + e)/2;
if (x == array[middle]){
n = middle;
if (key){
e = middle - 1;
}
else{
ss = middle + 1;
}
}
else if (x < array[middle]){
e = middle - 1;
}
else{
ss = middle + 1;
}
}
return n;
}
int main()
{
int s;
scanf("%d",&s);
int array[s];
for(int i = 0 ; i<s ; i++){
scanf("%d",&array[i]);
}
for(int i = 0 ; i<s;i++){
printf("%d ",array[i]);
}
printf("\n");
int x;
scanf("%d",&x);
int f = fun(array, s, x, 1);
int l = fun(array, s, x, 0);
int t = l - f + 1;
if (f!= -1){
printf("%d ", t);
}
return 0;
}
You can not use binary search to locate data in unsorted array. The elements must be in increasing order for the binary search work. You can use 'qsort' to sort the array in the program, or modify the input to be sorted.
If you modify the input array to: [1 4 5 5 7] , the output will be: 2

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 :)

Optimization of program processing structured input for large data

I have this one task. To make it more clear, I am gonna use picture below as an example. Input and output is separated with dotted line. First line of input is number N - number of sets. For every set, it's first line are 2 numbers - first one declares how many numbers am I gonna process and second one is number of intervals. Second line specifies the numbers to process and third line contains 2 numbers X and Y, which create and interval. For every interval I have to output 3 numbers - lowest number on interval, index of highest number on interval and XOR of all numbers. Everything is running fine except it is really slow for big data and I have no idea how to make work faster. I have attached my code and large data input as well.
input.txt
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int id;
int index;
} Censor;
int Xor(const int x, const int y, const Censor array[]) {
int xor = array[x].id;
if (x == y) {
return xor;
}
for (int i = x + 1; i <= y; i++) {
xor ^= array[i].id;
}
return xor;
}
int int_cmp(const void *a, const void *b) {
const Censor *ia = (const Censor *)a;
const Censor *ib = (const Censor *)b;
return (ia->id - ib->id);
}
int LowestId(const int x, const int y, Censor array[]) {
int id = array[x].id;
if (x == y) {
return id;
}
qsort(array, y - x + 1, sizeof(Censor), int_cmp);
return array[0].id;
}
int HighestIdIndex(const int x, const int y, Censor array[]) {
int index = array[x].index;
if (x == y) {
return index;
}
qsort(array, y - x + 1, sizeof(Censor), int_cmp);
return array[y].index;
}
int main() {
int t, n, q, b, e;
int max = 100;
int count = 0;
int *output = (int *)malloc(max * sizeof(output));
scanf("%d", &t); //number of sets
for (int i = 0; i < t; i++) {
scanf("%d %d", &n, &q);
//I am making 3 separate arrays for numbers, because some of them are being sorted and some of them not
Censor lowest_id[n];
Censor highest_id_index[n];
Censor xor[n];
//This loop fills arrays with the numbers to be processed
for (int j = 0; j < n; j++) {
scanf("%d", &(lowest_id[j].id));
lowest_id[j].index = j;
highest_id_index[j].id = lowest_id[j].id;
highest_id_index[j].index = j;
xor[j].id = lowest_id[j].id;
xor[j].index = j;
}
// Now I am scanning intervals and creating output. Output is being stored in one dynamically allocated array.
for (int k = 0; k < q; k++) {
scanf("%d %d", &b, &e);
if (count + 3 >= max) {
max *=2;
int *tmp = (int *)realloc(output, max * sizeof(tmp));
if (tmp == NULL) {
return 1;
} else {
output = tmp;
}
}
output[count++] = LowestId(b, e, lowest_id);
output[count++] = HighestIdIndex(b, e, highest_id_index);
output[count++] = Xor(b, e, xor);
}
}
printf("---------------------\n");
for (int i = 0; i < count; i++) {
printf("%d\n", output[i]);
}
free(output);
return 0;
}
Thanks #Dan Mašek and #Alex Lop. Sorting subarray in this case was unnecessary. Much easier is to iterate through the subarray in linear complexity.

Can a nested for loop in C recursively increase in depth times a user given integer?

I would like to avoid a nested for loop since it should recursively increase in depth by a user given integer.
So if the user input 3 it should be nested like the example below.. if the user input 6 there should be three more loops inside!?
#include <stdio.h>
int main(void)
{
// int depth_lvl = 3
char n[] = {'a','b','c'};
int i,j,y;
int x = sizeof(n);
for(i = 0; i < x; i++)// <---- LEVEL 1
{
printf("%c\n",n[i]);
for(j = 0; j < x; j++)// <---- LEVEL 2
{
printf("%c%c\n",n[i],n[j]);
for(y = 0; y < x; y++) // <---- LEVEL 3
{
printf("%c%c%c\n",n[i],n[j],n[y]);
}
}
}
}
Is it something like that what you are looking for?
The solution uses recursion together with an intermediate result string at each level, with which each state of the current level is carried over to the next deeper level.
#define MAX_DEPTH 6
void printRecursive(char n[], int x, int curDepth, char* result)
{
// note: x is supposed to be sizeof(n).
if (x > MAX_DEPTH) // prohibit overflow of intermediateResult
x = MAX_DEPTH;
if (curDepth < x) {
char intermediateResult[MAX_DEPTH+1];
if (result)
strcpy(intermediateResult,result);
else
strcpy(intermediateResult, "");
for (int i=0;i<x;i++) {
intermediateResult[curDepth] = n[i];
intermediateResult[curDepth+1] = '\0';
printRecursive(n,x,curDepth+1,intermediateResult);
}
}
if (curDepth > 0)
printf("%s\n", result);
}
int main(void)
{
char n[] = {'a','b','c', 'd'};
int x = sizeof(n);
printRecursive(n, x, 0, NULL);
return 0;
}

UVA problems 12503 gives TLE

I am trying to solve 12503 problem on UVA online judge. I think I have figured out the solution, but it gives me TLE. Here is the problem :
You have a robot standing on the origin of x axis. The robot will be given some instructions.
Your task is to predict its position after executing all the instructions.
• LEFT: move one unit left (decrease p by 1, where p is the position of the robot before moving)
• RIGHT: move one unit right (increase p by 1)
• SAME AS i: perform the same action as in the i-th instruction. It is guaranteed that i is a positive
Input
integer not greater than the number of instructions before this.
The first line contains the number of test cases T (T <= 100). Each test case begins with an integer n (1 <= n <= 100), the number of instructions. Each of the following n lines contains an instruction.
Output
For each test case, print the final position of the robot. Note that after processing each test case, the
robot should be reset to the origin.
Sample Input
2
3
LEFT
RIGHT
SAME AS 2
5
LEFT
SAME AS 1
SAME AS 2
SAME AS 1
SAME AS 4
Sample Output
1
-5
Here is my code in C:
#include <stdio.h>
char com[102][20];
int command(char comd[], int pos);
int main() {
int t;
int pos;
int i, n;
char tmp[20];
scanf("%d", &t);
for(i = 0; i < t; i++) {
scanf("%d", &n);
int j;
pos = 0;
for (j = 0; j < n; j++) {
gets(com[j]);
if (strcmp(com[j], "LEFT") == 0)
pos--;
else if(strcmp(com[j], "RIGHT") == 0)
pos++;
else {
pos = command(com[j], pos);
}
}
printf("%d\n", pos);
}
return 0;
}
int command(char comd[], int pos) {
if (strcmp(comd, "LEFT") == 0) {
pos--;
return pos;
}
else if (strcmp(comd, "RIGHT") == 0) {
pos++;
return pos;
}
else{
int a = atoi(&comd[8]);
return command(com[a-1], pos);
}
}
Is there any suggestion why this code gives TLE ?
In the int command(char comd[], int pos) function, you are using recursive call at the last line. This may lead to TLE.
To solve this problem you can use another array to store the number of steps taken by the robot at a command. You just have to access the index of the array later to get step at a previous command.
Here is how I would do it-
#include <stdio.h>
#include <string.h>
int move[110];
int getMove(char inp[], int);
int main()
{
int t, n;
char inp[50];
scanf(" %d ",&t);
while(t--)
{
scanf(" %d ",&n);
int i, pos = 0;
for(i = 0; i < n; i++)
{
gets(inp);
pos += getMove(inp, i);
}
printf("%d\n",pos);
}
return 0;
}
int getMove(char inp[], int i)
{
if(inp[0]=='S')
{
int j;
sscanf(strrchr(inp,' ')," %d",&j);
move[i] = move[j - 1];
}
else
{
move[i] = (inp[0] == 'L') ? -1 : 1;
}
return move[i];
}

Resources