Skip to content

Instantly share code, notes, and snippets.

@ryukzak
Created June 1, 2011 21:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ryukzak/1003337 to your computer and use it in GitHub Desktop.
Save ryukzak/1003337 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
struct List {
struct List *next;
int value;
};
struct List* makeList(int all, int inLoop) {
struct List *head = malloc(sizeof(struct List));
struct List *current = head;
int marker = 1;
for (int i = 0; i < all - inLoop; ++i) {
current = current->next = malloc(sizeof(struct List));
current->value = marker++;
}
if (inLoop > 0) {
struct List *loopStart = current;
for (int i = 0; i < inLoop; ++i) {
current = current->next = malloc(sizeof(struct List));
current->value = marker++;
}
current->next = loopStart->next;
}
return head;
}
typedef struct ReturnValue (* RecurFunction) (void *);
struct ReturnValue {
RecurFunction function;
void * value;
};
void * recur(RecurFunction function, void * input) {
struct ReturnValue tmp;
tmp.value = input;
tmp.function = function;
do {
tmp = tmp.function(tmp.value);
} while (tmp.function != NULL);
return tmp.value;
}
// Тип входных данных.
struct RecurFactorial {
int n, acc;
};
struct ReturnValue factorial(void * input) {
struct RecurFactorial * args = input; // Приведение типа данных.
struct ReturnValue result;
result.value = input; // Входные и результируещие данный одни и теже.
if (args->n == 1) {
// Функция на следующий запуск не устанавливается для завершения вычислений.
result.function = NULL;
} else {
// Формируем результаты итерации.
args->acc *= args->n;
args->n -= 1;
// Устанвливаем функцию на следующий запуск.
result.function = factorial;
}
return result;
}
struct RecurLoopInList {
struct List * fastMarker, * slowMarker;
};
struct ReturnValue slowMarker(void * input);
struct ReturnValue fastMarker(void * input);
bool loopInList(struct List *head) {
struct RecurLoopInList args;
args.fastMarker = head->next;
args.slowMarker = head;
bool * resultP = recur(fastMarker, (void*)&args);
bool result = *resultP;
free(resultP);
return result;
}
struct ReturnValue slowMarker(void * input) {
struct RecurLoopInList * args = input;
struct ReturnValue result;
result.value = input;
args->slowMarker = args->slowMarker->next;
result.function = fastMarker;
return result;
}
struct ReturnValue fastMarker(void * input) {
struct RecurLoopInList * args = input;
struct ReturnValue result;
if (args->fastMarker->next == NULL ||
args->fastMarker->next->next == NULL) {
bool * ans = malloc(sizeof(bool));
*ans = false;
result.value = (void*)ans;
result.function = NULL;
} else if (args->fastMarker->next == args->slowMarker ||
args->fastMarker->next->next == args->slowMarker) {
bool * ans = malloc(sizeof(bool));
*ans = true;
result.value = (void*)ans;
result.function = NULL;
} else {
args->fastMarker = args->fastMarker->next->next;
result.value = (void*)input;
result.function = slowMarker;
}
return result;
}
int main(int argc, char** argv) {
struct RecurFactorial fac;
fac.n = 5;
fac.acc = 1;
recur(factorial, (void *)&fac);
printf("factorial result: %d\n", fac.acc);
struct List * head = makeList(10, 5);
printf("loopInList: %s\n", loopInList(head) ? "true" : "false");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment