En C no se puede pasar el apuntador por referencia de ese modo. Lo hice de otro modo y a ver si me dices si es correcto o es una locura lo que hago.
El caso es que ya tengo solucionado el nivel 2 y 3 de la piramide y solo me falta la parte de los 4 valores de la base que ahi si que ya me pierdo. A ver si podeis ayudarme. Ya digo que esta aplicacion no sirve para nada ya que lo normal es que tengas los 4 valores de la base y te pidan resolver la piramide para saber cuanto vale el valor del pico y no al reves. Lo hago por aprender un poco y divertirme simplemente.
Lo que comentais de prueba/error parece mas encontrar un serial por fuerza bruta jejeje.
A ver si podeis orientarme aunque sea con un seudocodigo para ver como sería y de paso decirme si hago algo mal en el codigo o todo jejeje.
Hacerlo con recursividad... no se me da nada bien la recursividad y si así me está costando sudor y lagrimas... no quiero ni imaginarme con recursividad jajaja.
Aquí lo que tengo de codigo hasta ahora (espero comentarios):
Código PHP:
#include <stdio.h>
#include <stdlib.h>
int MCD(int a, int b);
int ObtenerListaDivisores(int valor, int** Divisores);
void LiberarListaDivisores(int** Divisores);
int ObtenerPareja(int dividendo, int** Divisores, int nDivisores, int* valor1, int* valor2, int posX, int posY);
void shuffle(int *Divisores, int nDivisores);
int main()
{
int i, n, z, multiplicando, multiplicador, divisorComun, nDivisores;
int *Divisores;
int Resultado[10];
int dividendo = 1000;
int salir = 0, repetido, retval=0, posibles=0;
int dibujados[100]={0};
//Inicializo la semilla para rand()
srand (time(NULL));
//Coloco el valor del pico de la piramide en el array que almacena el resultado
Resultado[0]=dividendo;
//Obtengo todos los divisores del valor del pico de la piramide
nDivisores = ObtenerListaDivisores(dividendo, &Divisores);
//Barajo la lista de divisores
shuffle(Divisores,nDivisores);
retval=0;
//Con estos dos bucles puedo calcular todas las posibilidades del segundo nivel de la pirámide
for(n=nDivisores-1;n>=0 && salir==0;n--)
{
for(z=nDivisores-2;z>=0 && salir==0;z--)
{
if(n!=z){
//Obtengo los dos valores del segundo nivel
retval = ObtenerPareja(dividendo, &Divisores, nDivisores, &multiplicando, &multiplicador, z, n);
//Si no hubo error entramos
if(retval != -1){
//Busco el multiplicando y el multiplicador en la lista y si no están los añado
for(i=0;i<nDivisores;i++)
{
if(dibujados[i] == multiplicando || dibujados[i] == multiplicador){
repetido=1;
break;
}else if(dibujados[i] == 0){
dibujados[i]=multiplicando;
dibujados[i+1]=multiplicador;
repetido=0;
break;
}
}
//Si no están repetidos los valores del segundo nivel
//Si está repetido nos saltamos esto para empezar de nuevo con la siguiente posibilidad
if(repetido != 1){
//Coloco los dos valores del segundo nivel en el array del resultado
Resultado[1]=multiplicando;
Resultado[2]=multiplicador;
//Calculo el valor central del tercer nivel
divisorComun = MCD(multiplicando,multiplicador);
//Calculo los dos extremos del tercer nivel para este MCD
multiplicando= multiplicando/divisorComun;
multiplicador= multiplicador/divisorComun;
//Coloco los tres valores del tercer nivel en el array del resultado.
//El MCD va en el centro
Resultado[3]=multiplicando;
Resultado[4]=divisorComun;
Resultado[5]=multiplicador;
//Incremento el contador de posibles soluciones
posibles++;
//Muestro la pirámide
printf(" %i\n", Resultado[0]);
printf(" %i %i\n", Resultado[1], Resultado[2]);
printf(" %i %i %i\n", Resultado[3], Resultado[4], Resultado[5]);
printf("%i %i %i %i\n", 1, 1, 1, 1); //Me falta calcular esta fila
printf("\n---------------------------------\n");
}
}
}
}
}
printf("\nSe obtuvieron %i posibles soluciones.\n",posibles);
//Libero la memoria reservada para almacenar los divisores para el segundo nivel
LiberarListaDivisores(&Divisores);
printf("\nPresiona INTRO para salir");
getchar();
return 0;
}
//---------------------------------------------------------------------------
//Máximo común divisor de dos números mediante el algoritmo de Euclides.
int MCD(int a, int b)
{
int aux, c, r;
if(a < b){
aux=b;
b=a;
a=aux;
}
r=a%b;
while(r>0)
{
if(a>b){
a=b;
b=r;
r=a%b;
}else{
return 0;
}
}
return b;
}
//---------------------------------------------------------------------------
//Retorna el numero de divisores posibles
int ObtenerListaDivisores(int valor, int** Divisores)
{
int i, j=0, nDivisores=0;
for(i=1;i<valor;i++)
if(valor%i==0){
nDivisores++;
}
*Divisores = (int*)malloc(sizeof(int) * nDivisores);
for(i=1;i<valor;i++)
if(valor%i==0){
(*Divisores)[j]=i;
j++;
}
return nDivisores;
}
//---------------------------------------------------------------------------
void LiberarListaDivisores(int** Divisores)
{
if(*Divisores != NULL)
free(*Divisores);
}
//---------------------------------------------------------------------------
//Funcion que obtiene la pareja de numeros para un MCD
int ObtenerPareja(int dividendo, int** Divisores, int nDivisores, int* valor1, int* valor2, int posX, int posY)
{
int divisorComun=0;
int n,z, salir=0;
int retval=0;
if(nDivisores>1){
divisorComun = MCD((*Divisores)[posX],(*Divisores)[posY]);
*valor1 = divisorComun;
*valor2 = dividendo/divisorComun;
}else{
retval=-1;
}
return retval;
}
//---------------------------------------------------------------------------
//Funcion para barajar el array de los divisores
void shuffle(int *Divisores, int nDivisores)
{
int i, j, t;
if (nDivisores > 1)
{
for (i = 0; i < nDivisores - 1; i++)
{
j = i + rand() % (nDivisores - i);
t = Divisores[j];
Divisores[j] = Divisores[i];
Divisores[i] = t;
}
}
}
//---------------------------------------------------------------------------