El blog de Juan Palómez

22 octubre 2008

Timoconcurso “cerillas”

Filed under: Uncategorized — Etiquetas: , , — thisisoneball @ 23:32

Este es un programa en C que resuelve uno de los problemas de los “timoconcursos” de los canales de la TDT. En concreto el que aparece un número de 4 cifras hecho con cerillas y hay que conseguir el número más alto posible moviendo dos cerillas.

Realmente este programa es algo más genérico: se puede especificar el número de cerillas que habría que mover, se pueden hacer con números de cualquier número de cifras, y devuelve todas las soluciones, no sólo el más alto.

Esto es una curiosidad, no es para llamar al programa y tener la solución, porque el timo por lo visto está en que te tienen media hora al teléfono esperando para dar la solución, y eso en el caso de que cojan la llamada.

NO LLAMES AL TIMOCONCURSO.

#define	TRUE	1
#define	FALSE	0
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>

/*	tipo de datos "segmentos":
		vector de 7 shorts, almacena un dígito en forma de segmentos, de la siguiente forma:
			|-0-|
			1   2
			|-3-|
			4   5
			|-6-|
		por ejemplo el 0 se almacenaría como:
			segmentos numero0 = {1,1,1,0,1,1,1};

	conjuntos de segmentos:
		permiten almacenar un número completo compuesto de varios dígitos, por ejemplo para almacenar números de 4 dígitos:
			segmentos numero[4];
		para hacer lo mismo en tiempo de ejecución:
			segmentos *numero;
			numero = (segmentos *) calloc(4, sizeof(segmentos));
*/
typedef short segmentos[7];

//	especificación de los dígitos del 0 al 9 en forma de segmentos (vector de 10x7 shorts)
segmentos digitos[10] = {
	{1,1,1,0,1,1,1},
	{0,0,1,0,0,1,0},
	{1,0,1,1,1,0,1},
	{1,0,1,1,0,1,1},
	{0,1,1,1,0,1,0},
	{1,1,0,1,0,1,1},
	{1,1,0,1,1,1,1},
	{1,0,1,0,0,1,0},
	{1,1,1,1,1,1,1},
	{1,1,1,1,0,1,1}
};

//	copia los 7 segmentos de un dígito
void CopiarSegmentos(segmentos destino, segmentos origen)
{
	memcpy(destino, origen, 7 * sizeof(destino[0]));
}

//	transforma un entero "origen" a un vector de segmentos "destino" (no un solo dígito sino un número completo compuesto de "tam" dígitos)
void IntSegmento(segmentos *destino, int origen, int tam)
{
	while (tam >= 1) {
		tam--;
		CopiarSegmentos(destino[tam], digitos[origen % 10]);
		origen = origen / 10;
	}
}

/*	compara dos números de "tam" dígitos
	devuelve TRUE si entre los dos se han movido "ndiferencias" segmentos
*/
int CompararSegmentos(segmentos *origen, segmentos *destino, int tam, int ndiferencias)
{
	int i;
	int diferencias = 0, total = 0;

	for (i=0; i < tam*7; i++) {
		total += (*origen)[i] - (*destino)[i];
		if ((*origen)[i] != (*destino)[i])
			diferencias++;
	}

	// total es la diferencia en el total de segmentos, y debe ser 0 (mismo nº de cerillas en los dos casos)
	// diferencias es el total de segmentos cambiados (es el doble del nº de cerillas movidas)
	if (diferencias == ndiferencias*2 && total == 0)
		return TRUE;
	else
		return FALSE;
}

/*	parámetros del programa: el número inicial y el número de cerillas que hay que mover

	retorno:
		0	sin errores
		1	error en el número de parámetros pasados
		2	error en el formato de los parámetros
*/
int main(int argc, char *argv[])
{
	int inicial, ndiferencias, tam; segmentos *s_inicial;
	int candidato; segmentos *s_candidato;

	// gestión de parámetros de entrada
	if (argc != 3) {
		fprintf(stderr, "Uso: %s\nEjemplo: %s 5912 2\n", argv[0], argv[0]);
		return 1;
	}

	inicial = atoi(argv[1]);		// ej: 5912
	ndiferencias = atoi(argv[2]);		// ej: 2
	if (inicial == 0 || ndiferencias == 0) {
		fprintf(stderr, "Los parámetros tienen que ser numéricos y distintos de 0\nEjemplo: %s 5912 2\n", argv[0]);
		return 2;
	}

	tam = strlen(argv[1]);			// ej: 4
	candidato = (int) pow(10,tam) - 1;	// ej: 9999

	s_inicial = (segmentos *) calloc(tam, sizeof(segmentos));
	s_candidato = (segmentos *) calloc(tam, sizeof(segmentos));

	// pasar el nº inicial a segmentos y comparar con cada nº candidato decrecientemente
	IntSegmento(s_inicial, inicial, tam);
	while (candidato >= 0) {
		IntSegmento(s_candidato, candidato, tam);
		if (CompararSegmentos(s_inicial, s_candidato, tam, ndiferencias))
			printf("%d\n", candidato);
		candidato--;
	}

	return 0;
}

12 comentarios »

  1. Hola,

    Me dio por probar el programa y hay algo incorrecto, ten en cuenta que de un 4 en forma de cerillas puedes sacar dos unos ( | | ).

    Teniendo esto en cuenta, de 6485 moviendo 2 cerillas se puede formar 61185, pero la cifra más alta que el programa encuentra es 9499.

    ¿Como se podría hacer para que lo calculase de la forma correcta?

    Saludos!

    Comentario por RedStripes — 13 enero 2009 @ 05:02

  2. PD: De 6485 moviendo 1 cerilla se puede formar 61185 quería decir.

    Comentario por RedStripes — 13 enero 2009 @ 05:02

  3. Muy agudo… fijo que en el programa utilizan eso para dar la respuesta como incorrecta.

    Tengo que mirarlo pero parece bastante difícil, cambia mucho la forma de generar los números de esa manera. Posiblemente haya que hacer reglas específicas para cada caso como ese que me comentas.

    Comentario por thisisoneball — 13 enero 2009 @ 11:32

  4. Y si fuera solo eso, otro “truco” de los teletimos es utilizar números romanos en la posible solución o incluso elevar un número a una potencia, por ejemplo:

    Tenemos el número 6485, moviendo las 2 cerillas de la parte superior del 6 y colocándolas debajo formando un 9, quedaría 9^485.

    Comentario por RedStripes — 13 enero 2009 @ 17:00

  5. Ayer tuve este programa puesto mientras trasteaba por internet y creo que dieron como valido un resultado no correcto, aunque despues del mareo de hora y pico no se si me entere muy bien. Con el numero 6485 habia que construir el mayor posible moviendo 2 cerillas, gano un tio que dio como cifra 91199

    Comentario por charli — 14 enero 2009 @ 02:28

  6. En ese caso tiene que ser lo que ha dicho RedStripes, el 4 lo habran pasado a 11 moviendo 1 cerilla.
    Con otra cerilla transformas el 6 inicial en un 9, y con otra transformas el 85 en 99.
    A mi me salen 3 cerillas movidas.

    De todas formas el programa esa solucion tambien te la daria incorrecta aunque le pases 3 como segundo parámetro, porque no tiene en cuenta lo de 4 -> 11.

    Comentario por thisisoneball — 15 enero 2009 @ 17:04

  7. Es 99119.

    el 6485 hay que voltearlo del reves, entonces con el palo del 8 puedes convertir el 5 volteado en un 9 , i dejas el 8 convertido en 9.

    luego conviertes el 4 a 11 moviendo un palo, i queda el 6 volteado como ultimo numero.

    asi que obtenemos 99119

    Comentario por eimo — 27 enero 2009 @ 04:43

  8. Esto es una estafa, yo lo tenia puesto hasta ahora que acaban de dar la solución y no consigo entenderlo, a ver si la sacais.

    El número era el 8017 y el resultado que les da es 500502.

    Comentario por masm — 8 septiembre 2009 @ 05:06

  9. Yo habia llegado al 91011, pero no se de donde se pueden sacar 500502 solo moviendo dos cerillas del número 8017

    Comentario por masm — 8 septiembre 2009 @ 05:08

  10. HOLA CUAL OS SALE DEL NUMERO,2185 POR QUE EL MAS ALTO A MI ME SALE 21135.GRACIAS

    Comentario por MONTSE — 12 enero 2010 @ 20:41

  11. Y como activas el programa? no lo entendí, quiero hacer la prueba con el nñumero 1939. Que conocimientos debo tener para usarlo o activarlo, es un scrip? gracias

    Comentario por sebaenvivo — 31 julio 2010 @ 06:42

  12. Debes grabarlo en un fichero .c y compilarlo. Necesitas conocimientos de lenguaje C.
    De todas formas lo calculo yo en mi ordenador: del 1939 moviendo dos cerillas puedes llegar al 7994

    Comentario por thisisoneball — 19 agosto 2010 @ 16:34


RSS feed for comments on this post. TrackBack URI

Responder

Por favor, inicia sesión con uno de estos métodos para publicar tu comentario:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

Blog de WordPress.com.

A %d blogueros les gusta esto: