Ver Mensaje Individual
  #81 (permalink)  
Antiguo 04/12/2014, 08:46
eferion
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 7 meses
Puntos: 204
Respuesta: Petando la pila. Problemas y retos usando recursividad.

Es un poquito más largo que los últimos que habéis puesto... dado que ya todos habíais puesto vuestras versiones he intentado diferenciarme un poco de lo que se estaba haciendo hasta ahora.

Código C++:
Ver original
  1. #define SWAP(a,b) { int c = *a; *a = *b; *b = c; }
  2.  
  3. const int _factor[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000 };
  4.  
  5. typedef struct _data
  6. {
  7.   int length;
  8.   int digits[15];
  9.   int* endPtr;
  10. } Data;
  11.  
  12. void toArray( int number, Data* data )
  13. {
  14.   if ( number > 0 )
  15.   {
  16.     *data->endPtr = number % 10;
  17.     ++data->endPtr;
  18.     ++data->length;
  19.     toArray( number/10, data );
  20.   }
  21. }
  22.  
  23. int factorial( int n )
  24. {
  25.   if ( n == 2 )
  26.     return 2;
  27.   else
  28.     return n * factorial( n - 1 );
  29. }
  30.  
  31. int toInt( int* first, int* last, const int* factor )
  32. {
  33.   if ( first != last )
  34.   {
  35.     if ( *first )
  36.       return *first * *factor + toInt( first + 1, last, factor + 1 );
  37.     else
  38.       return toInt( ++first, last, factor + 1 );
  39.   }
  40.   else
  41.     return 0;
  42. }
  43.  
  44. void reverse( int* first, int* last )
  45. {
  46.   if ( first <= --last )
  47.   {
  48.     SWAP( first, last );
  49.     reverse( ++first, last );
  50.   }
  51. }
  52.  
  53. int* findLessThan( int* cursor, int* toCompare )
  54. {
  55.   if ( *--cursor > *toCompare )
  56.     return cursor;
  57.  
  58.   return findLessThan( cursor, toCompare );
  59. }
  60.  
  61. void permutation( int* first, int* last, int* cursor )
  62. {
  63.   int* lastCursor = cursor--;
  64.  
  65.   if ( *cursor < *lastCursor )
  66.   {
  67.     int* ptr = findLessThan( last, cursor );
  68.     SWAP( cursor, ptr );
  69.     reverse( lastCursor, last );
  70.   }
  71.   else if ( cursor != first )
  72.     permutation( first, last, cursor );
  73.   else
  74.     reverse( first, last );
  75. }
  76.  
  77. bool es_vampiro( int num, Data* data, int maxPermutaciones )
  78. {
  79.   int* mid = &data->digits[ data->length / 2 ];
  80.   int int1 = toInt( data->digits, mid, _factor );
  81.   int int2 = toInt( mid, data->endPtr, _factor );
  82.  
  83.   if ( ( *data->digits || *mid ) && int1 * int2 == num )
  84.     return true;
  85.  
  86.   if ( --maxPermutaciones )
  87.   {
  88.     permutation( data->digits, data->endPtr, data->endPtr - 1 );
  89.     return es_vampiro( num, data, maxPermutaciones );
  90.   }
  91.  
  92.   return false;
  93. }
  94.  
  95. int es_vampiro( int num )
  96. {
  97.   Data data;
  98.   data.length = 0;
  99.   data.endPtr = data.digits;
  100.   toArray( num, &data );
  101.  
  102.   if ( data.length % 2 )
  103.     return 0;
  104.  
  105.   return es_vampiro( num, &data, factorial( data.length ) )? 1 : 0;
  106. }

Un saludo.