Blog Entry © Thursday, January 23, 2025, by James Pate Williams, Jr. Ackermann’s Super-Exponential Recursive Function in Vanilla C Programming Language

i = 2
j = 1
a(2, 1) =
4
# decimal digits = 1
enter another set (n to quit)? y
i = 2
j = 2
a(2, 2) =
16
# decimal digits = 2
enter another set (n to quit)? y
i = 2
j = 3
a(2, 3) =
65536
# decimal digits = 5
enter another set (n to quit)? y
i = 2
j = 4
a(2, 4) =
200352993040684646497907235156025575044782547556975141926501697371089\
405955631145308950613088093334810103823434290726318182294938211881266886\
950636476154702916504187191635158796634721944293092798208430910485599057\
015931895963952486337236720300291696959215610876494888925409080591145703\
767520850020667156370236612635974714480711177481588091413574272096719015\
183628256061809145885269982614142503012339110827360384376787644904320596\
037912449090570756031403507616256247603186379312648470374378295497561377\
098160461441330869211810248595915238019533103029216280016056867010565164\
...
506264233788565146467060429856478196846159366328895429978072254226479040\
061601975197500746054515006029180663827149701611098795133663377137843441\
619405312144529185518013657555866761501937302969193207612000925506508158\
327550849934076879725236998702356793102680413674571895664143185267905471\
716996299036301554564509004480278905570196832831363071899769915316667920\
895876857229060091547291963638167359667395997571032601557192023734858052\
112811745861006515259888384311451189488055212914577569914657753004138471\
712457796504817585639507289533753975582208777750607233944558789590571915\
6736
# decimal digits = 19729
enter another set (n to quit)?
/* 
** Computation of Akermann's super
** exponential function by James
** Pate Williams, Jr. (c) Tuesday,
** August 27, 2024 lip version
*/

#include <stdio.h>
#include "lip.h"

verylong Ackermann(verylong zi, verylong zj) {
	verylong a = 0;
	if (zscompare(zi, 1) == 0) {
		verylong ztwo = 0;
		zintoz(2, &ztwo);
		zexp(ztwo, zj, &a);
		return a;
	}
	else if (zscompare(zj, 1) == 0)
	{
		verylong ztwo = 0, ziminus1 = 0;
		zintoz(2, &ztwo);
		zsadd(zi, -1, &ziminus1);
		return Ackermann(ziminus1, ztwo);
	}
	else if (
		zscompare(zi, 2) >= 0 &&
		zscompare(zj, 2) >= 0) {
		verylong ziminus1 = 0;
		verylong zjminus1 = 0;
		verylong temp = 0;
		zsadd(zi, -1, &ziminus1);
		zsadd(zj, -1, &zjminus1);
		if (zscompare(ziminus1, 1) >= 0 &&
			zscompare(zjminus1, 1) >= 0) {
			return
				Ackermann(ziminus1, Ackermann(zi, zjminus1));
		}
	}
	return 0;
}

int DigitCount(verylong za) {
	int count = 0;
	while (zscompare(za, 0) > 0) {
		zsdiv(za, 10, &za);
		count++;
	}
	return count;
}

int main(void) {
	for (;;) {
		char buffer[256] = { '\0' };
		int i = 0, j = 0, number = 0;
		verylong za = 0, zi = 0, zj = 0;
		buffer[0] = '\0';
		printf_s("i = ");
		scanf_s("%d", &i);
		printf_s("j = ");
		scanf_s("%d", &j);
		zintoz(i, &zi);
		zintoz(j, &zj);
		printf_s("a(%d, %d) = \n", i, j);
		za = Ackermann(zi, zj);
		zwriteln(za);
		number = DigitCount(za);
		printf_s("# decimal digits = %d\n",
			number);
		printf_s("enter another set (n to quit)? ");
		scanf_s("%s", buffer, sizeof(buffer));
		zfree(&za);
		if (buffer[0] == 'n')
			break;
	}
	return 0;
}