Título: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: Karcrack en 7 Julio 2010, 12:31 pm Bueno, me hacia falta hacer una funcion de este tipo para un trabajito que estoy haciendo :silbar:... y he pensado que tal vez os seria util...
Código
Podriamos hacer un jueguecito... a ver quien lo hace mas rapido/corto :D Os apuntais? MOD: Yo utilizo este codigo para comprobar lo optimizado que esta: Código: Option Explicit Private n As Long Private Sub Form_Load() Dim x As Long Timer1.Interval = 10 Timer1.Enabled = True For x = 0 To 10 ^ 6 Call IsItPrime(x) DoEvents Next x Timer1.Enabled = False MsgBox n * 10 & " ms" End Sub Public Function IsItPrime(ByVal lNumber As Long) As Boolean Dim i As Long If (lNumber > 2) And (lNumber Mod 2) Or (lNumber = 2) Then For i = 2 To (lNumber ^ 0.5) If (lNumber Mod i) = 0 Then GoTo Exit_ End If Next i IsItPrime = True End If Exit_: End Function Private Sub Timer1_Timer() n = n + 1 End Sub Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: cbug en 7 Julio 2010, 12:45 pm Código: If (lNumber > 2) And (lNumber Mod 2) Then Al 2 lo evalúas? Ahora en visual basic se puede modificar el long para que únicamente tome los enteros positivos? Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: Karcrack en 7 Julio 2010, 12:54 pm Código: If (lNumber > 2) And (lNumber Mod 2) Then Al 2 lo evalúas? Ahora en visual basic se puede modificar el long para que únicamente tome los enteros positivos? Se puede utilizar un Integer, aunque tambien acepta Negativos... Pero solo enteros :-\ Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: cbug en 7 Julio 2010, 12:58 pm Citar Se puede utilizar un Integer, aunque tambien acepta Negativos... Pero solo enteros :-\ Claro, porque de acuerdo a la definición, los números primos son aquellos números naturales que... Pero igual, tu código creo que es el más eficiente en cuanto a complejidad, no sé cómo se tratará el goto en vb realmente... sin embargo, creo que se parece mucho al de la criba de eratóstenes... Saludos! Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: Dreamaker en 7 Julio 2010, 13:00 pm Me quedó una duda, en el primer for lo haces hasta la raíz cuadrada del número para que sea más eficiente cierto? (Osea, tarde menos tiempo)
Está bien aunque es sencillo, y no comprueba si el 1 es primo o no (no digas nada) :xD Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: Karcrack en 7 Julio 2010, 13:02 pm Citar Se puede utilizar un Integer, aunque tambien acepta Negativos... Pero solo enteros :-\ Claro, porque de acuerdo a la definición, los números primos son aquellos números naturales que... Pero igual, tu código creo que es el más eficiente en cuanto a complejidad, no sé cómo se tratará el goto en vb realmente... sin embargo, creo que se parece mucho al de la criba de eratóstenes... Saludos! Me quedó una duda, en el primer for lo haces hasta la raíz cuadrada del número para que sea más eficiente cierto? (Osea, tarde menos tiempo) No es necesario recorrer cada numero, con llegar a la raiz es suficiente :) No dire nada sobre el 1 :rolleyes: :xDEstá bien aunque es sencillo, y no comprueba si el 1 es primo o no (no digas nada) :xD Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: Psyke1 en 7 Julio 2010, 13:04 pm Código
Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: Karcrack en 7 Julio 2010, 13:07 pm @Psyke: Tu función es mucho mas lenta, ademas, no tiene en cuenta que el 2 es primo (como hacia la mia :rolleyes: :xD)
No es necesario que recorras todos los números, con llegar a la raiz es suficiente ;) Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: Psyke1 en 7 Julio 2010, 14:41 pm Ok, agradezco la correcion, lo no tuve en cuenta :P
Ahora lo corregi! Salu2! ;) Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: cobein en 8 Julio 2010, 09:17 am Código: 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 Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: e500 en 8 Julio 2010, 09:22 am Código: 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 Exelente COBEIN, este es más rápido Saludos Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: Karcrack en 8 Julio 2010, 12:47 pm Muy bueno Cobein :) No habia pensando que podrian saltarse los pares :laugh: ;)
He optimizado el primero que puse: Código
Saludos :D Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: Psyke1 en 8 Julio 2010, 14:48 pm Una pregunta Karcrack, porque pones que vaya a la etiqueta Exit_ y no pones Exit Function??
Salu2! Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: Karcrack en 8 Julio 2010, 14:53 pm Una pregunta Karcrack, porque pones que vaya a la etiqueta Exit_ y no pones Exit Function?? No lo habia pensado :laugh: , pero bueno, no interfiere en la velocidad, solo se llama una vez :PSalu2! Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: raul338 en 8 Julio 2010, 16:41 pm Una pregunta Karcrack, porque pones que vaya a la etiqueta Exit_ y no pones Exit Function?? No lo habia pensado :laugh: , pero bueno, no interfiere en la velocidad, solo se llama una vez :PSalu2! FAIL! :xD Che la verdad muy bueno estos pequeños "concursos" de algoritmos que estan proponiendo ultimamente. Lastima que no sea muy bueno precisamente en algoritmos XD Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: Dreamaker en 8 Julio 2010, 16:58 pm Mmm estaría bueno un topic lleno de ejercicios de algoritmos aportados por todos (no se si hay alguno ya), por ejemplo averiguar los primeros 100 números vampiros y cosas así, son muy buenas cosas para practicar programación, obviamente en VB :xD
PD: Deberían comprometerse todos a agregar ejercicios y sólo eso, las dudas en topics aparte Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: cbug en 9 Julio 2010, 14:02 pm En la sección Ejercicios de programación existen muchos ejercicios, que se pueden resolver en cualquier lenguaje, ya que vb no es el único.
Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: Karcrack en 9 Julio 2010, 14:17 pm En la sección Ejercicios de programación existen muchos ejercicios, que se pueden resolver en cualquier lenguaje, ya que vb no es el único. :laugh: :laugh: :laugh: En serio? :o :oTítulo: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: Psyke1 en 9 Julio 2010, 14:37 pm En la sección Ejercicios de programación existen muchos ejercicios, que se pueden resolver en cualquier lenguaje, ya que vb no es el único. :laugh: :laugh: :laugh: En serio? :o :oA proposito, creo que se podria mejorar las funciones aun mas Karcrack, me explico: Segun lo que hizo Cobein no comprobaba los numeros pares y eso ahorra trabajo, pero teniendo en cuenta que un numero primo solo puede acabar en: Código: 1,3,7,9 Con la funciones que hay se comprobarian los imapares:Código: 1,3,5,7,9 Pero todo numero que acabe en 5 es imposible que sea primo, me explico?Corregidme si me equivoco... :P Salu2! Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: cobein en 9 Julio 2010, 15:30 pm *PsYkE1* suena correcto lo que decis, el problema, en mi opinion es que para no comparar algun numero terminado en 5, agregarias mas operaciones que simplemente comprobandolo.
Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: Karcrack en 9 Julio 2010, 15:43 pm 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... Citar Advertencia - mientras estabas escribiendo, una nueva respuesta fue publicada. Probablemente desees revisar tu mensaje. No, gracias ;)Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: Psyke1 en 9 Julio 2010, 16:13 pm Ok, gracias por contestar :P
EDITO: Hice esta funcion, no es la mas rapida, pero es una forma diferente de hacerlo: Código
Funcion Karcrack : 3030 ms Funcion *PsYkE1* : 3840 ms Funcion Cobein : 4260 ms Decirme vuestra opinion! ;) Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: Dreamaker en 9 Julio 2010, 17:37 pm 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
Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: Karcrack en 9 Julio 2010, 18:35 pm @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:
Código: 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 ;) Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: raul338 en 9 Julio 2010, 19:39 pm Karcrack, seria mas exacto si usaras GetTickCount ;-D
Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: Karcrack en 9 Julio 2010, 19:41 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 (http://msdn.microsoft.com/en-us/library/ms644904%28VS.85%29.aspx) ;)Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: cobein en 9 Julio 2010, 20:10 pm Código: 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 Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: LeandroA en 9 Julio 2010, 20:29 pm 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. Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: Karcrack en 9 Julio 2010, 20:52 pm Código 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 Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: Psyke1 en 9 Julio 2010, 21:14 pm 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! ;) Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: raul338 en 9 Julio 2010, 21:16 pm Felicidades, fue divertido :P Habran mas de estos seguro >:D :xD COBEIN WINS! Fatality :xD Ps.... estare esperando haber si puedo participar :) Advertencia - mientras estabas escribiendo, una nueva respuesta fue publicada. Probablemente desees revisar tu mensaje. :¬¬ Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: cobein en 10 Julio 2010, 05:31 am Hay un error en el codigo, despues lo corrijo.
Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: Karcrack en 30 Agosto 2010, 22:16 pm Hay un error en el codigo, despues lo corrijo. Bueno, el error para quien quiera saberlo es que comprobaba mal la multiplicidad de 5...Me he quedado hoy pensando... y hay una forma realmente sencilla de obtener el ultimo digito de una cifra... sin usar cadenas de textoooo :o Simplemente hay que obtener el resto al dividir por 10 (aka Mod 10) :laugh: He hecho este codigo :D, si no me equivoco es la mas rapida (sin contar la de Cobein, que no acaba de funcionar) Código
Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: Psyke1 en 30 Agosto 2010, 22:29 pm WOow que bueno!! :D
A ver si cuando acabe examenes me meto a tope con bytes. :) Tu code es muy sencillo y eficaz! :D Una cosilla de nada: Si quitas el indicador en el For ahorras un poquitin (muy poco) de tiempo... ;) http://foro.rthacker.net/programacion-visual-basic/como-acelerar-codigo-en-vb6/ DoEvents¡! :P Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: Karcrack en 30 Agosto 2010, 22:35 pm Una cosilla de nada: Estas equivocado :PSi quitas el indicador en el For ahorras un poquitin (muy poco) de tiempo... ;) http://foro.rthacker.net/programacion-visual-basic/como-acelerar-codigo-en-vb6/ DoEvents¡! :P Código: http://www.xbeat.net/vbspeed/c_ForNext.htm Código: Despite all rumors: Next or Next i does NOT matter at all!! The minimal differences you see in the timings above are totally insignificant: you could produce any possible ranking order by running the same test over and over again long enough. Esa pequeña diferencia de tiempo va a favor de uno u otro dependiendo de cada vez que lo ejecutas... Título: Re: [SNIPPET+RETO] IsItPrime() - Comprobar si un numero es primo Publicado por: Psyke1 en 30 Agosto 2010, 22:37 pm :o
Ok tu ganas... :silbar: DoEvents¡! :P |