Foro de elhacker.net

Programación => Programación Visual Basic => Mensaje iniciado por: raul338 en 18 Agosto 2010, 14:54 pm



Título: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: raul338 en 18 Agosto 2010, 14:54 pm
Hooola!

No sabia si presentar esto como reto o no (?)

Código:
http://gaussianos.com/la-conjetura-del-196/
http://en.wikipedia.org/wiki/Lychrel_number

Ahi esta, tienen que hacer una funcion booleana que calcule los numeros capicuas a partir de este, con un numero maximo de vueltas, para calcular si es de Lychrel o no :P Ademas de devolver el numero final dado

La firma debe ser asi:

Código
  1. Public Function IsLychrelNumber(numero As Double, ByRef numeroFinal As Double,Optional maxVueltas As Long = 20) As Boolean
  2.  

Si no se logra dar el numero de vueltas en menos de maxVueltas se toma como si fuera numero de Lychrel (aunque el numero este en la vuelta 21 :¬¬)

NOTA: Cabe aclarar que debe devolver True cuando no se encuentra el numero capicua  :silbar:

El tiempo se medira con la clase CTiming ya publicada en retos anteriores...

Ahora si! A codear!


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: Psyke1 en 18 Agosto 2010, 14:55 pm
Me apunto raul!! :D

DoEvents¡! :P


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: [D4N93R] en 18 Agosto 2010, 15:36 pm
Tiene que ser en VB? xD


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: isseu en 18 Agosto 2010, 16:13 pm
lo hare más tarde, pero en c++


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: Novlucker en 18 Agosto 2010, 16:15 pm
Ya lo hice, ahora lo tengo que modificar :xD
Dada la manera en que se calcula el número, probando incluso con 89 (es uno de los ejemplos de wikipedia) se desborda, no sirven los long :xD

Saludos


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: raul338 en 18 Agosto 2010, 16:49 pm
Corregido! Puse como double los tipos de datos, asi no hay desbordamientos :P


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: 79137913 en 18 Agosto 2010, 16:52 pm
HOLA!!!

Que bueno acabo de leer el post de novlucker y me saco las dudas

Gracias!!!


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: Novlucker en 18 Agosto 2010, 16:56 pm
Código
  1. Function IsLychrelNumber(numero As Double, ByRef numeroFinal As Double, Optional maxVueltas As Long = 20) As Boolean
  2.  
  3. Dim i As Long
  4. numeroFinal = numero
  5.  
  6. For i = 0 To maxVueltas
  7. numeroFinal = numeroFinal + CDbl(StrReverse(CStr(numeroFinal)))
  8. If (numeroFinal = CDbl(StrReverse(CStr(numeroFinal)))) Then Exit Function
  9. Next
  10. IsLychrelNumber = True
  11.  
  12. End Function

Entendí que numeroFinal era el último generado, así que comienzo con ese, sino lo quito y no lo uso :xD
De cualquier manera, esto sigue siendo funcional para números "pequeños", sino hay que hacer la suma mediante strings.

Saludos


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: raul338 en 18 Agosto 2010, 17:29 pm
Optimizando me quedo como la de novlucker!! :xD

Se me habia ocurrido comprar solo dando vuelta "despues de la mitad" del numero, pero... era mas lento ._.

Aca esta, se podria decir que es practicamente igual a la de novlucker, solo que esta funciona aun para numeros grandes :xD

Código
  1. Public Function EsLychrel(ByVal numero As Double, ByRef numeroFinal As Double, Optional maxVueltas As Long = 100) As Boolean
  2.    Dim i As Long ' FAIL: As Integer xDDDD
  3.    numeroFinal = Abs(numero) ' No permito numeros negativos
  4.    If numero = CDbl(StrReverse(numero)) Then Exit Function ' Si el numero ya es capicua, para que me gasto? xD
  5.    numeroFinal = Val(numero) ' Quito los decimales
  6.    maxVueltas = Abs(maxVueltas) ' 1 a -10 (sumando 1) es imposible xDDD, quito los negativos
  7.    For i = 1 To maxVueltas
  8.        ' Sumo el normal y el numero al revez, poniendo formato numerico comun
  9.        numeroFinal = numeroFinal + CDbl(StrReverse(FormatNumber(numeroFinal, 0, vbTrue, vbFalse, vbFalse)))
  10.        ' Comparo si es el mismo :P
  11.        If FormatNumber(numeroFinal, 0, vbTrue, vbFalse, vbFalse) = StrReverse(FormatNumber(numeroFinal, 0, vbTrue, vbFalse, vbFalse)) Then Exit Function
  12.    Next
  13.    EsLychrel = True
  14. End Function
  15.  

EDIT: Hecho en 56957,0293718157 ms, 10 To 100000, maxVueltas = 1000 (con DoEvents entre calculo de cada numero :xD)


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: Novlucker en 18 Agosto 2010, 17:37 pm
Dudo que tan grandes, la variable numeroFinal tiene un límite y ahí crashea.
Además, los códigos funcionan porque tiene el maxVueltas bajo, donde lo agrandes muere :xD

[Edito]: El mío crashea con números más chicos xD

Saludos


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: [D4N93R] en 18 Agosto 2010, 17:44 pm
Ahí se los dejo, n se que tan weno sea eso, porque ni lo probé, no se si funciona en VB6 xD

me avisan xD
Código
  1. Public Function IsLychrelNumberDanger(ByVal numero As Double, ByRef numeroFinal As Double, ByRef actualit As Integer, Optional ByVal maxVueltas As Long = 60) As Boolean
  2.        actualit = actualit + 1
  3.        Dim original As String
  4.        original = CStr(numero)
  5.        Dim reverse As String
  6.        reverse = StrReverse(original)
  7.  
  8.        If original = reverse Then
  9.            IsLychrelNumberDanger = False
  10.        End If
  11.  
  12.        If actualit = maxVueltas Then
  13.            IsLychrelNumberDanger = True
  14.        End If
  15.        numeroFinal = CDbl(reverse) + numero
  16.        IsLychrelNumberDanger = IsLychrelNumberDanger(numeroFinal, numeroFinal, actualit, maxVueltas)
  17. End Function
  18.  
  19.  


Saludos!

PD: Primero y ultimo que hago en VB xD
PD2: gracias a raul por portar el code a vb6 xD


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: Novlucker en 18 Agosto 2010, 17:49 pm
Ahora entiendo por que decías que no servía cuando lo pasabas de VB.NET a VB6 :xD

El de raul338 es el "más válido", a la próxima le pongo todas las verificaciones esas, yo simplemente las omití porque entendí que los números de prueba iban a ser válidos para la función :P

Saludos


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: raul338 en 18 Agosto 2010, 17:51 pm
jajaja las validaciones las agregue al final :P

D4N93R propone agregar un parametro con el numero de iteraciones dado para llegar al resultado final, que dicen, lo ponemos? (seria devolver i en mi caso :xD)


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: Novlucker en 18 Agosto 2010, 17:54 pm
Eso es porque necesita una excusa para poder agregar una parámetro más a la función, el que usa para la recursividad :xD

Saludos


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: Tokes en 18 Agosto 2010, 20:35 pm
Buen día, gente. Aquí les dejo mi aporte:

Código:
Private Function EsNumLychrel4(ByVal num As Long, ByRef numeroFinal, Optional ByVal iteraciones As Long = 50) As Boolean
Dim n As Double, snrev As String
    If num And &H80000000 Then Exit Function
    n = num
    Do While iteraciones > 1
        snrev = StrReverse(n)
        If CStr(n) = snrev Then Exit Function
        n = n + CDbl(snrev)
        iteraciones = iteraciones - 1
    Loop
    snrev = StrReverse(n)
    If CStr(n) = snrev Then Exit Function
    EsNumLychrel4 = True
    numeroFinal = n
End Function

Por el momento es todo. Saludos.


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: Tokes en 18 Agosto 2010, 20:51 pm
Aquí les dejo otra versión que según yo es más rápida.

Código:
Private Function EsNumLychrel5(ByVal num As Long, ByRef numeroFinal, Optional ByVal iteraciones As Long = 50) As Boolean
Dim n As Double, nrev As Double
    If num And &H80000000 Then Exit Function
    n = num
    Do While iteraciones > 1
        nrev = CDbl(StrReverse(n))
        If n = nrev Then Exit Function
        n = n + nrev
        iteraciones = iteraciones - 1
    Loop
    nrev = CDbl(StrReverse(n))
    If n = nrev Then Exit Function
    EsNumLychrel5 = True
    numeroFinal = n
End Function

          ¡Buen día!


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: Karcrack en 18 Agosto 2010, 20:53 pm
No me da tiempo a leerme la documentacion ni nada, pero veo que estais dando la vuelta al numero usando cadenas... Esto puede que os ayude a mejorar la velocidad :)

Código:
Public Function lngReverse(ByVal lLong As Long) As Long
    Do
        lngReverse = (lngReverse * 10) + (lLong Mod 10)
        lLong = lLong \ 10
    Loop While lLong > 0
End Function

Saludos ;)


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: BlackZeroX en 18 Agosto 2010, 21:15 pm

Despues de que se me trabo la inche PC reice mi codigo aqui esta!¡.

Código
  1.  
  2. Public Function IsLychrelNumberBlackZeroX(ByVal InVal As Double, ByRef OutValEnd As Double, Optional InMaxVueltas As Long = 20) As Boolean
  3.    If InVal And &H80000000 Then Exit Function
  4.    OutValEnd = InVal
  5.    Do Until OutValEnd > 9
  6.        OutValEnd = OutValEnd + OutValEnd
  7.        InMaxVueltas = InMaxVueltas - 1
  8.    Loop
  9.    Do Until InMaxVueltas < 1 'Or IsLychrelNumberBlackZeroX = True
  10.        InVal = StrReverse(OutValEnd) + 0
  11.        IsLychrelNumberBlackZeroX = InVal - OutValEnd = 0
  12.        If IsLychrelNumberBlackZeroX Then Exit Do
  13.        OutValEnd = OutValEnd + InVal
  14.        InMaxVueltas = InMaxVueltas - 1
  15.    Loop
  16.    IsLychrelNumberBlackZeroX = True
  17. End Function
  18.  
  19.  

Ducles Lunas!¡.


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: Psyke1 en 18 Agosto 2010, 21:32 pm
Citar
Código
  1. InVal = StrReverse(OutValEnd) + 0
Le sumas cero por algo en particular?¿

DoEvents¡! :P


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: BlackZeroX en 18 Agosto 2010, 21:45 pm
strreverse devuelve un string yo a ese string le sumo 0 para pasarlo a numero, igual como le hago en C...

aqui lo dejo corregido

Version 2.
Código
  1. Public Function IsLychrelNumberBlackZeroX02(ByVal InVal As Double, ByRef OutValEnd As Double, Optional InMaxVueltas As Long = 20) As Boolean
  2.    If InVal And &H80000000 Then Exit Function
  3.    OutValEnd = InVal
  4.    Do Until OutValEnd > 9
  5.        OutValEnd = OutValEnd + OutValEnd
  6.        InMaxVueltas = InMaxVueltas - 1
  7.    Loop
  8.    Do Until InMaxVueltas < 1 'Or IsLychrelNumberBlackZeroX = True
  9.        InVal = StrReverse(OutValEnd) + 0
  10.        If InVal - OutValEnd = 0 Then Exit Do
  11.        OutValEnd = OutValEnd + InVal
  12.        InMaxVueltas = InMaxVueltas - 1
  13.    Loop
  14.    IsLychrelNumberBlackZeroX02 = True
  15. End Function
  16.  
  17.  

Version 3.
Código
  1.  
  2. Public Function IsLychrelNumberBlackZeroX03(ByVal InVal As Double, ByRef OutValEnd As Double, Optional InMaxVueltas As Long = 20) As Boolean
  3. Dim tmp             As Double
  4.    If InVal And &H80000000 Then Exit Function
  5.    OutValEnd = InVal
  6.    Do Until OutValEnd > 9
  7.        OutValEnd = OutValEnd + OutValEnd
  8.        InMaxVueltas = InMaxVueltas - 1
  9.    Loop
  10.    Do Until InMaxVueltas < 1
  11.        tmp = OutValEnd: InVal = 0
  12.        Do
  13.            InVal = (InVal * 10) + (tmp Mod 10)
  14.            tmp = tmp \ 10
  15.        Loop While tmp > 0
  16.        If InVal - OutValEnd = 0 Then Exit Do
  17.        OutValEnd = OutValEnd + InVal
  18.        InMaxVueltas = InMaxVueltas - 1
  19.    Loop
  20.    IsLychrelNumberBlackZeroX03 = True
  21. End Function
  22.  
  23.  

Dulces Lunas!¡.


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: Psyke1 en 18 Agosto 2010, 22:28 pm
Interesante, no conozco esos truquillos, supongo que es mas rapido que convertirlo con CDbl(), no?¿

DoEvents¡! :P


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: Karcrack en 18 Agosto 2010, 22:32 pm
Deberia ser mas rapida mi funcion de lngReverse() que el StrReverse()... Alguien ha provado? XD


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: BlackZeroX en 18 Agosto 2010, 22:45 pm

no comprove coherencias!¡, por lo cual no comprove que estubieran bien dichas funciones

Código
  1.  
  2. Tokes: 128,759 msec
  3. [D4N93R]: 10.388,359 msec
  4. Raul338: 308,872 msec
  5. Novlucker : 131,863 msec
  6. BlackZeroX (v 2): 96,643 msec
  7. BlackZeroX (v 3): 35,655 msec
  8.  
  9.  

http://infrangelux.sytes.net/FileX/index.php?file=/BlackZeroX/Comprovaciones/Lychrel/Gral%20Lychrel%2001.zip&dir=/BlackZeroX/Comprovaciones/Lychrel&

P.D.: En efecto Karcrack es mas rapido!¡.

Dulces Lunas!¡.


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: Tokes en 18 Agosto 2010, 23:29 pm
Aquí dejo un nuevo código, basado en la función que nos mostró Karcrack.

Código:
Private Function EsNumLychrel5(ByVal num As Long, ByRef numeroFinal, Optional ByVal iteraciones As Long = 50) As Boolean
Dim n As Double, nrev As Double, sp As String
    If num And &H80000000 Then Exit Function
    n = num
    sp = "1234"
    Do While iteraciones > 1
        nrev = dblReverse(n)
        If n = nrev Then Exit Function
        n = n + nrev
        iteraciones = iteraciones - 1
    Loop
    nrev = dblReverse(n)
    If n = nrev Then Exit Function
    EsNumLychrel5 = True
    numeroFinal = n
End Function

Y la función de Karcrack (modificada para que pueda manejar doubles y no sólo longs):

Código:
Public Function dblReverse(ByVal lDbl As Double) As Double
    Do
        dblReverse = dblReverse * 10 + (lDbl - (10 * Fix(lDbl / 10)))
        lDbl = Fix(lDbl / 10)
    Loop While lDbl > 0
End Function

     Efectivamente es más rápido.

     Saludos....
     Y muchas gracias Karcrack.


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: BlackZeroX en 18 Agosto 2010, 23:44 pm

BlackZeroX (v 3)

esta en base a la funcion de Karcrack xP


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: raul338 en 19 Agosto 2010, 00:14 am
porque siempre las mias es una de las mas lentas? :xD

bueno, con la base de Karcrack y tokes, me quedo esto, un poquitin mas rapido que la de tokes :P pero muchisimo mas rapida que la mia anterior

Código
  1. Public Function EsLychrel02(ByVal numero As Double, ByRef numeroFinal As Double, Optional maxVueltas As Long = 100) As Boolean
  2.    If &H80000000 And maxVueltas Then Exit Function
  3.    If numero < 10 Then Exit Function
  4.    numeroFinal = numero
  5.  
  6.    numero = dblReverse(numeroFinal)
  7.    If numeroFinal = numero Then
  8.        numeroFinal = numero + numero
  9.        Exit Function
  10.    End If
  11.  
  12.    For maxVueltas = maxVueltas To 1 Step -1
  13.        numero = dblReverse(numeroFinal)
  14.        If numeroFinal = numero Then Exit Function
  15.        numeroFinal = numeroFinal + numero
  16.    Next
  17.    EsLychrel02 = True
  18. End Function
  19.  


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: Tokes en 19 Agosto 2010, 00:29 am
Disculpen, hace rato puse mi código pero con instrucciones basura que nada que ver con el proceso (era para probar ciertas funciones). Aquí se los dejo corregido. Tiene prácticamente la misma velocidad de antes, pero sin ese código basura.

Código:
Private Function EsNumLychrel5(ByVal num As Long, ByRef numeroFinal As Double, Optional ByVal iteraciones As Long = 50) As Boolean
Dim n As Double, nrev As Double
    If num And &H80000000 Then Exit Function
    n = num
    Do While iteraciones > 0
        nrev = dblReverse(n)
        If n = nrev Then Exit Function
        n = n + nrev
        iteraciones = iteraciones - 1
    Loop
    nrev = dblReverse(n)
    If n = nrev Then Exit Function
    EsNumLychrel5 = True
    numeroFinal = n
End Function


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: LeandroA en 19 Agosto 2010, 00:47 am
creo que por el momento la unica que funciona bien es la de Novlucker las demas no esta trabajando correctamente

solo tengo mis dudas con la de Novlucker  con los numeros del 1 al 9 ya que dan numeros simples y no se cumple la condición de capicua

la de raul338  tambien anda bien con el mismo problea que el de Novlucker   y tambien pero hay un problema con el 11 ya que da como resultado 11 cuando deberia ser 22


@BlackZeroX

 0 = blucle infinito
la funcion deve devolver true si no se logra el capicua en los determinados ciclos
tambien el problema del 1 al 10 pero peor, muestra erronos

@Tokes no estas devolviendo "numeroFinal" correctamente.





Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: Tokes en 19 Agosto 2010, 00:59 am
Disculpen, es cierto. Según yo ya devuelvo numero final en este código.

Código:
Private Function EsNumLychrel5b(ByVal num As Long, ByRef numeroFinal As Double, Optional ByVal iteraciones As Long = 50) As Boolean
Dim n As Double, nrev As Double
    If num And &H80000000 Then Exit Function
    n = num
    Do While iteraciones > 0
        nrev = dblReverse(n)
        If n = nrev Then
            numeroFinal = n
            Exit Function
        End If
        n = n + nrev
        iteraciones = iteraciones - 1
    Loop
    nrev = dblReverse(n)
    If n = nrev Then Exit Function
    EsNumLychrel5b = True
    numeroFinal = n

Si alguien gusta hacerle alguna modiicación ¡Adelante!


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: Psyke1 en 19 Agosto 2010, 01:01 am
Citar
Si alguien gusta hacerle alguna modiicación ¡Adelante!
Si, yo si se la voy ha hacer, aqui esta:
Código
  1. Private Function EsNumLychrel5b(ByVal num As Long, ByRef numeroFinal As Double, Optional ByVal iteraciones As Long = 50) As Boolean
  2. Dim n As Double, nrev As Double
  3.    If num And &H80000000 Then Exit Function
  4.    n = num
  5.    Do While iteraciones > 0
  6.        nrev = dblReverse(n)
  7.        If n = nrev Then
  8.            numeroFinal = n
  9.            Exit Function
  10.        End If
  11.        n = n + nrev
  12.        iteraciones = iteraciones - 1
  13.    Loop
  14.    nrev = dblReverse(n)
  15.    If n = nrev Then Exit Function
  16.    EsNumLychrel5b = True
  17.    numeroFinal = n
  18. End Function
Faltaba el End Function... :laugh: :laugh:

DoEvents¡!
:P


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: Tokes en 19 Agosto 2010, 01:06 am
¡Ja, ja! Soy un imbécil. Pero bueno, gracias, PsYkE1.


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: raul338 en 19 Agosto 2010, 01:22 am
Bien LeandroA, ya puse el filtro para que no acepte numeros de un digito, y que si es capicua que calcule igual :P

Los numeros de 1 solo digito no pueden ser calculados, ya que nunca cumpliran la condicion de ser capicua


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: [D4N93R] en 19 Agosto 2010, 01:32 am
Visual Basic sucks.. xD  :-X :-X :-X :-X :-X :-X :¬¬ :¬¬ :¬¬ :¬¬ :¬¬ :¬¬ :¬¬
 :silbar: :silbar: :silbar: :silbar: :silbar: :silbar: :silbar: :silbar:



Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: Psyke1 en 19 Agosto 2010, 01:34 am
Citar
Código:
Tokes:	128,759 msec
[D4N93R]: 10.388,359 msec
Raul338: 308,872 msec
Novlucker : 131,863 msec
BlackZeroX (v 2): 96,643 msec
BlackZeroX (v 3): 35,655 msec
Visual Basic sucks.. xD  :-X :-X :-X :-X :-X :-X :¬¬ :¬¬ :¬¬ :¬¬ :¬¬ :¬¬ :¬¬
 :silbar: :silbar: :silbar: :silbar: :silbar: :silbar: :silbar: :silbar:
:silbar: >:D
Pd: El post para meterse con VB esta aqui:
http://foro.elhacker.net/programacion_visual_basic/iquesttu_tambien_crees_que_visual_basic_es_para_tontos-t302471.0.html
 :laugh:


DoEvents¡!
 :-*


Título: Re: [RETO] ¿Fácil? Buscando los números de Lychrel
Publicado por: [D4N93R] en 19 Agosto 2010, 01:54 am
Gracias xD ya postié ahí xD :D