Achtung: Bei Parametern jenseits von (4, 1) bzw. (3.13) geht das Ding natuerlich baden, weil die Zahlen einfach zu gross werden, und auf libgmp hatte ich keine Lust.
#include <err.h> #include <stdio.h> #include <stdlib.h> #include <string.h> /* Nicht wirklich das Original, sondern die Variante von Peter, die * aber ebenfalls nicht primitiv-rekursiv ist: */ unsigned long ack_rec(unsigned long n, unsigned long m) { if (!n) return m + 1; else if (!m) return ack_rec(n - 1, 1); else return ack_rec(n - 1, ack_rec(n, m - 1)); } /* Teil-iterativ: */ unsigned long ack_part_iter(unsigned long n, unsigned long m) { for (; n; n--) if (!m) m = 1; else m = ack_part_iter(n, m - 1); return m + 1; } /* Iterativ unter Verwendung eines expliziten Stacks: */ static void push(unsigned long); static unsigned long pop(void); /* 0, wenn der Stack leer ist, weil wir niemals eine 0 pushen. */ unsigned long ack_iter_stack(unsigned long n, unsigned long m) { start: for (; n; n--) if (m) { m--; push(n); goto start; } else m = 1; if (n = pop()) { m++; n--; goto start; } return m + 1; } int main(int argc, char *argv[]) { unsigned long n, m; unsigned long (*ack)(unsigned long, unsigned long); if (argc != 4 || !strchr("rpi", argv[1][0]) || argv[1][1] || sscanf(argv[2], "%lu", &n) != 1 || sscanf(argv[3], "%lu", &m) != 1) { fputs("usage: plemplem [r | p | i] n m\n" "\tr: recursive, p: partial iterative, " "i: iterative, using a stack\n", stderr); exit(1); } switch (argv[1][0]) { case 'r': ack = ack_rec; break; case 'p': ack = ack_part_iter; break; case 'i': ack = ack_iter_stack; break; } printf("%lu\n", ack(n, m)); return 0; } /* Hier kommt nur noch das Stack-Geraffel */ static struct { unsigned long *st_data; unsigned long st_max; unsigned long st_tos; } st = { NULL, 0, 0 }; static void push(unsigned long n) { if (st.st_tos >= st.st_max) { st.st_max = st.st_max ? 2 * st.st_max : 1024; if (!(st.st_data = realloc(st.st_data, st.st_max * sizeof(*(st.st_data))))) err(1, NULL); } st.st_data[st.st_tos++] = n; } static unsigned long pop(void) { return !st.st_tos ? 0 : st.st_data[--st.st_tos]; }