Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Karcrack

#821
1- Raul338 aplicas mal el algoritmo, como ha dicho Cobein (n * (n+1)) <> (n * n + 1)
2- La velocidad ha de comprobarse compilada siempre.
3- Algunos de vosotros no incluis el 2 como numero Oblongo, y lo es: 2 = 1*(1+1)
4- Aqui pongo los resultados del test que he corrido en mi PC (Con la llamada que puse yo, que es con la que hay que probar :)):
Karcrack -> 5,729 msec
Tokes -> 6,236 msec
LeandroA -> 24,102
B0X -> 76,071 msec
raul338 -> Funcion no valida






He actualizado mi funcion, tenia un gran fallo :laugh:
' Karcrack
Private Function IsOblongo01(ByVal lNumb As Long, ByRef n As Long) As Boolean
   If (lNumb = 0) Then n = 0: IsOblongo01 = True: Exit Function

   If (lNumb And 1) = 0 Then
       For n = 1 To Sqr(lNumb + 1)
           If lNumb = n * (n + 1) Then
               IsOblongo01 = True
               Exit For
           End If
       Next n
   End If
End Function

#822
Cita de: LeandroA en 17 Agosto 2010, 05:49 AM
jajaja y si yo lo dije, de todas formas esOdiosoTokLean se lleva la copa jejej
Querras decir que se la lleva el equipo CobKar! :laugh: :laugh:
#823
Si, estuve comprobando y Cobein+Karcrack solo se va un par de milisegundos de LeandroA( aka Gilad >:D :xD)+Tokes

Ya tenemos vencedores :P !! (?)
#824
@raul338: Para mejorar la velocidad te recomiendo que te saltes los pares, ya que ningun par mayor que 2 es pronico, tambien te recomiendo que hagas el bucle con la n; Te ahorras una variable y ganas velocidad... Y por ultimo te recomiendo que aqui:
        If lNumb / i = i + 1 Then
Hagas la division entera (\) que es mas rapida ;)

Saludos :D
#825
Aqui esta mi codigo :D
Código (vb) [Seleccionar]
' Karcrack
Private Function IsOblongo01(ByVal lNumb As Long, ByRef n As Long) As Boolean
    If (lNumb = 0) Then n = 0: IsOblongo01 = True: Exit Function

    If (lNumb And 1) = 0 Then
        For n = 1 To Sqr(lNumb + 1)
            If lNumb = n * (n + 1) Then
                IsOblongo01 = True
                Exit For
            End If
        Next n
    End If
End Function


Si simplemente se quiere comprobar si es oblongo sin calcular n, se puede hacer asi:
' Karcrack, no cumple el requisito de devolver n
Private Function IsOblongo02(ByVal lNumb As Long) As Boolean
   IsOblongo02 = (Round(Sqr(lNumb + 1)) - Round(Sqr(lNumb)) = 1)
End Function

Es mas corta, pero no mas rapida ;)
#826
Esta seria la forma habitual y logica de realizar el algoritmo:
Código (vb) [Seleccionar]
Private Function IsOblongo(ByVal lNumb As Long, ByRef n As Long) As Boolean
   Dim i   As Long
   
   For i = 0 To lNumb
       If lNumb = i * (i + 1) Then
           IsOblongo = True
           n = i
           Exit For
       End If
   Next i
End Function


Por cierto, la velocidad se medira llamando a la funcion con un rango de 10000 numeros, tal que asi:
   Dim i   As Long
   Dim n   As Long

   For i = 0 To 10000
       Call IsOblongo(i, n)
   Next i
#827
Seguimos con los retos de velocidad y numeros :) Ahora han tocado los numeros pronicos/oblongos... que no requieren un algoritmo muy complejo, pero si que tocara pensar para augmentar la velocidad :D

Mas informacion:
http://en.wikipedia.org/wiki/Pronic_number
http://oeis.org/classic/A002378

Se trata de comprobar si un numero puede ser expresado como el producto de dos enteros consecutivos... es decir:
numero_oblongo = n*(n+1)
Ejemplo:
6 = 2*(2+1)

Se trata de comprobar que el numero es oblongo y devolver el valor de n... La funcion ha de estar declarada de este modo:
Código (vb) [Seleccionar]
Private Function IsOblongo(ByVal lNumb As Long, ByRef n As Long) As Boolean

Tal vez la velocidad de aparicion de nuevos retos sea elevada, pero es que por las noches me aburro :-[ :P

Se el mas rapido del oeste, vaquero!
#828
@Cobein Muy interesante lo de meterlo todo en un byte :) Me he tomado la libertad de mejorarlo :P:

Private Function IsOdiousNumber(ByVal lVal As Long) As Boolean
    Dim lTmp    As Long
    Dim l       As Long
   
    lTmp = lVal

    lVal = lTmp And &HFF
    lTmp = lTmp \ &H100
    lVal = lVal Xor (lTmp And &HFF)
    lTmp = lTmp \ &H100
    lVal = lVal Xor (lTmp And &HFF)
    lTmp = lTmp \ &H100
    lVal = lVal Xor (lTmp And &HFF)

    l = l + ((lVal And &H80) \ &H80)
    l = l + ((lVal And &H40) \ &H40)
    l = l + ((lVal And &H20) \ &H20)
    l = l + ((lVal And &H10) \ &H10)
    l = l + ((lVal And &H8) \ &H8)
    l = l + ((lVal And &H4) \ &H4)
    l = l + ((lVal And &H2) \ &H2)
    l = l + ((lVal And &H1) \ &H1)

    IsOdiousNumber = (l And 1)
End Function


ES MAS RAPIDO QUE EL CODIGO DE LEANDROOO!! >:D >:D >:D :P
#829
Mi codigo, lo comento para que quien no entienda de Bits le quede mas claro ;):
Private Function IsItOdious(ByVal lNumb As Long) As Boolean
    Dim bTmp    As Byte
    Dim bRes    As Byte
   
    ' Si es negativo...
    If lNumb And &H80000000 Then Exit Function
   
    'Obtenemos el HiByte
    bTmp = lNumb And &HFF
    bRes = (bTmp And 1)
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
   
    ' Rotamos el numero 32bits a la derecha
    lNumb = lNumb \ &H100
   
    'Obtenemos el HiByte
    bTmp = lNumb And &HFF
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
   
    ' Rotamos el numero 32bits a la derecha
    lNumb = lNumb \ &H100
   
    'Obtenemos el HiByte
    bTmp = lNumb And &HFF
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
   
    ' Rotamos el numero 32bits a la derecha
    lNumb = lNumb \ &H100
   
    'Obtenemos el HiByte
    bTmp = lNumb And &HFF
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
    If (bTmp And 1) Then bRes = bRes + 1
    bTmp = bTmp \ 2
   
    IsItOdious = (bRes And 1)
End Function



Despues de ver que la tecnica de Leandro era muy rapida he intentado modificar la de Cobein que parecia que tenia potencial:
Private Function IsOdiousNumberX(ByVal lVal As Long) As Boolean
    If lVal And &H80000000 Then Exit Function
   
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2

    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
   
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
   
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
    If lVal And 1 Then IsOdiousNumberX = Not IsOdiousNumberX
    lVal = lVal \ 2
End Function



Resultados:
Karcrack:
49,668 msec
Cobein:
14,426 msec
LeandroA:
8,991 msec
Cobein (Mod Karcrack):
12,547 msec
#830
Aqui teneis un ejemplo de algoritmo habitual:
Código (vb) [Seleccionar]
Private Function IsItOdious(ByVal lNumb As Long) As Boolean
    Dim lCount  As Long
    Dim i       As Long
   
    If lNumb <= 0 Then Exit Function
    For i = 0 To 30
        If lNumb And 2 ^ i Then lCount = lCount + 1
    Next i
    IsItOdious = ((lNumb Mod 2) <> 0)
End Function


Por supuesto se puede hacer mas rapido :D

Todo el mundo a pensar en 0s y 1s!! :laugh: