Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> liczby pierwsze
Jabol
post
Post #1





Grupa: Przyjaciele php.pl
Postów: 1 467
Pomógł: 13
Dołączył: 22.02.2003

Ostrzeżenie: (0%)
-----


temat wydzielony od: http://forum.php.pl/viewtopic.php?t=9078
Chodzi o sprawdzanie licz czy są pierwsze.

Cytat
Najprosciej (choc nie najwydajniej) sprawdzic podzielnosc liczby X przez wszystkie liczby calkowite od 2 do sqrt(X) (sqrt - pierwiastek kwadratowy). Jesli się przez ktorakolwiek z nich dzieli to nie jest to liczba pierwsza (wyjatkiem jest liczba 2, ktora jest liczba pierwsza).
Najprościej jest podzielić przez wszystkie liczy pierwsze mniejsze od sqrt(X) i większe od 2.
Go to the top of the page
+Quote Post
2 Stron V   1 2 >  
Start new topic
Odpowiedzi (1 - 23)
FiDO
post
Post #2





Grupa: Przyjaciele php.pl
Postów: 1 717
Pomógł: 0
Dołączył: 12.06.2002
Skąd: Wolsztyn..... Studia: Zielona Góra

Ostrzeżenie: (0%)
-----


Cytat
Cytat
...
Najprościej jest podzielić przez wszystkie liczy pierwsze mniejsze od sqrt(X) i większe od 2.

Najpierw trzebaby je znalezc ;P Nie zeby to bylo trudne, ale kodu bedzie wiecej.


--------------------
Brak czasu :/
Go to the top of the page
+Quote Post
s_w_ir
post
Post #3





Grupa: Zarejestrowani
Postów: 315
Pomógł: 1
Dołączył: 6.08.2003
Skąd: Kielce

Ostrzeżenie: (0%)
-----


Dobra dzięki za te odpowiedzi. A czy macie rozwiązanie na punkt 2:
Cytat
2. Jak obliczeniami sprawdzić czy liczba jest całkowita(właśnie to mi jest do perla potrzebne), albo prosił bym o funkcje perla sprawdzającą to?

Bo ja robiłem co mogłem i nic.
Go to the top of the page
+Quote Post
DeyV
post
Post #4





Grupa: Zarząd
Postów: 2 277
Pomógł: 6
Dołączył: 27.12.2002
Skąd: Wołów/Wrocław




z przykrością muszę stwierdzić, że rozsądne wykonanie tego zadania wymaga znajmowości całkiem zaawansowanej matematyki, i napisania całkiem mądrego programu.
Kiedyś widziałem stroną pokazującą jak powinno się to zrobić, oraz program napisany w paskalu, który sprawdzał czy dana liczba jest pierwsza. Podawałem ten link komuś, a osoba ta postanowiła przepisać ten program na php. Jednak działanie php okazało się zawodne - tj. program w paskalu wykonaywał się kilka tys razy szybciej (może pojawiły się jakieś błdy w kodzie php - nie wiem)
W każdym razie temat jest ciekawy, tak wieć zapraszam do googlania


--------------------
"Niezależnie od tego, jakie masz osiągnięcia, ktoś Ci pomaga..."
Go to the top of the page
+Quote Post
Cudi
post
Post #5


Administrator planeta/IRC


Grupa: Przyjaciele php.pl
Postów: 385
Pomógł: 0
Dołączył: 19.04.2003
Skąd: Zabrze

Ostrzeżenie: (0%)
-----


Temat jest ciekawy, jedak eksperyment który opisuje DeyV nie powiódł sie. To ja byłem tą osoba która próbowała przetłumaczyć ten kod z paskala na php, niestety z nienajlepszym skutkiem smile.gif W każdym bądź razie są na polskich stronach opisy programów które potrafią to sprawdzić, są to jednak bardzo skomplikowane procesy korzystające z tzw. sita erostatenesa, i nie wiem czy język typu php lub Perl poradzi sobie z nimi smile.gif


--------------------
"Programmers are in a race with the Universe to create bigger and better idiot-proof programs, while the Universe is trying to create bigger and better idiots. So far the Universe is winning."
Cudi's devBlog
Go to the top of the page
+Quote Post
Jabol
post
Post #6





Grupa: Przyjaciele php.pl
Postów: 1 467
Pomógł: 13
Dołączył: 22.02.2003

Ostrzeżenie: (0%)
-----


mam program w C, który generuje ustaloną liczbę liczb pierwszych.
pierwsze c
Kod
#include <stdio.h>

#include "pierwsze.h"



int dividable( const int, const int[] );



int main( int argc, char * argv[] )

{

    int nrs[ARRSIZE] = { 2, 3, NULL }, i = 1, curr = 3;



#ifdef DEBUG

    fprintf( stderr, "array address: 0x%xn", nrs );

#endif

    puts( "1: 2n2: 3" );

    while( ( curr += 2 )  && ( ( i +  1 ) < ARRSIZE ) )

    {

        if( ! dividable( curr, nrs ) )

        {

            nrs[++i] = curr;

            nrs[i+1] = NULL;

            printf( "%d: %dn", (i + 1), curr );

#ifdef DEBUG

            if( ! ( ( i - 1 ) % NOTIFY ) )

                fprintf( stderr, "found %dn", i );

#endif

        }

    }

    return 0;

}



int dividable( const int nr, const int nrs[] )

{

    int i = 0;



    do

    {

#ifdef DEBUG

        fprintf( stderr, "checking: %d %% %dn", nr, nrs[i] );

#endif

        if( ! ( nr % nrs[i] ) )

            return 1;

    } while( ( nrs[++i] != NULL ) && ( nrs[i] < ( nr / 2 ) ) );

    return 0;

}
pierwsze.h
Kod
// Delete line below if you don't want to have debugging shit on the screen

#define DEBUG 1

// How many numbers do you wanna get

#define ARRSIZE 10

// Each how many numbers do you wanna be notified ? ( ignored if debug offed )

#define NOTIFY 2
Co prawda tutaj mam łatwiej, bo korzystam z wytworzonej wcześniej tabeli liczb pierwszych. Pamiętam, że jak generowałem pierwszy milion to sżło chyba z pare godzin ( ale niedużo ).
Aha, i dziele przez wszystkie mniejsze od połowy, bo szczerze mówiąc, nie umiałem podlinkować od biblioteki math.
Go to the top of the page
+Quote Post
s_w_ir
post
Post #7





Grupa: Zarejestrowani
Postów: 315
Pomógł: 1
Dołączył: 6.08.2003
Skąd: Kielce

Ostrzeżenie: (0%)
-----


Z bratem opracowaliśmy że każda liczba nie pierwsza powyżej 10 składa się z jednej z "CZTERECH MAGICZNYCH LICZB: 2 3 5 7", a dokładniej z mnożenia czegoś przez magiczną i na tej podstawie napisaliśmy:[php:1:8e5355715d]<?php
$liczba = 67; //dowolna liczba
if($liczba!=1){
if (($liczba == 2 || $liczba == 3 || $liczba == 5 || $liczba == 7) || ($liczba % 2 != 0 && $liczba % 3 != 0 && $liczba % 5 != 0 && $liczba % 7 != 0))
{
echo "dana liczba jest liczba pierwszan";
}

else
{
echo "badana liczba nie jest liczba pierwszan";
}
}
else echo "badana liczba nie jest liczba pierwszan";
?>[/php:1:8e5355715d]
Chyba to nie obciąża aż tak pamięci?
Go to the top of the page
+Quote Post
FiDO
post
Post #8





Grupa: Przyjaciele php.pl
Postów: 1 717
Pomógł: 0
Dołączył: 12.06.2002
Skąd: Wolsztyn..... Studia: Zielona Góra

Ostrzeżenie: (0%)
-----


Cytat
Z bratem opracowaliśmy że każda liczba nie pierwsza powyżej 10 składa się z jednej z "CZTERECH MAGICZNYCH LICZB: 2 3 5 7", a dokładniej z mnożenia czegoś przez magiczną

Niestety to jest zbyt proste, zeby bylo prawdziwe winksmiley.jpg

Sprawdz chocby liczbe 121, Wasz algorytm stwierdza, ze jest pierwsza, a 121 % 11 = 0. Przykladow mozna by mnozyc...


--------------------
Brak czasu :/
Go to the top of the page
+Quote Post
s_w_ir
post
Post #9





Grupa: Zarejestrowani
Postów: 315
Pomógł: 1
Dołączył: 6.08.2003
Skąd: Kielce

Ostrzeżenie: (0%)
-----


No to teraz dopiero się fatalnie poczułem. widać jeszcze mam za wąski umysł żeby takie banały przewidywać. Pozdro.
Go to the top of the page
+Quote Post
Cudi
post
Post #10


Administrator planeta/IRC


Grupa: Przyjaciele php.pl
Postów: 385
Pomógł: 0
Dołączył: 19.04.2003
Skąd: Zabrze

Ostrzeżenie: (0%)
-----


Tak jak napisałem można skorzystać z metody sita Eratostenesa, która jest dosyć wydajna, a pozwala ze zboiru liczb pozbyć sie wszystkich liczb nie-pierwszych. Nie będe tego opisywał, tylko dam odnośnik do strony gdzie jest to wyjaśnione, jest też kodzik źródlowy dla pascala:
:arrow: http://mpp.qs.pl/XAlgorytmy/AlgPierwsze.html
Oczywiście jest to troche okręzna metoda jeśli chcemy tylko sprawdzić czy dana liczba jest pierwsza, ale zawsze jest to metoda działająca winksmiley.jpg


--------------------
"Programmers are in a race with the Universe to create bigger and better idiot-proof programs, while the Universe is trying to create bigger and better idiots. So far the Universe is winning."
Cudi's devBlog
Go to the top of the page
+Quote Post
FiDO
post
Post #11





Grupa: Przyjaciele php.pl
Postów: 1 717
Pomógł: 0
Dołączył: 12.06.2002
Skąd: Wolsztyn..... Studia: Zielona Góra

Ostrzeżenie: (0%)
-----


Sa wydajne algrgorytmy na sprawdzanie (a przynajmniej losowanie ) duzych (bardzo...) liczb, bo przeciez na tym polega np. RSA, potrzebne sa tam spore liczby pierwsze, ale jak sie nazywa algorytm je losujacy to nie mam zielonego pojecia..


--------------------
Brak czasu :/
Go to the top of the page
+Quote Post
Cudi
post
Post #12


Administrator planeta/IRC


Grupa: Przyjaciele php.pl
Postów: 385
Pomógł: 0
Dołączył: 19.04.2003
Skąd: Zabrze

Ostrzeżenie: (0%)
-----


Niom, niestety masz racje. Przepisałem algorytm z podanej strony na php:
[php:1:cf773fee3d]<?php
$intX = 10000; // ilosc liczb do przecedzenia przez sito
$arrPrimes = range( 1, $intX );

for( $i = 2; $i <= $intX; $i++ )
{
$z = 2;

while( $i * $z <= $intX )
{
unset( $arrPrimes[ array_search( ( $i * $z ), $arrPrimes ) ] );
$z++;
}
}
?>[/php:1:cf773fee3d]
I niestety dla 10000 liczb pierwszych czas wynosi ok. 20 sekund sad.gif Ale jeśli chcemy wypisac tylko określoną ilość liczb pierwszych to taki czas jest chyba zadowalający winksmiley.jpg


--------------------
"Programmers are in a race with the Universe to create bigger and better idiot-proof programs, while the Universe is trying to create bigger and better idiots. So far the Universe is winning."
Cudi's devBlog
Go to the top of the page
+Quote Post
milosh
post
Post #13





Grupa: Zarejestrowani
Postów: 0
Pomógł: 0
Dołączył: 29.12.2003

Ostrzeżenie: (0%)
-----


Witam,
Zainteresowała mnie ta dyskusja, wiec postanowilem napisac cos i spłodziłem to w Pythonie (www.python.org.pl)
Kod
#Tester liczb pierwszych

spr = []

pierw =[1,2,3,5,7,11]

num = input('Podaj liczbe:')

for x in range(2,12):

    spr.append(num%x)

print spr

a = spr[0]+spr[1]+spr[2]+spr[3]+spr[4]+spr[5]+spr[6]+spr[7]+spr[8]+spr[9]

if num in pierw or a != 0:

    print num, 'to l. pierwsza'

else:

    print num, 'to nie l.pierwsza'

Nie jestem pewien, jak to będzie działało na większych liczbach, więc prosiłbym o test. Jeśli coś jest niejasne, chętnie wyjaśnię winksmiley.jpg
Pozdr.
Go to the top of the page
+Quote Post
s_w_ir
post
Post #14





Grupa: Zarejestrowani
Postów: 315
Pomógł: 1
Dołączył: 6.08.2003
Skąd: Kielce

Ostrzeżenie: (0%)
-----


To ja mam na 100% pewny kod i na 100% nie wydajny przy dużych liczbach i na który chyba każdy z was wpadł:[php:1:4ea04ac18a]<?php
$liczba=105;//dowolna liczba
if($liczba>=2){
for($i=2;$i<$liczba;$i++){
if($liczba % $i==0){ echo "Liczba $liczba dzieli się przez $i<br>";
$d++;}
}
if($d==0) echo "Liczba jest Pierwsza";
else {
$liczba2=$liczba-1;
echo "Liczba nie jest pierwsza, ponieważ dzieli się przez $d liczb(y) z przedziału (2, $liczba2)";
}
}
else echo "Liczba nie jest pierwsza";
?>[/php:1:4ea04ac18a]
edit:
Jednak można to skrócić dodając break jak tylko znajdzie się liczba która daje resztę 0 z dzielenia
Go to the top of the page
+Quote Post
FiDO
post
Post #15





Grupa: Przyjaciele php.pl
Postów: 1 717
Pomógł: 0
Dołączył: 12.06.2002
Skąd: Wolsztyn..... Studia: Zielona Góra

Ostrzeżenie: (0%)
-----


Teraz to sie nie popisales smile.gif

W tej metodzie (typowy brute-force bez optymalizacji) masz N - 2 iteracji petli, a w metodzie z pierwiastkiem (ktora podalem na poczatku) jest juz sqrt(N) - 2 iteracji, roznica jest niebanalna, choc i tak obie metody sa wolne (dla duzych liczb).


--------------------
Brak czasu :/
Go to the top of the page
+Quote Post
milosh
post
Post #16





Grupa: Zarejestrowani
Postów: 0
Pomógł: 0
Dołączył: 29.12.2003

Ostrzeżenie: (0%)
-----


Cytat
Widzisz ale tu nie wykluczasz brak licz pseudopierwszych

Niestety zdałem sobie sprawę z tego dopiero dziś, więc poprawiłem kod na coś takiego:
Kod
# Tester Liczb Pierwszych



spr = []

lp=[1,2,3,5,7]

num=666

while num != 0:

    num = input('Podaj liczbe:')

    if num < 0:

        continue

    for x in range(2,11):

        spr.append(num%x)

    print spr

    if round(num**0.5) != num**0.5 and 0 not in spr or num in lp:

        print num, 'to l. pierwsza'

        spr=[]

    else:

        print num, 'to nie l. pierwsza'

        spr=[]

print 'thx'

Teraz chyba działa, przynajmniej tak wynika z moich testów. Liczba wyjątków (o ile takie istnieją) jest chyba bardziej ograniczona.
Pozdr
Go to the top of the page
+Quote Post
dr_bonzo
post
Post #17





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


Cytat
Z bratem opracowaliśmy że każda liczba nie pierwsza powyżej 10 składa się z jednej z "CZTERECH MAGICZNYCH LICZB: 2 3 5 7", a dokładniej z mnożenia czegoś przez magiczną i na tej podstawie napisaliśmy:


To jakos tak bylo, ze: kazda liczbe calkowita da sie zapisac w postaci iloczynu liczb pierwszych.
Np:
39 = 3 * 13
14 = 2 * 7
210 = 2 * 3 * 5 * 7
5610 = 2 * 5 * 11 * 17

13 = 1 * 13
7 = 1 * 7


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
Jabol
post
Post #18





Grupa: Przyjaciele php.pl
Postów: 1 467
Pomógł: 13
Dołączył: 22.02.2003

Ostrzeżenie: (0%)
-----


285311670611=11*11
niestety, nie zadziałało
Go to the top of the page
+Quote Post
PMadej
post
Post #19


Vice-Administrator serwera


Grupa: Przyjaciele php.pl
Postów: 395
Pomógł: 0
Dołączył: 7.08.2003
Skąd: Kielce

Ostrzeżenie: (0%)
-----


przeciez to nie sa liczby pierwsze:
39 = 3 * 13
14 = 2 * 7
210 = 2 * 3 * 5 * 7
5610 = 2 * 5 * 11 * 17

liczba pierwsza dzieli sie przez sama siebie i przez 1 ... wiec wszystko co mnozysz przez cos innego niz 1 odpada smile.gif


te tak:
13 = 1 * 13
7 = 1 * 7


--------------------
Go to the top of the page
+Quote Post
matys
post
Post #20





Grupa: Zarejestrowani
Postów: 109
Pomógł: 0
Dołączył: 7.03.2004
Skąd: Szczecin|Bukowe

Ostrzeżenie: (0%)
-----


Ja napisałem w C++ program, który sprawdza, czy podana przez użytkownika liczba, jest liczbą pierwszą:
Kod
#include <iostream>

#include <stdlib.h>



using namespace std;



int main()

{

    int a, b, c, d;

    do

    {

    cout << "Podaj liczbe: ";

    cin >> a;

    b=2;

    do

        {

                c=a%b;

                b=b+1;

        }

    while(c!=0 && b<a);

    if((b<a) || (a==0))

    cout << "Liczba nie jest pierwsza.n";

    else

    cout << "Liczba jest pierwsza.n";

    cout << "1-dla kontynuacji, 2-dla wyjscian";

    cin >> d;

  }while(d==1);

  system("PAUSE");    

  return 0;

}


--------------------
"Unix is like a vigvam - no windows, no gates, Apache inside"
Warsztat: Windows XP PE | Dreamweaver | Apache 1.3.29 | PHP 4.3.4 | Araneae | MYSQL 4 | Visual Studio | Dev-C++
[b]Programowanie: llllll 40%
Go to the top of the page
+Quote Post
Cudi
post
Post #21


Administrator planeta/IRC


Grupa: Przyjaciele php.pl
Postów: 385
Pomógł: 0
Dołączył: 19.04.2003
Skąd: Zabrze

Ostrzeżenie: (0%)
-----


PMadej: Nie zrozumiałeś go, idź przeczytaj jeszcze raz co napisał smile.gif
Cytat
To jakos tak bylo, ze: kazda liczbe calkowita da sie zapisac w postaci iloczynu liczb pierwszych.

Każdą liczbe całkowitą, więc nie jest powiedziane że po lewej stronie musi być liczba pierwsza. Tylko ze nie wiem jak to można wykorzystać przy sprawdzaniu czy dana liczba jest liczbą pierwszą winksmiley.jpg


--------------------
"Programmers are in a race with the Universe to create bigger and better idiot-proof programs, while the Universe is trying to create bigger and better idiots. So far the Universe is winning."
Cudi's devBlog
Go to the top of the page
+Quote Post
dr_bonzo
post
Post #22





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


Cytat
285311670611=11*11
niestety, nie zadziałało

tzn. nie dalo sie rozlozyc na czynniki pierwsze?


Cytat
przeciez to nie sa liczby pierwsze:
39 = 3 * 13
14 = 2 * 7
210 = 2 * 3 * 5 * 7
5610 = 2 * 5 * 11 * 17
(...)


Zgadza sie -- nie sa to liczby pierwsze, ale prosze czytaj uwazniej --
Cytat
To jakos tak bylo, ze: kazda liczbe calkowita da sie zapisac w postaci iloczynu liczb pierwszych.  


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
Jabol
post
Post #23





Grupa: Przyjaciele php.pl
Postów: 1 467
Pomógł: 13
Dołączył: 22.02.2003

Ostrzeżenie: (0%)
-----


ale zauważ, że ta liczba którą podałem też da się rozłożyć na liczby pierwsze, ale tylko jedenastki, bo zakres liczb pierwszych jest szerszy od podanego przez Ciebie.

aha, i to nie było 11 * 11, tylko 11 ^ 11, ale prawidłowość pozostaje taka sama (121 też nie rozłożysz na czynniki pierwsze w przedziale 0 < n < 10).
Go to the top of the page
+Quote Post
raf2001
post
Post #24





Grupa: Zarejestrowani
Postów: 116
Pomógł: 0
Dołączył: 14.06.2002
Skąd: Żyrardów

Ostrzeżenie: (0%)
-----


Witam!
Wtrące się do rozmowy (jeżeli to co powiem już się powtórzylo to mnie niewincie niejestem w stanie śledzić przebiegu całej rozmowy)
Liczby pierwsze można posazukiwać przez wzór 2^n-1 gdzie n-liczba pierwsza. Mój pomysl (dlatego zwracam się do was jest chyba prosty, ale niwiem jak go rozpisać). Otóz skrypt na poczatku przeszukuje liczbe pierwszą z podanego zakresu. Poźniej sprawdzony zostaje wynicz czy n jest liczbą pierwszą i zostaje wykożystany wzór 2^n-1 i znowu zostaje sprawdzony wynicz czy liczba jest liczbą pierwszą i uzyskany wynik zostaje znowu podstawiony do wzoru (zrobić to można na pętli, tylko jak).Funkcja oczywiście musiała by mieć określone ile powtórzeń ma zostać wykonanych. Czy jest to możliwe do zrealizowania?


--------------------
Go to the top of the page
+Quote Post

2 Stron V   1 2 >
Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 22.08.2025 - 03:22