Constante de Kaprekar

El número 6174 es un número realmente misterioso. A simple vista, puede no parecer tan obvio, pero estamos a punto de ver que cualquier persona que sepa restar también puede descubrir el misterio que hace al número 6174 tan especial. En en año 1949 el matemático Dattatreya Ramachandra Kaprekar (Devlali, India) ideó un proceso que hoy en día conocemos como la Operación de Kaprekar. Esta operación está sujeta a las siguientes reglas:

\{\omega\in \mathbb{N}\ |\ \omega = n_{1}n_{2}n_{3}n_{4}\ |\ 0 \leq n \leq 9\ |\{n_{1}n_{2}n_{3} | n_{2}n_{3}n_{4}\}\ne nnn \}

Esto es:

  • \omega\in \mathbb{N} \rightarrow El número inicial ha de ser una cadena de dígitos que formen un numero natural.
  • \omega = n_{1}n_{2}n_{3}n_{4} \rightarrow La longitud de \omega ha de ser de 4 dígitos.
  • 0 \leq n \leq 9 \rightarrow Cada uno de los dígitos ha de ser un número natural comprendido entre el 0 y el 9, ambos inclusive.
  • \{n_{1}n_{2}n_{3} | n_{2}n_{3}n_{4}\}\ne nnn \rightarrow No puede haber tres dígitos seguidos iguales.

Por ejemplo, aquí algunos ejemplos de números aceptados y no aceptados conforme a las reglas de arriba:

Aceptados No aceptados
1234 1118
7391 4333
8033 5555
2764 0000
\vdots \vdots

La operación es muy sencilla, consiste en elegir un número que cumpla la reglas ya descritas anteriormente. Por ejemplo el número 9581. A continuación, reorganizar los dígitos para obtener el número más grande y el más pequeño que estos dígitos pueden hacer.

Número mas grande posible \rightarrow 9851
Número mas pequeño posible \rightarrow 1589

Después, restar al número más grande el número más pequeño para obtener un nuevo número.

9851-1589=8262

Si se repite una y otra vez la operación con cada nuevo número, se termina obteniendo la constante de Kaprekar, o sea el número 6174.

8622-2268=6354
6543-3456=3087
8730-0378=8352
8532-2358=6174 \Longleftarrow

El motivo por el que no se puede escoger un número con tres dígitos consecutivos iguales es por que o bien en la primera resta (cuatro dígitos seguidos iguales) o en la segunda resta (tres dígitos seguidos iguales) termina dando resto 0. Por ejemplo:

7666-6667=999
999-999=0

Al final, da igual el número que se escoja (siempre que cumpla las reglas anteriores), al final siempre devuelve el número 6174.

A continuación dejo el código fuente de un programa en C que hace la Operación de Keprekar sobre un número introducido.

/*
 * constanteKaprekar v0.01
 * Copyleft - 2016  Javier Dominguez Gomez
 * Written by Javier Dominguez Gomez <jdg@member.fsf.org>
 * GnuPG Key: 6ECD1616
 * Madrid, Spain
 *
 * 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 3 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, see <http://www.gnu.org/licenses/>.
 *
 * Compilation: gcc -std=gnu99 -O0 -g3 -Wall -c -o constanteKaprekar.o "constanteKaprekar.c"
 *              gcc -o constanteKaprekar constanteKaprekar.o
 *
 * Usage:       ./constanteKaprekar
 */

#include <stdio.h>
#include <stdbool.h>

/* Procedimiento para ordenar dos numeros. */
void swap(int *x, int *y) {
	if (*x < *y) {
		int aux;
		aux = *x;
		*x = *y;
		*y = aux;
	}
}

/* Funcion que devuelve la longitud de un int. */
int LongitudInt(int n) {
	int i = 1;
	while (n > 9) {
		i++;
		n /= 10;
	}
	return i;
}

/* Funcion que devuelve un int con sus digitos en orden descendente. */
int OrdenacionDescendenteInt(int n) {
	int i, n_ordenado = 0;
	for (i = 9; i >= 0; i--) {
		int aux = n;
		while (aux > 0) {
			int digit = aux % 10;
			if (digit == i) {
				n_ordenado *= 10;
				n_ordenado += digit;
			}
			aux /= 10;
		}
	}
	return n_ordenado;
}

/* Funcion que devuelve un int con sus digitos en orden ascendente. */
int OrdenacionAscendenteInt(int n) {
	int i, n_ordenado = 0;
	for (i = 0; i <= 9; i++) {
		int aux = n;
		while (aux > 0) {
			int digit = aux % 10;
			if (digit == i) {
				n_ordenado *= 10;
				n_ordenado += digit;
			}
			aux /= 10;
		}
	}
	return n_ordenado;
}

/* Funcion que comprueba si el numero introducido tiene 4 digitos. */
static bool CompruebaDigitos(int n) {
	if (LongitudInt(n) < 4) {
		printf("Longitud del numero %d invalida. Tiene que tener 4 digitos.\n", n);
		return false;
	} else {
		return true;
	}
}

int main() {
	int n, x, y, kaprekar;

	do {
		printf("Numero de 4 digitos: ");
		scanf("%d", &n);
	} while (CompruebaDigitos(n) == false);

	x = OrdenacionDescendenteInt(n);
	y = OrdenacionAscendenteInt(n);
	kaprekar = x - y;

	printf("%d - %d = %d\n", x, y, kaprekar);

	do {
		if (kaprekar == 0) {
			printf("Numero %d invalido por resto 0.\n", n);
			break;
		}
		x = OrdenacionDescendenteInt(kaprekar);
		y = OrdenacionAscendenteInt(kaprekar);
		kaprekar = x - y;
		printf("%d - %d = %d\n", x, y, kaprekar);
	} while (kaprekar != 6174);

	return 0;
}

Una vez compilado este es su funcionamiento:

./constanteKaprekar
Numero de 4 digitos: 9581
9851 - 1589 = 8262
8622 - 2268 = 6354
6543 - 3456 = 3087
8730 - 378 = 8352
8532 - 2358 = 6174