TheAlgorithms-C/misc/cantor_set.c

124 lines
2.9 KiB
C
Raw Normal View History

2020-06-30 20:38:36 +03:00
/**
* @file
* @brief Program to generate [Cantor ternary
2020-06-30 20:38:36 +03:00
* set](https://en.wikipedia.org/wiki/Cantor_set)
*/
2019-10-01 08:11:58 +03:00
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
2020-06-30 20:38:36 +03:00
/** structure to define Cantor set */
typedef struct _cantor_set
2019-10-01 08:11:58 +03:00
{
double start; /**< start of interval */
double end; /**< end of interval */
struct _cantor_set *next; /**< pointer to next set */
} CantorSet;
2020-06-30 20:38:36 +03:00
/** Iterative constructor of all sets in the current level. This function
* dynamically allocates memory when creating new sets. These are freed by the
* function ::free_memory.
* @param head pointer to interval set instance to update
*/
void propagate(CantorSet *head)
2019-10-01 08:11:58 +03:00
{
2020-06-30 20:38:36 +03:00
// if input is NULL, ignore the process
if (head == NULL)
2020-06-30 20:38:36 +03:00
return;
2019-10-01 08:11:58 +03:00
CantorSet *temp = head; // local pointer to track propagation
2019-10-01 08:11:58 +03:00
2020-06-30 20:38:36 +03:00
// create new node for the new set
CantorSet *newNode = (CantorSet *)malloc(sizeof(CantorSet));
2019-11-04 14:26:45 +03:00
2020-06-30 20:38:36 +03:00
// get 1/3rd of interval
double diff = (((temp->end) - (temp->start)) / 3);
2019-11-04 14:26:45 +03:00
2020-06-30 20:38:36 +03:00
// update interval ranges
newNode->end = temp->end;
temp->end = ((temp->start) + diff);
newNode->start = (newNode->end) - diff;
2019-11-04 14:26:45 +03:00
2020-06-30 20:38:36 +03:00
// update pointer to next set in this level
newNode->next = temp->next;
2019-10-01 08:11:58 +03:00
2020-06-30 20:38:36 +03:00
// point to next set
temp->next = newNode;
// create next set
propagate(temp->next->next);
2019-10-01 08:11:58 +03:00
}
2020-06-30 20:38:36 +03:00
/** Print sets in the current range to `stdout`
* @param head pointer to first set in the current level
*/
void print(CantorSet *head)
2019-10-01 08:11:58 +03:00
{
CantorSet *temp = head;
2020-06-30 20:38:36 +03:00
while (temp != NULL) // print while a valid set is found
{
printf("\t");
printf("[%lf] -- ", temp->start);
printf("[%lf]", temp->end);
temp = temp->next;
}
2019-10-01 08:11:58 +03:00
printf("\n");
2019-11-04 14:26:45 +03:00
}
2019-10-01 08:11:58 +03:00
2020-06-30 20:38:36 +03:00
/** Clear memory allocated by ::propagate function.
* @param head pointer to first allocated instance.
*/
void free_memory(CantorSet *head)
2019-10-01 08:11:58 +03:00
{
2020-06-30 20:38:36 +03:00
if (!head)
return;
if (head->next)
free_memory(head->next);
free(head);
}
2020-06-30 20:38:36 +03:00
/** Main function */
int main(int argc, char const *argv[])
{
int start_num, end_num, levels;
if (argc < 2)
{
printf("Enter 3 arguments: start_num \t end_num \t levels\n");
scanf("%d %d %d", &start_num, &end_num, &levels);
}
else
{
start_num = atoi(argv[1]);
end_num = atoi(argv[2]);
levels = atoi(argv[3]);
}
2020-06-30 20:38:36 +03:00
if (start_num < 0 || end_num < 0 || levels < 0)
{
fprintf(stderr, "All numbers must be positive\n");
return -1;
}
CantorSet head = {.start = start_num, .end = end_num, .next = NULL};
2020-06-30 20:38:36 +03:00
// loop to propagate each level from top to bottom
for (int i = 0; i < levels; i++)
{
printf("Level %d\t", i);
2020-06-30 20:38:36 +03:00
print(&head);
propagate(&head);
printf("\n");
}
printf("Level %d\t", levels);
2020-06-30 20:38:36 +03:00
print(&head);
// delete all memory allocated
free_memory(head.next);
return 0;
2019-11-04 14:26:45 +03:00
}