Alkuluvuissa väliltä 2..20000 kymmenjärjestelmässä esitettynä on numero 0 aliedustettuna ja 1 esiintyy useiten. Luonnollisesti kaikki parilliset luvut 0,2,4,6,8 esiintyvät harvoin, koska viimeinen numero ei voi olla sellainen (kuten ei 5:nkaan) paitsi luvussa alkuluvuissa 2 (ja 5). Ohjelmoimisen ilosta ohjelmoin.
EDIT: 0 ei tietystikään ole parillinen, mutta siihen päättyvät luvut ovat.
Alkuluvuissa võliltõ 2..20000 esiintyy numero 0 540 kertaa.
Alkuluvuissa võliltõ 2..20000 esiintyy numero 1 2278 kertaa.
Alkuluvuissa võliltõ 2..20000 esiintyy numero 2 701 kertaa.
Alkuluvuissa võliltõ 2..20000 esiintyy numero 3 1252 kertaa.
Alkuluvuissa võliltõ 2..20000 esiintyy numero 4 681 kertaa.
Alkuluvuissa võliltõ 2..20000 esiintyy numero 5 673 kertaa.
Alkuluvuissa võliltõ 2..20000 esiintyy numero 6 665 kertaa.
Alkuluvuissa võliltõ 2..20000 esiintyy numero 7 1220 kertaa.
Alkuluvuissa võliltõ 2..20000 esiintyy numero 8 652 kertaa.
Alkuluvuissa võliltõ 2..20000 esiintyy numero 9 1222 kertaa.
Eratostheneen seulaa käytin: https://fi.wikipedia.org/wiki/Eratostheneen_seula
program Eratostheneenseula; uses SysUtils; const maxluku=20000; // lasketaan maxluku:a pienemmät alkuluvut Eratostheneen seulalla var taulukko: array [1..maxluku] of boolean; // totuusarvo sille on indeksi alkuluku i,ci: integer; neliojuuri: Double; luku: integer; lukuMerkkijonona: String; esiintymat: array [0..9] of integer; begin neliojuuri:=sqrt(maxluku); for i:=2 to maxluku do taulukko[i]:=true; //oletetaan kaikki alkuluvuiksi taulukko[1]:=false; //paitsi ensimmäinen i:=2; while i<=maxluku do //poistetaan kakkosen monikerrat begin taulukko[i]:=false; i:=i+2; end; luku:=2; while luku <= neliojuuri do begin while (taulukko[luku] = false) and (luku < neliojuuri) do // etsitään seuraava alkuluku luku:=luku+1; i:=2*luku; while i<=maxluku do begin taulukko[i]:=false; //poistetaan sen monikerrat i:=i+luku; end; luku:=luku+1; end; taulukko[2]:=true; for i:=0 to 9 do esiintymat[i]:=0; // alustetaan esiintymät nolliksi for i:=1 to maxluku do if taulukko[i] then begin lukuMerkkijonona := IntToStr(i); for ci:=1 to Length(lukuMerkkijonona) do esiintymat[StrToInt(lukuMerkkijonona[ci])]:=esiintymat[StrToInt(lukuMerkkijonona[ci])]+1; end; //for i:=1 to maxluku do if taulukko[i] then writeln(i); for i:=0 to 9 do writeln('Alkuluvuissa väliltä 2..', maxluku, ' esiintyy numero ', i , ' ', esiintymat[i], ' kertaa.'); end.
PetriKeckman kirjoitti:
EDIT: 0 ei tietystikään ole parillinen, mutta siihen päättyvät luvut ovat.
Nolla on parillinen luku ainakin matematiikassa ja ohjelmoinnissa.
En oikein keksi missä yhteydessä se olisi pariton luku, eli siis luku, jossa muodostettaessa pareja jäisi yksi yli.
Alkulukujen joukossa 0 ei ole parillinen, koska se ei edes kuulu alkulukujen joukkoon ;)
Jatkan turhia tutkimuksiani - ohjelmoimisen ilosta. Nyt kun alkuluvut väliltä 2..20000 on selvitetty totuusarvoiseen taulukkoon Array[1..20000] Of BOOLEAN, niin niiden avulla voidaan tsekata onko jokin luku väliltä 20000..(20000*20000)=400 miljoonaa alkuluku. Edellisessä ohjelmassa taulukon kokoa rajoittaa, että const saa olla vain korkeintaan 32767 (tosin se oli 20000).
Jätin ohjelman pyörimään kello 20:11. Saa nähdä valmistuuko huomiseksi :) Mitä veikkaatte?
program Eratostheneenseula; uses SysUtils; const maxluku=20000; // lasketaan maxluku:a pienemmät alkuluvut Eratostheneen seulalla var taulukko: array [1..maxluku] of boolean; // totuusarvo sille on indeksi alkuluku i,ci: integer; neliojuuri: Double; luku,indeksi: integer; lukuMerkkijonona: String; esiintymat: array [0..9] of integer; suurin,j: LongInt; function onalkuluku(tutkittavaluku:LongInt):boolean; //tutkitaan onko tutkittavaluku alkuluku //Eratostheneen seulalla saadun taulukon avulla var onalku: boolean; begin if (tutkittavaluku=2) or (tutkittavaluku=3) then onalku:=true else begin onalku:=true; //oletetaan alkuluvuksi indeksi:=3; while (onalku and (indeksi<=sqrt(tutkittavaluku))) do begin if taulukko[indeksi] then begin if (tutkittavaluku mod indeksi)=0 then begin onalku:=false; end; end; indeksi:=indeksi+2; end; //siirrytään seuraavaan alkulukuun while (taulukko[indeksi]=false) and (indeksi<=sqrt(tutkittavaluku)) do begin indeksi:=indeksi+2; end; end; onalkuluku:=onalku; end; begin neliojuuri:=sqrt(maxluku); for i:=2 to maxluku do taulukko[i]:=true; //oletetaan kaikki alkuluvuiksi taulukko[1]:=false; //paitsi ensimmäinen i:=2; while i<=maxluku do //poistetaan kakkosen monikerrat begin taulukko[i]:=false; i:=i+2; end; luku:=2; while luku <= neliojuuri do begin while (taulukko[luku] = false) and (luku < neliojuuri) do // etsitään seuraava alkuluku luku:=luku+1; i:=2*luku; while i<=maxluku do begin taulukko[i]:=false; //poistetaan sen monikerrat i:=i+luku; end; luku:=luku+1; end; taulukko[2]:=true; //nyt ollaan taulukoitu lukujen 1..maxluku alkuluvullisuuden totuusarvot for i:=0 to 9 do esiintymat[i]:=0; // alustetaan esiintymät nolliksi esiintymat[2]:=1; //paitsi 2 suurin:=maxluku*maxluku; j:=3; while j<=suurin do begin if onalkuluku(j) then begin lukuMerkkijonona := IntToStr(j); for ci:=1 to Length(lukuMerkkijonona) do esiintymat[StrToInt(lukuMerkkijonona[ci])]:=esiintymat[StrToInt(lukuMerkkijonona[ci])]+1; end; j:=j+2; end; //for i:=1 to maxluku do if taulukko[i] then writeln(i); for i:=0 to 9 do writeln('Alkuluvuissa väliltä 2..', maxluku*maxluku, ' esiintyy numero ', i , ' ', esiintymat[i], ' kertaa.'); end.
Veikkaan, että ohjelma tietysti kaatuu Number Overflow...siis lukujen esiintymiä tulee niin paljon, täytyy laittaa uudestaan pyörimään. Muutan taulukon alkion tyypiksi LongInt. Saa nähdä auttaako, tai ehkä Double?
EDIT: Väärä hälytys! :) Integer tyyppihän saa olla jopa 2147483647
Ehän tuohon mennyt kuin 20 minuuttia!
Alkuluvuissa võliltõ 2..400000000 esiintyy numero 0 23683 kertaa.
Alkuluvuissa võliltõ 2..400000000 esiintyy numero 1 12196 kertaa.
Alkuluvuissa võliltõ 2..400000000 esiintyy numero 2 14774 kertaa.
Alkuluvuissa võliltõ 2..400000000 esiintyy numero 3 -4103 kertaa.
Alkuluvuissa võliltõ 2..400000000 esiintyy numero 4 -16508 kertaa.
Alkuluvuissa võliltõ 2..400000000 esiintyy numero 5 -29616 kertaa.
Alkuluvuissa võliltõ 2..400000000 esiintyy numero 6 26234 kertaa.
Alkuluvuissa võliltõ 2..400000000 esiintyy numero 7 -20672 kertaa.
Alkuluvuissa võliltõ 2..400000000 esiintyy numero 8 12151 kertaa.
Alkuluvuissa võliltõ 2..400000000 esiintyy numero 9 26365 kertaa.
EDIT: Oho! Kiersivät jotkin luvut ympäri negatiiviseksi.
EDIT2: En tajua mitä tässä on tapahtunut. Testasin ohjelmaa 10:llä ja se toimi eli välillä 2..10*10.
Kenties sulla on käytössä 16-bittiset kokonaisuluvut, ainakin kaikki sopisivat välille -32768 - +32767.
Itse sain tällaisen tulokset 2 - 400 000 000
0 : 14310531
1 : 25636772
2 : 20134326
3 : 25358329
4 : 14925700
5 : 14912592
6 : 14902906
7 : 20229952
8 : 14888823
9 : 20211453
Laskennassa meni aikaa vajaa 6 sekuntia Eratostheneen seulalla.
const int maxNum = 20000; //Alkuluvut 2-400 000 000 //Käsitellään vain parittomia lukuja, niin säästyy puolet muistista int sieveSize = (maxNum * maxNum) >> 1; int halfMaxNum = maxNum >> 1; var sieve = new byte[sieveSize]; //Siivilöidään alkuluvuilla, jotka välillä [3,19999] for (int i = 1; i < halfMaxNum; i++) { if (sieve[i] == 0) { var a = (i << 1) + 1; var j = a + i; while (j < sieveSize) { sieve[j] = 1; j += a; } } } //Lasketaan jäljelle jääneiden alkulukujen numerot var num = new int[10]; for (int i = 1; i < sieveSize; i++) { if (sieve[i] == 0) { var n = (i << 1) + 1; while (n > 0) { num[n % 10]++; n /= 10; } } } num[2]++; //Lisätään ainoa parillinen alkuluku 2, koska sitä ei käsitellä ylempänä for (int i = 0; i < 10; i++) { Console.WriteLine($"{i} : {num[i]}"); }
Grez kirjoitti:
0 : 14310531
1 : 25636772
2 : 20134326
3 : 25358329
4 : 14925700
5 : 14912592
6 : 14902906
7 : 20229952
8 : 14888823
9 : 20211453
Joo. Nyt sain samat tulokset kuin sinä, kun käytin esiintymien laskentaan Currency liukulukua.
Alkuluvuissa võliltõ 2..400000000 esiintyy numero 0 1.4310531000000E+07 kertaa.
Alkuluvuissa võliltõ 2..400000000 esiintyy numero 1 2.5636772000000E+07 kertaa.
Alkuluvuissa võliltõ 2..400000000 esiintyy numero 2 2.0134326000000E+07 kertaa.
Alkuluvuissa võliltõ 2..400000000 esiintyy numero 3 2.5358329000000E+07 kertaa.
Alkuluvuissa võliltõ 2..400000000 esiintyy numero 4 1.4925700000000E+07 kertaa.
Alkuluvuissa võliltõ 2..400000000 esiintyy numero 5 1.4912592000000E+07 kertaa.
Alkuluvuissa võliltõ 2..400000000 esiintyy numero 6 1.4902906000000E+07 kertaa.
Alkuluvuissa võliltõ 2..400000000 esiintyy numero 7 2.0229952000000E+07 kertaa.
Alkuluvuissa võliltõ 2..400000000 esiintyy numero 8 1.4888823000000E+07 kertaa.
Alkuluvuissa võliltõ 2..400000000 esiintyy numero 9 2.0211453000000E+07 kertaa.
Free Pascalissa on se ongelma, että tosiaan CONST vakioita ei voi määrittää kuin kai 16-bittisinä ja sitä tarvitaan taulukon määrittämiseen. Yritin kyllä kokeilla jotain Array[1..400000000] taulukkoa - se meni kääntäjästä läpi, mutta muu koodi kaatui muistaakseni jo käännösvaiheessa sitten.
Joo freepascalissa kannattanee käyttää LongInt tyyppiä jos varmasti haluaa 32-bittisen kokonaisluvun. Ilmeisesti integer voi tarkoittaa joko SmallInt (16-bit) tai LongInt. On siellä Int64 myös jos tarvii n. 2 miljardia (tai etumerkittömillä Uint32 n. 4 miljardia) isompia.
PetriKeckman kirjoitti:
käytin esiintymien laskentaan Currency liukulukua.
Currency ei käsittääkseni ole varsinaisesti liukuluku vaan 64-bittinen kokonaisluku, jossa piste on lukittu 4 desimaalin päähän lopusta. (Eli siis fixed point, ei floating point). No freepascalin wikissäkin nähtävästi se on laitettu liukuluvut (floating point) -kategoriaan, että sinänsä ei voi sinua syyttää tuon termin käytöstä :D
Kuinka monta prosenttia Fibonaccin luvuista on alkulukuja? Raja-arvo? Onko se nolla? Hankala sanoa...Mitenhän sitä empiirisesti tutkisi? Huomasin:
"Unsolved problem in mathematics:
Are there an infinite number of Fibonacci primes?
"
https://en.wikipedia.org/wiki/Fibonacci_prime
Eli, jos niitä olisi äärellinen määrä, niin sitten raja-arvo ei olisikaan nolla. EDIT: Heh! Sori! Eiku toistepäin!! :)
Fibonaccin lukuja võlillõ 1..4 on 4, joista alkulukuja 2 kappaletta eli 5.0E+0001 prosenttia.
Fibonaccin lukuja võlillõ 1..9 on 6, joista alkulukuja 4 kappaletta eli 6.7E+0001 prosenttia.
Fibonaccin lukuja võlillõ 1..16 on 7, joista alkulukuja 5 kappaletta eli 7.1E+0001 prosenttia.
Fibonaccin lukuja võlillõ 1..25 on 8, joista alkulukuja 5 kappaletta eli 6.3E+0001 prosenttia.
Fibonaccin lukuja võlillõ 1..36 on 9, joista alkulukuja 6 kappaletta eli 6.7E+0001 prosenttia.
Fibonaccin lukuja võlillõ 1..49 on 9, joista alkulukuja 6 kappaletta eli 6.7E+0001 prosenttia.
Fibonaccin lukuja võlillõ 1..64 on 10, joista alkulukuja 6 kappaletta eli 6.0E+0001 prosenttia.
Fibonaccin lukuja võlillõ 1..81 on 10, joista alkulukuja 6 kappaletta eli 6.0E+0001 prosenttia.
Fibonaccin lukuja võlillõ 1..100 on 11, joista alkulukuja 7 kappaletta eli 6.4E+0001 prosenttia.
.
.
.
Fibonaccin lukuja võlillõ 1..100000000 on 39, joista alkulukuja 11 kappaletta eli 2.8E+0001 prosenttia.
.
.
.
Fibonaccin lukuja võlillõ 1..1024000000 on 44, joista alkulukuja 12 kappaletta eli 2.7E+0001 prosenttia.
program Eratostheneenseula; uses SysUtils; const maxluku=32000; // lasketaan maxluku:a pienemmät alkuluvut Eratostheneen seulalla var taulukko: array [1..maxluku] of boolean; // totuusarvo sille onko indeksi alkuluku i: integer; neliojuuri: Double; luku,indeksi,luku1,luku2,luku3: LongInt; suurin,lukumaaraalkuluku,lukumaarafib,maxluku2: LongInt; function onalkuluku(tutkittavaluku:LongInt):boolean; //tutkitaan onko tutkittavaluku alkuluku //Eratostheneen seulalla saadun taulukon avulla var onalku: boolean; begin if (tutkittavaluku=1) then onalku:=false else if (tutkittavaluku=2) or (tutkittavaluku=3) then onalku:=true else begin onalku:=true; //oletetaan alkuluvuksi indeksi:=3; while (onalku and (indeksi<=sqrt(tutkittavaluku))) do begin if taulukko[indeksi] then begin if (tutkittavaluku mod indeksi)=0 then begin onalku:=false; end; end; indeksi:=indeksi+2; end; //siirrytään seuraavaan alkulukuun while (taulukko[indeksi]=false) and (indeksi<=sqrt(tutkittavaluku)) do begin indeksi:=indeksi+2; end; end; onalkuluku:=onalku; end; begin neliojuuri:=sqrt(maxluku); for i:=2 to maxluku do taulukko[i]:=true; //oletetaan kaikki alkuluvuiksi taulukko[1]:=false; //paitsi ensimmäinen i:=2; while i<=maxluku do //poistetaan kakkosen monikerrat begin taulukko[i]:=false; i:=i+2; end; luku:=2; while luku <= neliojuuri do begin while (taulukko[luku] = false) and (luku < neliojuuri) do // etsitään seuraava alkuluku luku:=luku+1; i:=2*luku; while i<=maxluku do begin taulukko[i]:=false; //poistetaan sen monikerrat i:=i+luku; end; luku:=luku+1; end; taulukko[2]:=true; //nyt ollaan taulukoitu lukujen 1..maxluku alkuluvullisuuden totuusarvot for maxluku2:=2 to 32000 do begin suurin:=maxluku2*maxluku2; luku1:=1; luku2:=1; luku3:=luku1+luku2; lukumaaraalkuluku:=0; lukumaarafib:=2; while luku3<=suurin do begin lukumaarafib:=lukumaarafib+1; //writeln(luku3, ' on Fibonaccin luku'); if onalkuluku(luku3) then begin lukumaaraalkuluku:=lukumaaraalkuluku+1; //writeln(luku3, 'on alkuluku'); end; luku1:=luku2; luku2:=luku3; luku3:=luku1+luku2; end; writeln('Fibonaccin lukuja välillä 1..', suurin, ' on ', lukumaarafib, ', joista alkulukuja ', lukumaaraalkuluku, ' kappaletta eli ' ,100*lukumaaraalkuluku/lukumaarafib:4 , ' ', 'prosenttia.'); end; end.
Aihe on jo aika vanha, joten et voi enää vastata siihen.