Ver Mensaje Individual
  #42 (permalink)  
Antiguo 29/11/2014, 03:37
amchacon
 
Fecha de Ingreso: julio-2012
Mensajes: 375
Antigüedad: 12 años, 4 meses
Puntos: 28
Respuesta: Petando la pila. Problemas y retos usando recursividad.

Cita:
Iniciado por leosansan Ver Mensaje
¡¡¡ A petarla ¡¡¡

Reconozco que la primera idea ha sido la de usar a la de usar bruta, pero me he contenido y he preferido dejarlo para otra ocasión Así que he optado por un camino más rebuscado, sencillamente a lo que a primera vista invita el reto.

Y es que si un número es de, por ejemplo seis cifras, tan sólo hay un número de variaciones de 6^3 variaciones tomadas las cifras de tres en tres, lo que da tan solo 216 casos posibles. Una vez obtenidas tan solo hay que ir multiplicándolas entre sí a ver si sale el número original,

Las dificultades inherentes ha sido obtener las variaciones y "bambolear" el array de cifras de una función a otra.

Cumple los cometidos encomendados, no valen dos grupos de cifras terminados ambos en cero y filtro aquellos que empiecen por cero por ser en realidad números de dos cifras.

Con estas ideas básicas sale el siguiente código:

Código C++:
Ver original
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. int esVampiro ( int num ) ;
  6. void variaciones_sin_repe ( char numero [ ] , int tam , int permutacioneS , char aux [ ] , char Npermutacion [ permutacioneS ][ tam + 1 ] , int n0 , int n ) ;
  7.  
  8. int main( void ) {
  9.   int num = 939658 ;
  10.   return printf ( "\n!!! Como lo quiere Pantalaimon ( 0 - 1 ) !!! ==> : [%d]\n\n" , esVampiro ( num ) ) , 0 ;
  11. }
  12.  
  13. int esVampiro (  num ) {
  14.   int i , j , n , tam , permutacioneS = 1 , num0 = num ;
  15.   for ( tam = 1 ; num0 ; tam++ , num0 /= 10 ) ;
  16.   char numero [ tam + 1 ] ;
  17.   if ( tam %2 == 0 )
  18.     return puts ( "NO ES VAMPIRO por numero impar de cifras." ) , 0 ;
  19.   itoa ( num , numero , 10 ) ;
  20.   n = tam / 2 ;
  21.   for( i = 1 , permutacioneS *= (tam-1) ; i <  n ; ++i , permutacioneS *= (tam-1));
  22.   char aux [ tam + 1 ] , Npermutacion [ permutacioneS ][ tam + 1 ] ;
  23.   variaciones_sin_repe ( numero , tam , permutacioneS , aux , Npermutacion , n, n ) ;
  24.   for( i = 0 ; i < permutacioneS ; i++ )
  25.     for( j = 0 ; j < permutacioneS ; j++ )
  26.       if ( ( Npermutacion [ i ][ tam ] == 0 && Npermutacion [ i ][ tam ] == 0 ) || ( Npermutacion [ i ][ 0 ] == 0 && Npermutacion [ i ][ 0 ] == 0 ) )
  27.         continue ;
  28.       else if ( atoi ( Npermutacion [ i ] ) * atoi ( Npermutacion [ j ] ) == num  ) {
  29.         return printf ( "\nES VAMPIRO: %d = %d * %d\n" , atoi ( Npermutacion [ i ] ) * atoi ( Npermutacion [ j ] ) , atoi ( Npermutacion [ i ] ) , atoi ( Npermutacion [ j ] ) ) , 1 ;
  30.   }
  31.   return puts ( "NO ES VAMPIRO" ) , 0 ;
  32. }
  33.  
  34. void variaciones_sin_repe( char numero [ ] , int tam , int permutacioneS , char aux [ ] , char Npermutacion [ permutacioneS ][ tam + 1 ] , int n0 , int n ){
  35.   int  i ;
  36.   static int j = 0 , permutaciones = 1  ;
  37.   if( n != 0 )
  38.     for( i = 0 ; i < tam - 1 ; ++i ) {
  39.       aux [ j ] = numero [ i ] ;
  40.       ++j ;
  41.       variaciones_sin_repe ( numero , tam , permutacioneS , aux, Npermutacion , n0 , n - 1 );
  42.       --j;
  43.     }
  44.   else {
  45.     aux [ n0 ] = '\0' ;
  46.     strcpy ( Npermutacion [ permutaciones - 1 ] , aux ) ;
  47.     permutaciones++ ;
  48.   }
  49. }

Ha sido rapidito y queda a expensas de mejoras, pero me quería adelantar por una vez.

Se puede comprobar que 126000 lo da como no vampiro, pero si desactivas el if de los números que termina en cero, dará lógicamente que sí lo es. Pero como no es vampiro no lo da como tal.

Espero que la originalidad de la idea sea merecedora de los tan apreciados usuarios.

A la espera de las críticas y/o correcciones quedo.

P.D: amchacon no me he olvidado de tí. A ver si mañana mismo te mando un mp.
Vaya código tan grande te ha salido Leo.

El uso de variables estáticas no me convence mucho, y bueno los bucles habría que quitarlos tramposo ;)

Cita:
Iniciado por Pantaláimon Ver Mensaje
Edit: NOTA IMPORTANTE: la firma para noRep en C++ puede tener la variante
Código C++:
Ver original
  1. std::string noRep(const std::string&);
. Antes me he colado y he puesto la firma pasando el parámetro por valor.

Un saludo!
Tal y como está definido es irresoluble de forma recursiva, no hay ninguna variable con la que puedes jugar ahí.

Si le quitaras el const si se podría hacer algo...