Cita:
Iniciado por Pantaláimon Bien, bien leosan
Aún no me lo he mirado con profundidad pero remitiéndome al primer post que puse:
aún debes corregir ciertas cosas para que sea válido!
Un saludo!
Buuueno, pero que conste que es de lo más efectivo el código anterior.
Pero las reglas son las reglas y las has puesto tú aunque un poco de manga ancha no vendría mal.
Para que no se diga: sin un for ni do ni while ni goto. Tutti con funciones recursivas, y son unas cuantas para que no se diga.
La idea es usar la fuerza bruta, pero de forma proporcional.
* Obtengo el tamaño del número, vamos sus dígitos.
* Saco los valores mínimo y máxima que pueden alcanzar los dos números que multiplicados nos darán el número original.
* Pruebo los posibles productos a partir de los valores anteriores que nos puedan dar el número.
* Obtenido cualquier posibilidad, compruebo que los dígitos que componen los números parciales se corresponden con el número original: si es sí, O.k, es Vampiro y si no, no lo es.
Sencillito, ¿ verdad ? y todo usando una "nomenclatura" que puedan seguir los usuarios menos avanzados. De ahí que me haya molestado en poner nombres muy descriptivos a las variables....
eferion estará muy contento por ello.
¡¡¡ Ahí va el "pedazo" de código:
Código C++:
Ver original#include <stdio.h>
#include <stdlib.h>
int cantidadDigitos ( int num ) ;
int esVampiro ( int numero ) ;
int obtenerNumMinimo ( int digitos ) ;
int obtenerNumMaximo ( int digitos ) ;
int probar ( int numero , int num_1 , int num_0 , int n_minimo , int n_maximo , int digitos , int DigitosNumero [ 10 ] ) ;
int DigitosNumero ( int digitosNumero [ 10 ], int numero , int flag ) ;
int main ( ) {
int numero = 939658 ; /** 939658 = 953 * 986 **/
return printf ( "\n!!! Como lo quiere Pantalaimon ( 0 - 1 ) !!! ==> : [%d]\n\n" , esVampiro
( numero
) ) , 0 ; return 0;
}
int cantidadDigitos ( int num ) {
return ( num == 0 ) ? 0 : 1 + cantidadDigitos ( num / 10 ) ;
}
int obtenerNumMinimo ( int digitos ) {
return ( digitos == 0 ) ? 1 : 10 * obtenerNumMinimo ( - 1 + digitos ) ;
}
int obtenerNumMaximo ( int digitos ) {
return ( digitos == 0 ) ? 1 : 10 * obtenerNumMinimo ( - 1 + digitos ) ;
}
void inicializar_digitosNumero ( int digitosNumero [ 10 ] , int indice ) {
if ( indice < 10 )
digitosNumero [ indice ] = 0 , inicializar_digitosNumero ( digitosNumero , indice + 1 ) ;
}
int DigitosNumero ( int digitosNumero [ 10 ], int numero , int flag ) {
if ( numero > 0 && flag == 0 )
digitosNumero [ numero % 10 ]++ , DigitosNumero ( digitosNumero , numero / 10 , 0 ) ;
else if ( numero > 0 && flag == 1 )
digitosNumero [ numero % 10 ]-- , DigitosNumero ( digitosNumero , numero / 10 , 1 ) ;
if ( digitosNumero [ numero % 10 ] < 0 )
return 0 ;
else return 1 ;
}
int ComprobarDigitos ( int digitosNumero [ 10 ] , int indice , int cont ) {
if ( indice < 10 )
if ( digitosNumero [ indice ] == 0 )
return 1 + ComprobarDigitos ( digitosNumero , indice + 1 , cont + 1 ) ;
else return
ComprobarDigitos ( digitosNumero , indice + 1 , cont ) ;
return 0 ;
}
int esVampiro ( int numero ) {
int i , indice = 0 , n_maximo , n_minimo , numero_0 , numero_1 , digitos , digitosNumero [ 10 ] ;
inicializar_digitosNumero ( digitosNumero , indice ) ;
DigitosNumero ( digitosNumero , numero , 0 ) ;
digitos = cantidadDigitos ( numero ) ;
if ( digitos %2 != 0 )
return puts ( "\n\n\tNO ES VAMPIRO por numero impar de cifras.\n\n" ) , 0 ; n_minimo = obtenerNumMinimo ( - 1 + digitos / 2 ) ;
n_maximo = obtenerNumMaximo ( digitos / 2 ) ;
numero_0 = numero_1 = n_minimo ;
return probar ( numero , numero_1 , numero_0 , n_minimo , n_maximo , digitos , digitosNumero ) ;
}
int probar ( int numero , int num_1 , int num_0 , int n_minimo , int n_maximo , int digitos , int digitosNumero [ 10 ] ) {
int i , indice = 0 , flag = 0 ;
if ( num_1 < n_maximo - 1 && num_0 == n_maximo )
num_0 = n_minimo , num_1 = numero / n_maximo ;
if ( num_0 == n_maximo - 1 )
return printf ( "\n\n\t::%d NO ES VAMPIRO\n\n" , numero
) , 0 ; if ( num_0 < n_maximo ){
num_1 = numero / num_0 ;
if ( num_0 * num_1 == numero ) {
inicializar_digitosNumero ( digitosNumero , 0 ) ;
DigitosNumero ( digitosNumero , numero , 0 ) ;
if ( num_0 * num_1 == numero ) {
DigitosNumero ( digitosNumero , num_0 , 1 ) ;
DigitosNumero ( digitosNumero , num_1 , 1 ) ;
if ( ComprobarDigitos ( digitosNumero , 0 , 0 ) == 10 && ( num_0 % 10 != 0 || num_1 % 10 != 0 ) )
return printf ( "\n\n\tES VAMPIRO: %d = %d * %d\n\n" , numero
, num_1
, num_0
) , 1 ; }
}
return probar ( numero , num_1 , 1 + num_0 , n_minimo , n_maximo , digitos , digitosNumero ) ;
}
}
Lo he testeado un ratito así que espero no tenga bugs y si no ya me lo dirán.....
Por cierto, dar la bienvenida a kspr, HackmanC y amchacon por su incorporación a los retos.
Notita::1:: HaxkmanC no me da como vampiro el "939658".
Notita::2:: Cita: amchcon:: 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 ;)
Pues el código es increiblemente eficiente comparado con los otros propuestos. Pero ya ves que me he aplicado y pongo ahora uno "sin trampas", campeón. Yo por lo menos me he lanzado a por el difícil, je,je.
Por cierto, paso una breve lista de números vampiros:
Código C++:
Ver original1395=15*93
1260=21*60
1827=21*87
2187=27*81
1530=30*51
1435=35*41
6880=80*86
108135=135*801
129640=140*926
118440=141*840
136948=146*938
105750=150*705
139500=150*930
115672=152*761
125248=152*824
146952=156*942
110758=158*701
116725=161*725
156915=165*951
117067=167*701
162976=176*926
129775=179*725
102510=201*510
120600=201*600
126027=201*627
180297=201*897
105264=204*516
125460=204*615
105210=210*501
126000=210*600
182700=210*870
190260=210*906
192150=210*915
136525=215*635
186624=216*864
211896=216*981
172822=221*782
180225=225*801
182250=225*810
123354=231*534
125433=231*543
135828=231*588
173250=231*750
175329=231*759
156240=240*651
125460=246*510
218488=248*881
229648=248*926
125500=251*500
152608=251*608
215860=251*860
201852=252*801
205785=255*807
104260=260*401
126846=261*486
152685=261*585
156289=269*581
226498=269*842
218700=270*810
197725=275*719
226872=276*822
124483=281*443
182650=281*650
262984=284*926
251896=296*851
150300=300*501
153000=300*510
131242=311*422
133245=315*423
134725=317*425
146137=317*461
296320=320*926
217638=321*678
312975=321*975
132430=323*410
216733=323*671
260338=323*806
193257=327*591
319536=336*951
233896=338*692
213466=341*626
329346=342*963
140350=350*401
143500=350*410
253750=350*725
135837=351*387
145314=351*414
315900=351*900
319059=351*909
153436=356*431
329656=356*926
336960=360*936
346968=366*948
361989=369*981
174370=371*470
369189=381*969
371893=383*971
338296=392*863
362992=392*926
193945=395*491
163944=396*414
284760=420*678
245182=422*581
304717=431*707
312475=431*725
378418=431*878
384912=432*891
378450=435*870
263074=437*602
404968=446*908
241564=461*524
429664=464*926
386415=465*831
286416=468*612
416988=468*891
254740=470*542
378400=473*800
447916=476*941
428980=482*890
284598=489*582
414895=491*845
326452=524*623
336550=530*635
341653=533*641
365638=533*686
315594=534*591
456840=540*846
489955=545*899
458640=546*840
489159=549*891
536539=563*953
475380=570*834
529672=572*926
368550=585*630
559188=588*951
498550=590*845
392566=593*662
486720=624*780
538650=630*855
416650=641*650
457600=650*704
568750=650*875
638950=650*983
567648=657*864
629680=680*926
516879=681*759
673920=720*936
679500=750*906
736695=765*963
769792=776*992
729688=788*926
688000=800*860
794088=807*984
789525=825*957
738468=843*876
792585=855*927
815958=858*951
789250=875*902
809919=891*909
841995=891*945
809964=894*906
829696=896*926
939658=953*986
¡¡¡Saluditos!!!
Puntitos Puntitos
Me gusta me gusta [/QUOTE]