
//Finds consecutive happy numbers up to limit
//Dev Gualtieri (gualtieri@ieee.org), March 13, 2022
//Based on Rosetta Code example at https://www.rosettacode.org/wiki/Happy_numbers#C)
//to compile using gcc: gcc -o happy_consecutive happy_consecutive.c

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define limit 10000000
#define CACHE 256
enum { h_unknown = 0, h_yes, h_no };
unsigned char buf[CACHE] = { 0, h_yes, 0 };

char fn[16] = "happy.dat";
FILE *outdata;
clock_t start;
clock_t end;

int happy(int n)
{
    int sum = 0, x, nn;
    if (n < CACHE) {
	if (buf[n])
	    return 2 - buf[n];
	buf[n] = h_no;
    }

    for (nn = n; nn; nn /= 10)
	x = nn % 10, sum += x * x;

    x = happy(sum);
    if (n < CACHE)
	buf[n] = 2 - x;
    return x;
}

int main()
{
    printf("\nOutput file selected = %s\n", fn);

    if ((outdata = fopen(fn, "w")) == NULL) {
	printf("\nOutput datafile cannot be opened.\n");
	exit(1);
    }

    start = clock();

    int i, cnt = 8;
    for (i = 2; i <= limit; i++)
	if (happy(i)&&happy(i-1)) {
	    printf("%d\t", i);
	    fprintf(outdata, "%d\n", i);
	}

    end = clock();
    fclose(outdata);
    printf("\nElapsed time for n = %d = %f\n", limit, (double)(end-start)/CLOCKS_PER_SEC);
    printf("Done.\n");

    return 0;
}
