/* * http://codegolf.stackexchange.com/q/54287/134 * Reference implementation when invoked with two arguments, * transformation from / to Zeckendorf representation when invoked with * one argument. */ #include #include static const int fibs[31] = { 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309 }; /* convert a number to Zeckendorf representation */ static int tozeck(int n) { int i, z = 0; for (i = 30; i >= 0; i--) { z <<= 1; if (n >= fibs[i]) { n -= fibs[i]; z++; } } return z; } /* convert a number from Zeckendorf representation */ static int unzeck(int z) { int i, n = 0; for (i = 0; i < 31; i++) if (z & 1 << i) n += fibs[i]; return n; } extern int main(int argc, char *argv[]) { unsigned long a, b; char *endptr; switch (argc) { case 2: a = strtoul(argv[1], &endptr, 0); if (a > 2147483647 || *endptr != '\0' || *argv[1] == '\0') goto usage; if (a <= 3524577) printf("Z(%ld) = %d\n", a, tozeck(a)); if ((a & a >> 1) == 0) printf("%ld = Z(%d)\n", a, unzeck(a)); return EXIT_SUCCESS; case 3: a = strtoul(argv[1], &endptr, 0); if (a > 2147483647 || *endptr != '\0' || argv[1] == '\0' || (a & a >> 1)) { fprintf(stderr, "%s is not a valid Zeckendorf representation\n", argv[1]); return EXIT_FAILURE; } b = strtoul(argv[2], &endptr, 0); if (b > 2147483647 || *endptr != '\0' || argv[2] == '\0' || (b & b >> 1)) { fprintf(stderr, "%s is not a valid Zeckendorf representation\n", argv[2]); return EXIT_FAILURE; } a = unzeck(a); b = unzeck(b); if (a + b > 3524577) { fprintf(stderr, "Sum too large!\n"); return EXIT_FAILURE; } printf("%d\n", tozeck(a + b)); return EXIT_SUCCESS; default: usage: fprintf(stderr, "Usage: %s number or %s number number\n" "numbers must be smaller than 2^31 = 1073741824\n" "first case computes Zeckendorf representation and invers,\n" "second case computes sum of numbers in Zeckendorf representaion.\n", argv[0], argv[0]); return EXIT_FAILURE; } }