Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 02-03-2015
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
saber valores de base de piramide a partir de su resultado

Bueno, el titulo es complicado de explicar ya que lo que quiero es lo siguiente, teniendo 4 valores, multiplico de la siguiente manera:
Código:
          X
       X     X
   X     X     X
1     2     3     4
Código:
1*2=2
2*3=6
3*4=12
Y queda así:
Código:
          X
       X     X
   2     6     12
1     2     3     4
Ahora:
Código:
2*6=12
6*12=72
y queda así:
Código:
          X
      12    72
   2     6     12
1     2     3     4
y por ultimo:
Código:
12*72=864
quedando:
Código:
         864
      12    72
   2     6     12
1     2     3     4
Bueno pues eso ya lo tengo en codigo y quedó asi:
Código PHP:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argccharargv[])
{
   
int i,x;
   
char *numeral[4]={"primer","segundo","tercer","cuarto"};
   
double base[4];
   
char acomodo[100] = "";

   for(
i=0;i<4;i++){
      
printf("Introduce el %s numero de la base: ",numeral[i]);
      
scanf("%lf",&base[i]);
   }

   
printf("\nPIRAMIDE:");
   
printf("\n---------\n");
   for(
i=0;i<4;i++)
      
printf("%.0lf      ",base[i]);

   for(
i=0;i<4;i++)
   {
      
strcat(acomodo,"   ");
      
printf("\n%s",acomodo);
      for(
x=0;x<3-i;x++)
      {
         
base[x] = base[x] * base[x+1];
         
printf("%.0lf      ",base[x]);
      }
   }
   
printf("\nResultado: %.0lf\n\n",base[0]);
   
system("PAUSE");
   return 
0;

Y me surge una duda ¿es posible hacer el paso inverso? o sea, a partir del valor final obtener los valores de la base de una piramide. Supongo que sería dividiendo pero no debe tener decimales y supongo que no todos los valores pueden tener piramide asi. ¿Alguno podria decirme si se puede y como sería? Es simple curiosidad.
Responder Con Cita
  #2  
Antiguo 03-03-2015
Avatar de Ñuño Martínez
Ñuño Martínez Ñuño Martínez is offline
Moderador
 
Registrado: jul 2006
Ubicación: Ciudad Catedral, Españistán
Posts: 6.000
Poder: 25
Ñuño Martínez Tiene un aura espectacularÑuño Martínez Tiene un aura espectacular
Por poder, se podría, pero sería largo. Yo empezaría con una función al que le pases un valor y te devuelva dos posibles soluciones. A partir de ahí, un bucle y ya casi lo tendrías.

El problema es que la cantidad de triángulos que obtendrías con un único valor sería alto, en algunos casos.
__________________
Proyectos actuales --> Allegro 5 Pascal ¡y Delphi!|MinGRo Game Engine
Responder Con Cita
  #3  
Antiguo 03-03-2015
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.271
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Poder claro que puedes, otra cosa es que en algunos casos es de suponer que tendrás varias posible soluciones.
La primera opción a probar sería un algoritmo de "prueba y error" o "ensayo y error" que básicamente lo que hace es explorar todas las soluciones posibles.
No suelen ser muy eficientes, pero te darán TODAS las soluciones a un problema.

A partir de ahí puedes intentar "optimizar" este algoritmo o buscar otro más elaborado.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #4  
Antiguo 03-03-2015
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.271
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
La idea es pensar cómo lo harías tú manualmente y luego aplicar un algoritmo.

Si coges el número superior, deberías:
(1) Buscar sus DIVISIORES.
(2) Para todos los divisores probar con las parejas que al muntiplicarlas dan el número inicial.

Volver a aplicar el punto (1) (la recursividad parece una buena opción) sobre cada uno de esos números...
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #5  
Antiguo 03-03-2015
engranaje engranaje is offline
Miembro
 
Registrado: may 2011
Posts: 163
Poder: 13
engranaje Va por buen camino
Yo sigo en la línea de las respuestas que ya te han dado. Mi planteamiento es una función que dado un número devuelva todas los posibles productos de 2 números que den como resultado el número pasado. Se me ocurre que por defecto ya tenemos una tupla (1,numeroPasado) , y despues bastaría con un bucle incrementando i comparando cuando numeroPasado mod i = 0, para cada vez que se cumpla la condición añadir una tupla mas a la lista de posibles semillas del número pasado (i,numeropasado/i).

Asi tendras el vertice y todas las posibles 2º lineas de triangulo que daran como resultado ese vertice. Según cuantas lineas quieres que tenga el triangulo te tocara para todas esas tuplas buscar los divisores comunes de los dos elementos teniendo en cuenta solo las tuplas que tengan divisores comunes.

Tendremos una 3º linea por cada divisor común con 3 números: en medio el divisor común, a la izquierda el numero de la izuierda en la 2º linea dividido entre el divisor comun y a la derecha el número de la derecha de la 2º líneda dividida entre el divisor común.

La 3º línea se complica y para cada divisor común del número de la izquierda y del centro además el número del centro/divisor común debe de ser divisor común del número del centro y el número de la derecha...

En fín me he puesto a escribir mientras pensaba y me he liado, lo cierto es que si parece posible.
PD: Neftalí se me ha adelantado mientras escribía esto explicando como siempre todo con mucha mas claridad. (y en 2 lineas, nnf, nnnf)

Última edición por engranaje fecha: 03-03-2015 a las 14:09:36.
Responder Con Cita
  #6  
Antiguo 03-03-2015
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Red face

pues la verdad es que yo me lio y no soy capaz de hacer lo que indicais. Lo que si que se me ha ocurrido leyendoos es que si hago lo que indicais pero en vez de dividir multiplico obtendria una piramide divertida para hacer divisiones y obtener el resultado de su cima. El caso es que en ninguno de los casos se me ocurre como hacerlo. El caso es mas complejo de lo que parece ya que, en lo que exponia al iniciar este tema, la linea de dos valores (la que esta justo debajo de la cima tiene que contener valores mas o menos grandes y, cuando decis de probar todos los divisores, me puedo encontrar que hay valores pequeños que pueden ser divisores como 1, 2, y 3 y el caso es que es muy dificil que se llegue a ese nivel de la pirámide con un producto tan pequeño. La verdad es que no lo veo. ¿Habeis probado alguno a ver si os sale o es mas complejo de lo que parece? Como es por curiosidad pues no hay requisitos, podria ser por ejemplo que muestre la primera solucion, o tambien que las calcule todas y luego mostrar una al azar, o por ejemplo mostrar las x primeras, o cualquier cosa por el estilo. La idea surgio porque a mi niña le mandaron en el cole un trabajo de matematicas divertidas y buscando por google di con algo llamado piramide divertida y que las hay para sumas y multiplicaciones. Ya hice que un codigo resuelva ambas y luego se me ocurrio hacer lo inverso pero ahi ya me atasqué. Por cierto, no vi ninguna piramide para divisiones asi que no estaria mal aplicar lo que indicais para crear piramides para que practique las divisiones tambien.
Responder Con Cita
  #7  
Antiguo 04-03-2015
engranaje engranaje is offline
Miembro
 
Registrado: may 2011
Posts: 163
Poder: 13
engranaje Va por buen camino
A ver si no me lio... La cosa es que de todos esos posibles valores para la segunda línea vas a tener que descartarlos casi todos a no econtrar divisores comunes entre ambos. Es decir el número del medio de la tercera linea debe ser un divisor común a los dos números de la segunda, Si quieres puedes buscar directamente el máximo común divisor y pillar la tupla con el máximo comúm divisor mas alto, asi elminiarias esos números bajos que tanto molestan.
Lo que pasa es que como la tercera línea también debe tener divisores comunes igual llegas a un punto muerto en la tercera línea de la piramide.... De entrada y si es por jugar yo probaría lo que digo de escoger la tupla con el máximo común divisor mas alto a ver que sale.
Responder Con Cita
  #8  
Antiguo 04-03-2015
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.271
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por aguml Ver Mensaje
... y cuando decis de probar todos los divisores, me puedo encontrar que hay valores pequeños que pueden ser divisores como 1, 2, y 3 y el caso es que es muy dificil que se llegue a ese nivel de la pirámide con un producto tan pequeño.
Correcto. Esos casos se consideran de ERROE. Por eso se llama "PRUEBA Y ERROR". Por que se evalúan todos los casos posibles que pueden ser miles. De todos esos tal vez unos cuantos, uno sólo o ninguno sean viables (CORRECTOS).
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #9  
Antiguo 04-03-2015
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.271
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Yo creo que la cosa no es tan difícil.
Te recomiendo dividir el problema en pasos pequeños.

Por ejemplo, primer paso:

(PASO 1) Dado un número (864) obtener todos sus divisores: 1-2-3-4-6-8-9-12-16-18-24-27-32-36-48-54-72-96-108-144-216-288-432

__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #10  
Antiguo 04-03-2015
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.271
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
(PASO 2): Utilizando esos divisores, buscar todas las parejas que son válidas para un nivel inferior.

__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #11  
Antiguo 04-03-2015
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Primer problema, estoy intentando crear una funcion a la cual se le da un valor y te devuelve una matriz con todos los divisores posibles. El caso es que no se como hacerlo para pasar un puntero de tipo int y que al retornar tenga en ese puntero la matriz.
Tengo este codigo:
Código PHP:
int *Divisores;

nDivisores ObtenerListaDivisores(10,&Divisores);

//Retorna el numero de divisores posibles
int ObtenerListaDivisores(int valorintDivisores[])
{
   
int ij=0nDivisores=0;

   for(
i=1;i<valor;i++)
      if(
valor%i==0){
         
nDivisores++;
         
printf("%i\n",i);
      }

   
Divisores malloc(sizeof(int) * nDivisores);

   for(
i=1;i<valor;i++)
      if(
valor%i==0){
         *
Divisores[j]=i;
         
j++;
      }
   return 
nDivisores;

El caso es que me estoy equivocando y no se como solucionarlo ya que no se como rellenar el array y retornar el puntero y que no se pierdan esos valores al salir de la funcion, no se si me explico.
Edito: Ya lo solucione esta parte.

Última edición por aguml fecha: 04-03-2015 a las 14:48:30.
Responder Con Cita
  #12  
Antiguo 04-03-2015
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola aguml.

Yo tampoco entiendo bién lo que buscas, pero en una parte mencionas:
Cita:
no se como rellenar el array ... y que no se pierdan esos valores al salir de la funcion
Una forma de hacerlo es pasar el arreglo por referencia:
Código PHP:
...
void foo(int*&, int);

int main()
{
  
int *vec;
  
  
foo(vec10);
  for (
int i 010i++) cout << vec[i] << endl
  ...
}

void foo(int*& vint n) {
  
= new int[n];
  for(
int i 0ni++) v[i] = i;

Pero como te digo arriba, no entiendo bién el objetivo de obtener el apuntador al arreglo y tal vez me esté perdiendo algo...

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #13  
Antiguo 04-03-2015
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
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 aint b);
int ObtenerListaDivisores(int valorint** Divisores);
void LiberarListaDivisores(int** Divisores);
int ObtenerPareja(int dividendoint** Divisoresint nDivisoresintvalor1intvalor2int posXint posY);
void shuffle(int *Divisoresint nDivisores);

int main()
{
   
int inzmultiplicandomultiplicadordivisorComunnDivisores;
   
int *Divisores;
   
int Resultado[10];
   
int dividendo 1000;
   
int salir 0repetidoretval=0posibles=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>=&& salir==0;n--)
   {
      for(
z=nDivisores-2;z>=&& salir==0;z--)
      {
         if(
n!=z){
            
//Obtengo los dos valores del segundo nivel
            
retval ObtenerPareja(dividendo, &DivisoresnDivisores, &multiplicando, &multiplicadorzn);

            
//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
                  
multiplicandomultiplicando/divisorComun;
                  
multiplicadormultiplicador/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"1111); //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 aint b)
{
   
int auxcr;

   if(
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 valorint** Divisores)
{
   
int ij=0nDivisores=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 dividendoint** Divisoresint nDivisoresintvalor1intvalor2int posXint posY)
{
   
int divisorComun=0;
   
int n,zsalir=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 *Divisoresint nDivisores)
{
   
int ijt;

   if (
nDivisores 1)
   {
      for (
0nDivisores 1i++)
      {
         
rand() % (nDivisores i);
         
Divisores[j];
         
Divisores[j] = Divisores[i];
         
Divisores[i] = t;
      }
   }
}
//--------------------------------------------------------------------------- 
Responder Con Cita
  #14  
Antiguo 05-03-2015
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Cita:
Empezado por aguml Ver Mensaje
En C no se puede pasar el apuntador por referencia de ese modo...
Mismo ejemplo en C:
Código PHP:
#include <stdio.h>
#include <stdlib.h>

#define ELEM 10

void foo(intvint);

int main()
{
  
int i, *vec = (int*) malloc(sizeof(int) * ELEM);

  
foo(vecELEM);
  for (
0ELEMi++) printf("%3d"vec[i]);
  
free(vec);

  
getchar();
}

void foo(intvint n) {
  
int i;
  for(
0ni++) *(v+i) = i;

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #15  
Antiguo 05-03-2015
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Ok, mañana lo miro que hoy ya es muy tarde. ¿Estas seguro que si lo hago así como indicas pero usando malloc dentro de la funcion funcionará? He corregido otros fallos que vi por el codigo:
Código PHP:
#include <stdio.h>
#include <stdlib.h>

int MCD(int aint b);
int ObtenerListaDivisores(int valorint** Divisores);
void LiberarListaDivisores(int** Divisores);
int ObtenerPareja(int dividendoint** Divisoresint nDivisoresintvalor1intvalor2int pos);
void shuffle(int *Divisoresint nDivisores);

int main()
{
   
int inzmultiplicandomultiplicadordivisorComunnDivisores;
   
int *Divisores;
   
int Resultado[10]={0};
   
int dividendo 100;
   
int salir 0repetidoretval=0posibles=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 este bucle puedo calcular todas las posibilidades del segundo nivel de la pirámide
   
for(z=0;z<nDivisores && salir==0;z++)
   {
      
//Obtengo los dos valores del segundo nivel
      
retval ObtenerPareja(dividendo, &DivisoresnDivisores, &multiplicando, &multiplicadorz);

      
//Si no hubo error entramos
      
if(retval != -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
         
if(multiplicando divisorComun)
            
multiplicandodivisorComun/multiplicando;
         else
            
multiplicandomultiplicando/divisorComun;

         if(
multiplicador divisorComun)
            
multiplicador divisorComun/multiplicador;
         else
            
multiplicadormultiplicador/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"1111); //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 aint b)
{
   
int auxcr;

   if(
b){
      
aux=b;
      
b=a;
      
a=aux;
   }

   
r=a%b;
   while(
r>0)
   {
      if(
a>b){
         
a=b;
         
b=r;
         
r=a%b;
      }else{
         
b=0;
         break;
      }
   }
   return 
b;
}
//---------------------------------------------------------------------------

//Retorna el numero de divisores posibles
int ObtenerListaDivisores(int valorint** Divisores)
{
   
int ij=0nDivisores=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 dividendoint** Divisoresint nDivisoresintvalor1intvalor2int pos)
{
   
int divisorComun=0;
   
int n,zsalir=0;

   if(
nDivisores>1){
      *
valor1 = (*Divisores)[pos];
      *
valor2 = (dividendo / *valor1);
      
divisorComun MCD(*valor1, *valor2);
   }else{
      
divisorComun=-1;
   }
   return 
divisorComun;
}
//---------------------------------------------------------------------------

//Funcion para barajar el array de los divisores
void shuffle(int *Divisoresint nDivisores)
{
   
int ijt;

   if (
nDivisores 1)
   {
      for (
0nDivisoresi++)
      {
         
rand() % (nDivisores-1);
         
Divisores[i];
         
Divisores[i] = Divisores[j];
         
Divisores[j] = t;
      }
   }
}
//--------------------------------------------------------------------------- 
Responder Con Cita
  #16  
Antiguo 05-03-2015
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola aguml.

Para que sea un código mas claro y menos proclive a errores, yo creo que es mejor usar malloc/free fuera de la función, sobre todo si la llamas mas de una vez.

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #17  
Antiguo 05-03-2015
engranaje engranaje is offline
Miembro
 
Registrado: may 2011
Posts: 163
Poder: 13
engranaje Va por buen camino
Acerca del nivel 4 y posteriores... a ver si te sirve de ayuda lo que pienso. La cosa es que ya no basta solo con un divisor común. El cociente de dividir el dividendo de la derecha en la linea superior entre el divisor tiene a su vez que ser divisor de ese mismo número y del siguiente número a la derecha... a ver si puedo aclararlo con un pseudográfico.

A B C
D dcAB dcBC F

siendo dcAB el divisor común de A y B, y siendo dcBC el divisor común de B y C hay que comprobar que:

B/dcAB es divisor de C para poder garantizar que es un dcBC. Esto tocará hacerlo para cada elemento no exterior del triangulo de mood que como ves puede incluso suceder que siguiendo un "camino" encuentres divisores comunes para los 2 primeros elementos pero te falle el tercero y debas abandonar este camino.
Responder Con Cita
  #18  
Antiguo 05-03-2015
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Lo he solucionado aunque creo que lo hago de una forma algo diferente a lo que explicas (o eso creo jejeje). Pongo el codigo a ver que os parece:
Código PHP:
#include <stdio.h>
#include <stdlib.h>

int MCD(int aint b);
int ObtenerNumeroDeDivisores(int valor);
void ObtenerListaDivisores(int valorintDivisores);
int ObtenerPareja(int dividendointDivisoresint nDivisoresintvalor1intvalor2int pos);
void shuffle(intDivisoresint nDivisores);

int main()
{
   
int inzmultiplicandomultiplicadordivisorComunnDivisores;
   
int *Divisores;
   
int Resultado[10]={0};
   
int repetidoretval=0posibles=0;
   
int salir;
   
char caracter;

   
//Inicializo la semilla para rand()
   
srand (time(NULL));

   do{
      
//Pido el valor del pico de la piramide
      
printf("Introduce el valor de la cima de la piramide: ");
      
scanf("%d",&Resultado[0]);
      
printf("\n---------------------------------\n");

      
nDivisores ObtenerNumeroDeDivisores(Resultado[0]);

      
Divisores = (int*)malloc(sizeof(int) * nDivisores);

      
//Obtengo todos los divisores del valor del pico de la piramide
      
ObtenerListaDivisores(Resultado[0], Divisores);

      
//Barajo la lista de divisores
      
shuffle(Divisores,nDivisores);

      
retval=0;

      
//Con este bucle puedo calcular todas las posibilidades del segundo nivel de la pirámide
      
for(z=0;z<nDivisores;z++)
      {
         
//Obtengo los dos valores del segundo nivel
         
retval ObtenerPareja(Resultado[0], DivisoresnDivisores, &multiplicando, &multiplicadorz);

         
//Si no hubo error entramos
         
if(retval != -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
            
if(multiplicando divisorComun)
               
multiplicandodivisorComun/multiplicando;
            else
               
multiplicandomultiplicando/divisorComun;

            if(
multiplicador divisorComun)
               
multiplicador divisorComun/multiplicador;
            else
               
multiplicadormultiplicador/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;

            
multiplicador divisorComun;
            
divisorComun MCD(multiplicandomultiplicador);

            
//Calculo los dos extremos del tercer nivel para este MCD
            
if(multiplicando divisorComun)
               
multiplicandodivisorComun/multiplicando;
            else
               
multiplicandomultiplicando/divisorComun;

            if(
multiplicador divisorComun)
               
multiplicador divisorComun/multiplicador;
            else
               
multiplicadormultiplicador/divisorComun;

            
Resultado[6]=multiplicando;
            
Resultado[7]=divisorComun;
            
Resultado[8]=multiplicador;

            if(
Resultado[8] <= Resultado[5] && Resultado[5] % Resultado[8] == 0)
            {
               
Resultado[9]=Resultado[5] / Resultado[8];

               
//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"Resultado[6], Resultado[7], Resultado[8], Resultado[9]); //Me falta calcular esta fila
               
printf("\n---------------------------------\n");
            }
         }
      }

      if(
nDivisores == 2)
         
printf("\nEl valor introducido es primo. Solo se pueden obtener 2 posibilidades.\n");
      else
         
printf("\nSe obtuvieron %i posibles soluciones.\n",posibles);

      
//Libero la memoria reservada para almacenar los divisores para el segundo nivel
      
if(Divisores != NULL)
         
free(Divisores);

      
//Pido que el usuario decida si repetir o salir
      
do{
         
fflush(stdin);
         
printf("\nPresiona 'S' para salir o 'R' para repetir: ");
         
caracter getchar();
      }while(
caracter != 'S' && caracter != 's' && caracter != 'R' && caracter != 'r');

      if(
caracter == 'S' || caracter == 's')
         
salir 1;
      else
         
system("CLS");
   }while(
salir != 1);

   return 
0;
}
//---------------------------------------------------------------------------

//Máximo común divisor de dos números mediante el algoritmo de Euclides.
int MCD(int aint b)
{
   
int auxcr;

   if(
b){
      
aux=b;
      
b=a;
      
a=aux;
   }

   
r=a%b;
   while(
r>0)
   {
      if(
a>b){
         
a=b;
         
b=r;
         
r=a%b;
      }else{
         
b=0;
         break;
      }
   }
   return 
b;
}
//---------------------------------------------------------------------------

//Retorna el numero de divisores posibles
int ObtenerNumeroDeDivisores(int valor)
{
   
int inDivisores=0;

   for(
i=1;i<=valor;i++)
      if(
valor%i==0){
         
nDivisores++;
      }
   return 
nDivisores;
}
//---------------------------------------------------------------------------

//Rellena el array con divisores posibles
void ObtenerListaDivisores(int valorintDivisores)
{
   
int ij=0;

   for(
i=1;i<=valor;i++)
      if(
valor%i==0){
         *(
Divisores+j)=i;
         
j++;
      }
}
//---------------------------------------------------------------------------

//Funcion que obtiene la pareja de numeros para un MCD
int ObtenerPareja(int dividendointDivisoresint nDivisoresintvalor1intvalor2int pos)
{
   
int divisorComun=0;
   
int n,z;

   if(
nDivisores>0){
      *
valor1 = *(Divisores+pos);
      *
valor2 = (dividendo / *valor1);
      
divisorComun MCD(*valor1, *valor2);
   }else{
      
divisorComun=-1;
   }
   return 
divisorComun;
}
//---------------------------------------------------------------------------

//Funcion para barajar el array de los divisores
void shuffle(int *Divisoresint nDivisores)
{
   
int ijt;

   if (
nDivisores 1)
   {
      for (
0nDivisoresi++)
      {
         
rand() % (nDivisores-1);
         
= *(Divisores+i);
         *(
Divisores+i) = *(Divisores+j);
         *(
Divisores+j) = t;
      }
   }
}
//--------------------------------------------------------------------------- 
Responder Con Cita
  #19  
Antiguo 05-03-2015
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Y este para crear la piramide divertida pero de divisiones:
Código PHP:
#include <stdio.h>
#include <stdlib.h>

#define MAXCOUNTBUCLES 10

int ObtenerPosibles(doubleResultadoint posToShow);
void ObtenerNivelDosdoublepResultadodouble cocientedouble divisor);
int ObtenerNivelTres(doublepResultadodouble valor6);
int ObtenerNivelCuatro(doublepResultadodouble valor9);

int main()
{
   
double Resultado[10]={0.0};
   
int posibles=0posToShow;
   
int salir=0;
   
char caracter;

   do{
      
//Pido el valor del pico de la piramide
      
printf("Introduce el valor de la cima de la piramide: ");
      
scanf("%lf",&Resultado[0]);

      
posibles ObtenerPosibles(Resultado,-1);
      
printf("\nSe obtuvieron %i posibles soluciones para un contador maximo para los bucles de %i.\n"posiblesMAXCOUNTBUCLES);

      if(
posibles 0){
         
printf("Introduce el indice de la piramide que deseas mostrar ('0' para mostrar todas): ");
         
scanf("%i",&posToShow);

         
posibles ObtenerPosibles(Resultado,posToShow);
      }

      
//Pido que el usuario decida si repetir o salir
      
do{
         
fflush(stdin);
         
printf("\nPresiona 'S' para salir o 'R' para repetir: ");
         
caracter getchar();
      }while(
caracter != 'S' && caracter != 's' && caracter != 'R' && caracter != 'r');

      if(
caracter == 'S' || caracter == 's')
         
salir 1;
      else
         
system("CLS");
   }while(
salir != 1);

   return 
0;
}
//---------------------------------------------------------------------------

int ObtenerPosibles(doubleResultadoint posToShow)
{
   
int ixnretvalposibles=0;

   for(
i=1;i<MAXCOUNTBUCLES;i++)
   {
      
ObtenerNivelDos(ResultadoResultado[0], i);

      for(
x=1;x<MAXCOUNTBUCLES;x++)
      {
         
retval ObtenerNivelTres(Resultadox);

         if(
retval == 0){
            for(
n=1;n<MAXCOUNTBUCLES;n++)
            {
               
retval ObtenerNivelCuatro(Resultadon);

               if(
retval == 0){
                  
posibles++;
                  if(
posToShow == posibles || posToShow == 0){
                     
//Muestro la pirámide
                     
printf("\n---------------------------------\n");
                     
printf("         %.0lf\n"Resultado[0]);
                     
printf("      %.0lf     %.0lf\n"Resultado[1], Resultado[2]);
                     
printf("   %.0lf     %.0lf     %.0lf\n"Resultado[3], Resultado[4], Resultado[5]);
                     
printf("%.0lf     %.0lf     %.0lf     %.0lf\n"Resultado[6], Resultado[7], Resultado[8], Resultado[9]);
                  }
               }
            }
         }
      }
   }
   if(
posToShow != -1)
      
printf("\n---------------------------------\n");
   return 
posibles;
}
//---------------------------------------------------------------------------

void ObtenerNivelDosdoublepResultadodouble cocientedouble divisor)
{
   *(
pResultado+1) = cociente divisor;
   *(
pResultado+2) = divisor;
}
//---------------------------------------------------------------------------

int ObtenerNivelTres(doublepResultadodouble valor6)
{
   
int retval=-1;

   *(
pResultado+5) = valor6;
   *(
pResultado+4) = *(pResultado+5) * *(pResultado+2);
   if(*(
pResultado+4) <= *(pResultado+1)){
      *(
pResultado+3) = *(pResultado+1) * *(pResultado+4);
      
retval 0;
   }
   return 
retval;
}
//---------------------------------------------------------------------------

int ObtenerNivelCuatro(doublepResultadodouble valor9)
{
   
int retval=-1;

   *(
pResultado+9) = valor9;
   *(
pResultado+8) = *(pResultado+9) * *(pResultado+5);
   if(*(
pResultado+8) <= *(pResultado+4)){
      *(
pResultado+7) = *(pResultado+4) * *(pResultado+8);
      if(*(
pResultado+7) <= *(pResultado+3)){
         *(
pResultado+6) = *(pResultado+3) * *(pResultado+7);
         
retval 0;
      }
   }
   return 
retval;
}
//--------------------------------------------------------------------------- 
¿que os parece? La verdad es que no soy programador profesional, todo lo que se lo he aprendido por libre porque siempre me ha apasionado la programacion y para mi plantearme hacer un codigo es como para otros hacer un sudoku, me divierte y me entretiene y hay veces (muchas) que tengo que pedir ayuda porque me atasco .
Responder Con Cita
  #20  
Antiguo 05-03-2015
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Esta es la idea con la que empezó todo, vi una imagen en internet donde aparecia una esfinge con 4 piramides de estas y se me ocurrio hacer una estrella y al final puedo poner tanto multiplicaciones como divisiones jejeje.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Generar base de datos en MSSQL a partir de un Esquema XML Ledian_Fdez SQL 1 17-05-2013 10:59:17
Piramide Poblacional, como? El_Raso Varios 0 13-04-2009 20:35:54
Restaurar base de datos a partir de un MDF erickperez6 MS SQL Server 1 16-08-2007 21:11:40
como mostrar una ventana con base al resultado de una busqueda Nelly Varios 3 02-02-2006 18:16:20
Como saber el tipo de componentes a partir de un string? Roger OOP 2 02-04-2004 13:21:48


La franja horaria es GMT +2. Ahora son las 05:28:24.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi