[SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo

Iniciado por Karcrack, 7 Julio 2010, 12:31 PM

0 Miembros y 1 Visitante están viendo este tema.

Karcrack

#20
Tienes, razon, cualquier numero mayor que 5 acabado en 5 no es primo debido a que ya seria divisible por 5 (Recordemos que los multiplos de 5 son todos los numeros acabados en 5 y en 0)

Tampoco creas que augmenta mucho la velocidad, debido a que simplemente ha de hacer un Mod 3 antes que el Mod 5 para comprobar que acaba en 5...
Ademas, no se me ocurre una forma de comprobar que acabase en 5 sin ralentizar el proceso...


CitarAdvertencia - mientras estabas escribiendo, una nueva respuesta fue publicada. Probablemente desees revisar tu mensaje.
No, gracias ;)

Psyke1

#21
Ok, gracias por contestar :P

EDITO:
Hice esta funcion, no es la mas rapida, pero es una forma diferente de hacerlo:
Código (vb) [Seleccionar]
Public Function Check_Prime_Number(ByVal lNumber As Long) As Boolean
   Const sPrimeDigit            As String = "1379"
   Dim sLastDigit               As String * 1
   Dim sNumber                  As String
   Dim x                        As Long
   
   If (lNumber > 2) Then
       sNumber = Str$(lNumber)
       sLastDigit = Right$(sNumber, 1)
       If InStr(sPrimeDigit, sLastDigit) > 0 Then
           For x = 3 To Sqr(lNumber) Step 2
               If (lNumber Mod x) = 0 Then Exit Function
           Next
           Check_Prime_Number = True
       End If
   End If
End Function


Funcion Karcrack   : 3030 ms
Funcion *PsYkE1* : 3840 ms
Funcion Cobein      : 4260 ms

Decirme vuestra opinion! ;)

Dreamaker

#22
Apropósito si que me quedó una duda, como se fijan el tiempo que tarda en resolverlo exactamente cada función? (Como puso recién *PsYkE1*, eso me serviría para ver cuan eficientes son mis aplicaciones

Karcrack

#23
@PsYkE1: Debes comprobar la velocidad con el proyecto compilado, si no no es de fiar... por ejemplo, el codigo de Cobein era un poco mas rapido que el mio cuando lo prove...

Para hacer tu codigo mas rapido deberias hacer la comprobacion trabajando con los bits... voy a ver si puedo hacer algo sin pasarlo a String... que eso consume mucho

MOD:
Tu codigo falla con el 2 y el 5, que son primos y devuelve False ;)

MOD2:
Acabo de hacer los Test de Velocidad:

  • Karcrack: 1320ms
  • Cobein: 1330ms
  • Psyke: 2360ms
He hecho la prueba con un ciclo desde el 3 a 10^6  :D

Option Explicit
Private n       As Long

Private Sub Form_Load()
    Dim x       As Long
   
    Timer1.Interval = 10
   
    Timer1.Enabled = True
    For x = 3 To 10 ^ 6
        Call IsItPrime(x)
        DoEvents
    Next x
    Timer1.Enabled = False
    MsgBox n * 10 & " ms" & " KARCRACK"
    n = 0
   
    Timer1.Enabled = True
    For x = 3 To 10 ^ 6
        Call CheckPrimality(x)
        DoEvents
    Next x
    Timer1.Enabled = False
    MsgBox n * 10 & " ms" & " COBEIN"
    n = 0
   
    Timer1.Enabled = True
    For x = 3 To 10 ^ 6
        Call Check_Prime_Number(x)
        DoEvents
    Next x
    Timer1.Enabled = False
    MsgBox n * 10 & " ms" & " Psyke"
    n = 0
End Sub

Public Function Check_Prime_Number(ByVal lNumber As Long) As Boolean
    Const sPrimeDigit            As String = "1379"
    Dim sLastDigit               As String * 1
    Dim sNumber                  As String
    Dim x                        As Long

    If (lNumber > 2) Then
        sNumber = Str$(lNumber)
        sLastDigit = Right$(sNumber, 1)
        If InStr(sPrimeDigit, sLastDigit) > 0 Then
            For x = 3 To Sqr(lNumber) Step 2
                If (lNumber Mod x) = 0 Then Exit Function
            Next
            Check_Prime_Number = True
        End If
    End If
End Function

Private Function CheckPrimality(ByVal lNum As Long) As Boolean
    Dim i       As Long
    Dim lSqr    As Long
       
    If lNum Mod 2 = 0 Then GoTo Composite:

    lSqr = Sqr(lNum)

    i = 3
    Do Until i > lSqr
        If lNum Mod i = 0 Then GoTo Composite:
        i = i + 2
    Loop
   
Prime:
    CheckPrimality = True
    Exit Function
Composite:
    If lNum = 2 Then CheckPrimality = True
End Function

Public Function IsItPrime(ByVal lNumber As Long) As Boolean
    Dim i       As Long

    If (lNumber >= 2) And (lNumber And 1) Or (lNumber = 2) Then
        For i = 3 To Sqr(lNumber) Step 2
            If (lNumber Mod i) = 0 Then Exit Function
        Next i
        IsItPrime = True
    End If
End Function

Private Sub Timer1_Timer()
    n = n + 1
End Sub


S2 ;)

raul338

Karcrack, seria mas exacto si usaras GetTickCount ;-D

Karcrack

Cita de: raul338 en  9 Julio 2010, 19:39 PM
Karcrack, seria mas exacto si usaras GetTickCount ;-D
Simplemente queremos ver quien es mas rapido, tampoco necesitamos mas precision, si la necesitasemos usaria QueryPerformanceCounter ;)

cobein

#26
Private Function CheckPrimality(ByVal lNum As Long) As Boolean
   Dim i       As Long

   If lNum < 10 Then
       If lNum = 2 Then CheckPrimality = True: Exit Function
       If lNum = 5 Then CheckPrimality = True: Exit Function
       If lNum = 1 Then Exit Function
   End If
   
   If Not (lNum And 1) = 1 Then Exit Function
   If (lNum And 5) = 5 Then Exit Function
   For i = 3 To Sqr(lNum) Step 2
       If lNum Mod i = 0 Then Exit Function
   Next
   CheckPrimality = True
End Function


Test project: http://uploading.com/files/c72amae6/Prime.rar/
No estoy seguro si la clase para testear la velocidad esta en la descarga, si no esta la pueden descargar de aca http://www.xbeat.net/vbspeed/download/CTiming.zip
http://www.advancevb.com.ar
Más Argentino que el morcipan
Aguante el Uvita tinto, Tigre, Ford y seba123neo
Karcrack es un capo.

LeandroA

uuuu vuela la ultima, es casi la mitad de la primera que posteaste al principio.

y si lo del timer para medir la velocidad mm no es de fiar mas que nada por el doevents mejor usar  GetTickCount o QueryPerformanceCounter.

Karcrack

#28
Código (vb,11) [Seleccionar]
Private Function CheckPrimality(ByVal lNum As Long) As Boolean
   Dim i       As Long

   If lNum < 10 Then
       If lNum = 2 Then CheckPrimality = True: Exit Function
       If lNum = 5 Then CheckPrimality = True: Exit Function
       If lNum = 1 Then Exit Function
   End If
   
   If Not (lNum And 1) = 1 Then Exit Function
   If (lNum And 5) = 5 Then Exit Function
   For i = 3 To Sqr(lNum) Step 2
       If lNum Mod i = 0 Then Exit Function
   Next
   CheckPrimality = True
End Function

Interesante linea... con eso se puede comprobar si es multiple de 5? No acabo de entender como funciona... voy a jugar un poco con los Bits...

Pues eso, Cobein vence :P A no ser que alguien encuentre una forma de calcular la multiplicidad mas rapida que con Mod  :laugh: :laugh:

Felicidades, fue divertido :P Habran mas de estos seguro >:D :xD

Psyke1

Ok, lo siento por las medidas, quizas hice algo mal sin darme cuenta...  :-\
Tengo curiosidad a ver como lo haces Karcrack  :), me gustan este tipo de retos, aprendo mucho y salen diferentes manera de hacer las cosas... :P

Salu2! ;)