/******************************************************************************
 *
 * decadence.c
 * -----------
 * written by d1s4st3r <d1s4st3r@gmail.com>
 *
 *
 * This program illustrates the "decay of the numbers".
 *
 * Here's an example:
 *
 *	The given number is 222133. In order from left to right,
 *	it contains 2 three times, 1 one time and 3 two times.
 *	Therefore, the first step of 222133's decay is 321123.
 *	The second step will consist in the first step's decay,
 *	and so on...
 *
 *	222133 ---> 321123 ---> 1312211213 ---> etc...
 *
 ******************************************************************************
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>


#define		MAXFNLEN	16
#define		__OFFSET	48


typedef unsigned int uint;


char *decade_step(char *num);
uint sum_step(char *num);


/* returns a pointer to a string containing the decay of the number
   written in the string pointed by '*num' */
char *decade_step(char *num)
{
	uint len = strlen(num);
	uint j = 0;
	uint n = 0;
	uint i;
	char *ret = malloc(sizeof(char)*((len*2)+1));

	for (i=0; i<len; i++)
	{
		if (num[i]==num[i+1])
			n++;
		else
		{
			ret[j++] = (++n) + __OFFSET;
			ret[j++] = num[i];
			n = 0;
		}
	}

	return ret;
}


/* returns an integer which is the sum of all the digits of the
   number written in the string pointed by '*num' */
uint sum_step(char *num)
{
	uint len = strlen(num);
	uint ret = 0;
	uint i;

	for (i=0; i<len; i++)
		ret = ret + (num[i] - __OFFSET);

	return ret;
}


/* Hello, Mr. Main! */
int main(int argc, char *argv[])
{
	char *firstnum;
	char *tmp;
	uint i;
	uint iters = 1; /* default number of iterations is 1 */

	if (argc==2)
	{
		firstnum = argv[1];
	}
	else if (argc==3)
	{
		iters = atoi(argv[1]);
		firstnum = argv[2];
	}
	else
	{
		fprintf(stderr, "Wrong syntax.\nUsage: %s [<iterations>] <number>\n", argv[0]);

		return EXIT_FAILURE;
	}

	if (strlen(firstnum)>MAXFNLEN)
	{
		fprintf(stderr, "Too many digits.\nMaximum number of digits must be %d.\n", MAXFNLEN);

		return EXIT_FAILURE;
	}
	else
	{
		tmp = firstnum;

		printf("Index\tSum\tDecay\n");
		printf("[N]\t%d\t%s\n", sum_step(tmp), tmp);

		for (i=0; i<iters; i++)
		{
			tmp = decade_step(tmp);
			printf("%d\t%d\t%s\n", i+1, sum_step(tmp), tmp);
		}

		free(tmp);

		return EXIT_SUCCESS;
	}
}

