13.) Írj programot,
amely egy egydimenziós számtömböt kezel. Megkérdezi, hány elemű a tömb, aztán
beolvassa a tömböt, majd megkeresi a legnagyobbat és legkisebbet, kiszámítja a
számok átlagát, végül növekedő sorrendben kiírja a számokat a képernyőre.
Eddigi programjainkban
az ismétlő eljárások szerepe az volt, hogy egy programrészletet többször is
végre kellett hajtani, leírni viszont csak egyszer írtuk le. Ez a program arra
ad megoldást, hogyan lehet nagyszámú ismeretlent kezelni. Gyakran előfordul
ugyanis, hogy egy programban több száz, esetleg több ezer adat szerepel.
Értékeinek tárolására tehát nagyon nagyszámú változóra lenne szükség.
Szerencsére, nagyon gyakran, a nagyszámú adat ugyanolyan jellegű. Ezek
tárolására a matematikából ismert vektort vagy mátrixot használják a
programnyelvek. Itt ezeket tömböknek nevezzük. Aszerint, hogy hány index
segítségével írhatók le, léteznek egy-, két- esetleg három-, négy- vagy
magasabb dimenziójú tömbök. Egy egyszerű névsor egydimenziós, de egy ülésrend,
vagy egy órarend kétdimenziós. Ebben a programban egydimenziós számtömbbel
találkozhatunk.
A tömb azonosítója: sz.
A tömb elemeit indexek segítségével írhatjuk le. Az indexeket szögletes
zárójelben kell feltüntetni: Sz[8] jelenti az Sz tömb 8. elemét. A
tömb deklarációját az Array … Of
szópár segítségével adjuk meg. Az Array után fel kell tüntetni az indexeket [kezdőérték .. végérték]
formában, mely leggyakrabban egész szám. Kezdőérték és végérték tetszőleges
lehet, az indexek egyesével növekszenek. Az index csak sorszámozott típus lehet,
azaz: byte, integer, word, char, logikai felsorolt és intervallum. A Of utáni típusnév határozza meg a tömb
elemeinek típusát, ez példánkban egész. Magasabb dimenziójú tömbnél a
további indexek felsorolását vesszővel kell elválasztani, pl.:
T: Array[1..4,2..10,5..8] Of String.
Ez a T egy háromdimenziós String tömb, elemeinek száma: 4*9*4=144, T[3,6,6] pedig egy eleme. A programban egy újfajta
azonosító típust is találunk, ez pedig a
konstans: Const. Típusát a
kapott értéke azonosítja, példánkban ez egész.
Haszna az, hogy a programban sok helyen szerepelhet egy olyan, általában limit
érték, ahová mindig ki kellene azt írni, ami még nem is lenne nagy baj, de ha a
limit-et változtatni szeretnénk, akkor a listában végig mindenütt ki kellene
cserélni a helyesre, így viszont csak a program fejében, egyetlen helyen kell
cserét végrehajtani. A tömb deklarációjában is
használhatjuk. Így a program maximum Max
db szám
kezelésére alkalmas. Az aktuális darabszámot az N tartalmazza.
Nézzük meg, hogy jut ez az érték a programba: a ReadLn eljárással. Ez az első olyan
programunk, amely futás közben tőlünk adatot vár, mert a beadott érték
függvényében tud a továbbiakban dolgozni. A
program azt
kérdezi meg, hogy hány számmal szeretnénk dolgozni.
Ezt a bekérést úgy teszi, hogy mindaddig újra kérdez, ameddig 1..Max intervallumból
nem adunk N-nek értéket. Ezt a Repeat … Until ismétlő eljárással
lehet elegánsan megoldani. Az ismétlő eljárás
leállításáról egy intervallumba való tartozás vizsgálata gondoskodik, melynek
kulcsszava: In. Az első
For ciklus a
tömb elemeit kéri be, mindig kiírva, hogy hányadikat kérdezi. Az
utolsó tömbelem beírása után a program a végéig lefut. Az
Lk:= MaxInt; értékadással a lehető legnagyobb értéket veszi fel az Lk. A MaxInt
előre definiált konstans, értéke 32767. Azaz, ha helyesen írtunk be egészeket,
akkor a legkisebb ennél kisebb egyenlő. Ehhez hasonlítva a tömbelemeket és
cserélve, választja ki a legkisebbet. Az Ln:= -MaxInt-1; a legkisebb egész
számot jelenti, azaz a legnagyobb ennél nagyobb vagy egyenlő. A
következő programrészlet ezt keresi meg, végighaladva a
tömb elemein.
Program SzamTomb;
Uses NewDelay,
Crt, CrtPlus;
Const Max=20;
Var Sz: Array[1..Max] Of Integer;
I,J,Lk,Ln,N,S,Puf: Integer;
Atl:Real;
Begin
TextMode(CO80);
Szinek(1,15);
Repeat
ClrScr;
Write('Hány számmal dolgozol? ');
Szinek(1,14);
ReadLn(N);
Until
N In [1..Max];
For
I:= 1 To N Do
Begin
Write('Kérem a(z) ',I:3,'. számot: ');
ReadLn(Sz[I]);
End;
Lk:= MaxInt;
For
I:= 1 To N Do
If
Sz[I]<Lk Then Lk:= Sz[I];
Ln:= -MaxInt-1;
For
I:= 1 To N Do
If
Sz[I]>Ln Then Ln:= Sz[I];
Writeln('A legkisebb szám: ',Lk);
Writeln('A legnagyobb szám: ',Ln);
S:= 0;
For
I:= 1 To N Do S:= S+Sz[I];
Atl:= S/N;
Szinek(1,6);
Writeln('A
számok átlaga: ',Atl:10:2);
For
I:= 1 To N-1 Do For J:= I+1 To N Do
If
Sz[I]>Sz[J]
Then
Begin
Puf:= Sz[I];
Sz[I]:= Sz[J];
Sz[J]:= Puf;
End;
For I:= 1 To N Do
Write(Sz[I],’ ’);
Tunj;
Varj;
End.
A számok átlagának
meghatározásához össze kell adni őket. Az összeget a program az s változóban
tárolja, ezért az összegzés előtt célszerű kinullázni. Az összegzést For ciklussal hajtjuk végre, a
következő tömbelem ismételt hozzáadásával. Az átlaghoz az összeget n-nel kell
osztani. Az átlag érték nem feltétlen egész szám, sőt mivel osztással
keletkezett, a Pascal biztosan Real-két kezeli. Real: valós számot takar, azaz
itt tizedes törtet. Ezért deklaráltuk az Atl-ot Real-nek.
Gyakran előfordul, hogy
elemeket sorba kell rendezni. Nagy elemszám esetén a rendezés időigényes
tevékenység. A rendezés végrehajtására többféle eljárást dolgoztak ki. Itt nem
a leggyorsabb, de talán a legérthetőbb eljárás rendez, melynek alapja a
közvetlen összehasonlítás. A külső ciklus az első elemtől az utolsó előttiig
megy, a belső a külső aktuális értékétől az utolsó elemig. Mire a kettős ciklus
lejár, bármely két elem össze lesz hasonlítva, és ha nem jó sorrendben voltak,
fel lesznek cserélve, azaz biztosan jó sorrendben fognak szerepelni a tömbben.
A módszert szokás közvetlen összehasonlításnak nevezni. A kiírást egy egyszerű For ciklus végzi.
Gyakorló programozási feladatok:
F.13: Készíts ülésrendet. Alul a tanári asztal,
felette 4 * 6 -os elrendezésben az osztály. A neveket a programlistában
tároljuk. Tudjon két tanuló helyet cserélni, melyet inputról irányíthatunk.
F.14: Készíts órarendet. Az oszlop és sorfejeket
(nap és óra) a program listában tárolja, de az órákat oszlop-folytonosan
lehessen beírni.
F.15: Készíts bizonyítványt. A tantárgyakat a
program tárolja, de a tantárgyi eredményeket inputról kéri. A magatartás és
szorgalom kivételével átlagot számít.
F.16: Készíts naplót, jegylezárással. A
tantárgyakat a program tárolja, de az 5 hónap jegyeit sorfolytonosan nekünk
kell beírni. Számítson tantárgyi átlagból félévi érdemjegyet, és a szokásos
módon tanulmányi átlagot.
F.17:
Írj programot, amely eldönti, hogy egy számtömb átlaga benne van-e a tömbben.
14.) Írjunk
programot, amely egy LOTTO szelvényt jelenít meg, válasszon véletlenül 5 számot
lottószámként, ezeket a számokat a képernyőn villogtassa, valamint külön is írja
ki a kiválasztott számokat.
A program a kihúzott
számokat a ki nem húzottaktól egy logikai tömb segítségével különbözteti meg.
Ennek neve Mutato. Ha egy szám, pl.: a 21-es ki lett húzva, akkor Mutato[21]
értéke True, ha nem, akkor False. A
lista első néhány ciklusa a látvány megjelenítését
végzi. A lottószelvény felrajzolásának utolsó lépése a
számok kiírása 1-től 90-ig.
Ez azt jelenti, hogy egy vektort tömbként (6*15-ös alakban) kell megjeleníteni.
Ez is tanulságos feladat, célszerű megjegyezni, mert gyakran előfordulhat ilyen
jellegű probléma. Ezt az első 90-ig futó ciklus hajtja végre. Nézzük a ciklus
magjában lévő GoToXY két paraméterét. Két új műveletet találunk benne: Mod és Div. A Mod eredménye a
két oldalán lévő szám egész osztásához tartozó maradék (előtte az osztandó,
mögötte az osztó), azaz: 14 Mod 3
értéke 1, mert 14-et 3-al osztva 1 maradékot kapunk. A Div eredménye a két oldalán lévő szám egész osztásának hányadosa,
azaz 14 Div 3 értéke 4, mert 14-ben
a 3 négy egész-szer van meg. E két művelet segítségével érhetjük el, hogy egy For ciklus 1-től 90-ig számol, közben
az X érték 6-szor kezd növekedéshez (0-15) és az Y csak
Program Lotto;
Uses NewDelay,
Crt, CrtPlus;
Var I,J,V: Byte;
Mutato: Array[1..90] Of Boolean;
begin
TextMode(CO80);
Szinek(Blue,Yellow);
ClrScr;
Racs(3,1,4,1,15,6);
For I:= 1 To
90 Do
Begin
GotoXY(((I-1) Mod 15)*5+5,((I-1) Div
15)*2+2);
Write(I:2);
End;
For
I:= 1 To 90 Do Mutato[I]:= False;
Randomize;
For
I:= 1 To 5 Do
Begin
Repeat
V:= Random(90)+1;
Until
Not Mutato[V];
Mutato[V]:= True;
End;
Szinek(Blue,Yellow+Blink);
For
I:= 1 To 90 Do If Mutato[I] Then
Begin
GotoXY(((I-1) Mod 15)*5+5,((I-1) Div
15)*2+2);
Write(I:2);
End;
Szinek(Blue,Yellow);
WriteXY(1,20,’A nyerőszámok: ’);
For I:= 1 To
90 Do If Mutato[I] Then
Write(I:4);
Tunj;
Varj;
End.
A következő 90-es For ciklus a logikai tömb értékét False-ra
állítja. A Randomize beindítja a véletlen-szám generátort. Az 5 lottószámot egy
5-ig menő For ciklus állítja elő. A
véletlen választás mindig a 90 számból történik, ezért gondoskodni kell az
újraválasztás kizárásáról. Ezt szolgálja a logikai tömb. A lottószám generáló
ciklusban a véletlen választás Repeat-el
addig ismétlődik, ameddig ki nem húzott számot nem választ a gép. A Repeat elhagyása egy új számot jelent,
melynek mutatóját a ciklus True-ra állítja. A továbbiakban a számok villogtatása,
illetve egyszerű kiíratása történik. Mivel a mutatók nem keverednek, ezért
indexük a kihúzott számmal megegyeznek, azaz végül nem kell a nagyság szerinti
kiíráskor a lottószámokat rendezni. Figyeljük meg, hogy a programban a Mutato
tömb elemeit, mint logikai értékeket használjuk, és nem írtunk olyat a Repeat leállításánál, hogy: Until Mutato[V]=False,
helyette: Not Mutato[V].
15.)
Irj programot, amely bekéri egy háromszög három oldalát, majd megvizsgálja,
valóban lehet-e a három távolság egy háromszög három oldala, ha igen, akkor
kiszámolja a háromszög kerületét és területét, valamint megállapitja, hogy a
háromszög hegyes-, derék- vagy tompaszögű.
Ha jól meggondoljuk,
ennek a programnak négy fő tevékenysége van: bekéri az adatokat, megvizsgálja,
kiszámítja a kerületet és területet, valamint minősíti a háromszöget. A
főprogram összesen ennek a négy tevékenységnek a hívásából áll, minden
tevékenységre eljárást irtunk. Igy célszerű eljárni azokban az esetekben, ha a
program sok, de külön-külön jól elhatárolt részfeladatokra bontható. Az Adatbe
eljárás egyetlen érdekessége: ha azt akarjuk, hogy a képernyőn idézőjel
jelenjék meg, meg kell kettőzni. A vizsgál rutinban két új dolog van: az Or logikai művelet, amely magyarul Vagy. Akkor igaz, ha valamelyik tagja
igaz a logikai kifejezésnek. Egyébként a háromszög-egyenlőtlenség
teljesülésének vizsgálatához használtuk a listában. A másik a Halt eljárás,
mely feltétel nélkül befejezi a programunk futtatását és visszaadja a
vezérlést, a programot hívó környezetnek. A KerTer eljárásban talán a Heron
képlet érdemel említést, mely húrnégyszögek területének kiszámítására alkalmas
az oldalak ismeretében. Ki kell számolni a húrnégyszög fél-kerületét, minden
oldalt ki kell belőle vonni, össze kell szorozni, a szorzat négyzetgyöke adja a
húrnégyszög területét. Mivel d=0 választással a húrnégyszög háromszöggé fajul,
a képlet háromszögekre is alkalmazható.
A Minoseg eljárásban
fontos új dolog található. Ez pedig a többszörös elágazás (szelekció), ahol az
ágak közül csak legfeljebb egy hajtódik végre. A minősítés Pithagorasz tétele
alapján történik. Mivel a háromszög oldalai bármilyen nagyság szerint következhetnek,
először meg kell állapítani, hogy melyik oldal a legnagyobb. Első esetben az A,
másodikban a B és harmadik esetben a C oldal. Erre azért volt szükség, hogy
Pithagorasz tételét fel tudjuk írni. Mindhárom esetben létezhet mindhárom csoport,
hogy a megfelelő alakban írjuk fel a Pithagorasz tételt, esetenként kell
szétválogatni a lehetőségeket, mivel ez három eset, célszerű a már említett
többszörös elágazást alkalmazni. Ennek kulcsszavai: Case … Of … Else … End; A Case és Of közé kerül a diszkrét értékeket
felvevő szelektor. A Case strukturált
párja az End;. Közéjük a szelektor
értékekkel kezdődő sorokat bekezdésesen kell írni. A szelektor értékek után
kettőspontot kell írni, melyet egyetlen utasítás követhet. Ha több utasítást
szeretnénk elhelyezni, akkor összetett utasítás kell alkalmazni. Ha bizonyos
értékekre mondjuk csak meg, hogy mi a teendő, az összes többi esetén pedig
valami egyéb a tevékenység, akkor ezt a szelektor lista végén Else mögé kell írni (programunkból ez
most hiányzik). A csoportba sorolás kiírásánál még egyszerűbb Case utasítást látunk. Ha a szelektor
olyan értéket vesz föl, amely nincs felsorolva a Case … End;-ben, akkor a
szerkezet egyetlen utasítása sem hajtódik végre (csak maga a Case). Ezek után a lista:
Program Haromsz;
Uses NewDelay,
Crt, CrtPlus;
Var A,B,C,T,K:
Real;
Procedure Adatbe;
Begin
TextMode(CO80);
ClrScr;
Write('Kérem a háromszög ''a'' oldalát: ');
ReadLn(A);
Write('Kérem a háromszög ''b'' oldalát: ');
ReadLn(B);
Write('Kérem a háromszög ''c'' oldalát: ');
ReadLn(C);
End;
Procedure Vizsgal;
Begin
If
(A+B<=C) Or (A+C<=B) Or (B+C<=A) Then
Begin
Writexy(1,6,'Az adatok nem lehetnek egy
háromszög oldalai!');
Tunj;
Varj;
Halt;
End;
End;
Procedure KerTer;
Var S: Real;
Begin
K:= A+B+C;
S:= K/2;
T:= Sqrt(S*(S-A)*(S-B)*(S-C));
WriteXY(1,6,'A háromszög kerülete: '); Write(K:8:4);
WriteXY(1,8,'A háromszög területe: '); Write(T:8:4);
End;
Procedure Minoseg;
Var Eset,Csop:
Byte;
Begin
If
(A>=B) And (A>=C) Then Eset:= 1;
If
(B>=A) And (B>=C) Then Eset:= 2;
If
(C>=A) And (C>=B) Then Eset:= 3;
Case
Eset Of
1: If
A*A<B*B+C*C Then Csop:=1 Else
If A*A=B*B+C*C Then Csop:=2 Else Csop:=3;
2: If
B*B<A*A+C*C Then Csop:=1 Else
If B*B=A*A+C*C Then Csop:=2 Else Csop:=3;
3: If
C*C<A*A+B*B Then Csop:=1 Else
If
C*C=A*A+B*B Then Csop:=2 Else Csop:=3;
End;
Case
Csop Of
1: WriteXY(1,12,'A háromszög hegyesszögű');
2: WriteXY(1,12,'A háromszög derékszögű');
3: WriteXY(1,12,'A háromszög tompaszögű');
End;
Tunj;
Varj;
End;
Begin
Adatbe;
Vizsgal;
KerTer;
Minoseg;
End.
16.) Írjunk
programot, amely bekéri egy másodfokú egyenlet három együtthatóját, majd ez
alapján megoldja az egyenletet.
Mivel a lista semmilyen új programozási elemet
nem tartalmaz, ezért elemzésétől eltekintünk. Íme a program:
Program Masodf;
Uses NewDelay,
Crt, CrtPlus;
Var A,B,C,D,X1,X2:
Real;
Procedure Adatbe;
Begin
TextMode(CO80);
ClrScr;
Write('Kérem a másodfokú egyenlet ''a''
együtthatóját: '); ReadLn(A);
Write('Kérem a másodfokú egyenlet ''b'' együtthatóját:
'); Readln(B);
Write('Kérem a másodfokú egyenlet ''c''
együtthatóját: '); Readln(C);
End;
Procedure Vizsgal;
Begin
If
A=0 Then
Begin
WriteXY(1,10,’Az egyenlet nem másodfokú’);
Tunj;
Varj;
Halt;
End;
D:= B*B-4*A*C;
If
D<0 Then
Begin
WriteXY(1,10,’Az egyenletnek nincs valós
gyöke’);
Tunj;
Varj;
Halt;
End;
End;
Procedure Gyokok;
Begin
X1:=(-B-Sqrt(D))/2/A;
X2:=(-B+Sqrt(D))/2/A;
WriteXY(1,10,’Az egyenlet gyökei:’);
Write(X1:12:4,’ és ’,X2:12:4);
Tunj;
Varj;
End;
Begin
Adatbe;
Vizsgal;
Gyokok;
End.
17.) Írjunk
feleltető programot. A kérdések 10 és 20 közötti számok szorzatára vonatkozzon.
Számolja össze a helyes és a rossz válaszokat folyamatosan, a végén adjon
érdemjegyet a százalékos teljesités függvényében. A kérdések számát kérdezze
meg a program.
A program listájában
talán csak egyetlen hely van, amely magyarázatra szorul. A felelő válaszait a
képernyőnek mindig ugyanarra a helyére kell írni. Az újabb válaszokat a régi
válaszok a jelenlétükkel zavarnák. Eddigi ismereteink szerint a képernyőt le
kellene törölni, és a kérdésfeltevést mindig üres lappal kellene indítani,
ehelyett a listában egy újabb eljárást látunk, a ClrEOL-t, aminek az a szerepe,
hogy a képernyőn a kurzor helyétől a sor végéig letörli a képernyősor
tartalmát, így tüntetve el az előző inputok értékeit. A lista egyéb részlete
könnyen értelmezhető.
Program Kerdezo;
Uses NewDelay,
Crt, CrtPlus;
Var A,B,I,N,Jv,Rv,V,Ej:
Integer;
Sz: Real;
Begin
TextMode(CO80);
ClrScr;
Write('Hány szorzást kérdezzek? ');
ReadLn(N);
WriteXY(30,8,'Mivel egyenlő:');
Randomize;
For
I:= 1 To N Do
Begin
A:= Random(11)+10;
B:= Random(11)+10;
GoToXY(31,10); Write(A:2,' * ',B:2,' = '); ClrEOL;
ReadLn(V);
If V=A*B Then
Begin
Inc(Jv);
Sound(1000);
Delay(200);
NoSound;
End
Else
Begin
Inc(Rv);
Sound(100);
Delay(200);
NoSound;
End;
GoToXY(15,15); Write('Jó válasz: ',Jv);
GoToXY(45,15); Write('Rossz válasz: ',Rv);
End;
Sz:= Jv/N;
Ej:= 1;
If
Sz>1/3 Then Ej:= 2;
If
Sz>1/2 Then Ej:= 3;
If
Sz>2/3 Then Ej:=4;
If
Sz>17/20 Then Ej:=5;
GoToXY(1,20);
Write('Érdemjegyed: ',Ej);
Tunj;
Varj;
End.
18.) Írj
programot, amely meghatározza két szám legnagyobb közös osztóját és legkisebb
közös többszörösét.
A feladatot Euklideszi
algoritmussal oldjuk meg: Ha A és B a két szám, akkor A-t oszd el maradékosan B-vel,
majd A szerepét vegye át B, B szerepét pedig a maradék, és az osztást és a
cserét végezd mindaddig, amíg a maradék 0 nem lesz, ekkor az utolsó osztó a
legnagyobb közös osztó. Ezt végzi a program listájában az ismétlő eljárás.
Továbbá azt kell még tudni, hogy két szám legnagyobb közös osztójának és
legkisebb közös többszörösének a szorzata nem más, mint a két szám szorzata. Így
a legkisebb közös többszörös osztással meghatározható. A listában szerepel még
egy új deklaráció: a LongInt, vagy magyarul hosszú egész, melynek értéke kb -2
milliárdtól + 2 milliárdig terjedhet. Íme a lista:
Program Lnko; {Nyomkövetéssel futtatni!}
Uses NewDelay,
Crt, CrtPlus;
Var A,B,M: LongInt;
S: LongInt;
Begin
TextMode(CO80);
ClrScr;
WriteXY(28,1,'A legnagyobb közös osztó');
WriteXY(1,3,'Kérem az első egész számot: ');
ReadLn(A);
WriteXY(1,4,'Kérem a második egész számot:
');
ReadLn(B);
S:= A*B;
If
S=0 Then Halt;
Repeat
M:= A Mod
B;
A:= B;
B:= M;
Until
M=0;
WriteXY(1,6,'A legnagyobb közös osztó: ');
Write(A);
WriteXY(1,8,'A legkisebb közös többszörös:
');
Write(Round(S/A));
Tunj;
Varj;
End.
19.) Írj
programot, amely 0-99 intervallumban kiválogatja a prímszámokat, illetve
tetszőleges számról megállapítja, hogy prim-e.
A feladat első részét
Eratosztenész szitája segítségével oldjuk meg. Azaz: a 0-99 számból húzzuk ki a
0-t és 1-et, mert ezek nem prímszámok. Az első ki nem húzott szám a 2, ezért
húzzuk ki minden másodikat (kivéve magát a 2-t) egészen 99-ig, a következő ki
nem húzott szám a 3, ezért húzzuk ki minden 3. számot, a következő ki nem
húzott az 5 lesz, és így tovább. Az utolsó szám, amivel szitálni kell a 7 lesz.
Általánosan leírva a szitálást a szám négyzetgyökéig kell végezni. Ennek az az
oka, hogy minden összetett számnak létezik a négyzetgyökénél nem nagyobb prímosztója.
Ha tehát egy szám a négyzetgyökéig való szitálásig nem esett ki, akkor az már
nem is fog.
Ezek
után a program listája:
Program Primszam;
Uses NewDelay,
Crt, CrtPlus;
Var I,J: Integer;
Szam: LongInt;
Pr: Array[0..99]
Of Boolean;
Procedure Tabla;
Begin
TextMode(CO80);
Szinek(0,15);
ClrScr;
WriteXY(29,1,'Eratosztenész szitája');
Racs(15,2,4,1,10,10);
For I:= 0 To
99 Do
Begin
GoToXY((I Mod 10)*5+17,(I Div
10)*2+3);
Write(I:2);
End;
End;
Procedure Szitalas;
Var P: Integer;
Procedure
Kikap(K: Byte);
Begin
GoToXY((K Mod 10)*5+17,(K Div
10)*2+3);
Write(K:2);
End;
Begin
For
I:= 0 To 99 Do Pr[I]:= True;
Szinek(0,7);
Pr[0]:= False;
Kikap(0);
Delay(100);
Pr[1]:= False;
Kikap(1);
Delay(100);
P:=0;
While
P<10 Do
Begin
Repeat
Inc(P);
Until
Pr[P];
If
P>10 Then Exit;
I:= P;
While
I<100-P Do
Begin
Inc(I,P);
Pr[I]:= False;
Kikap(I);
Delay(100);
End;
End;
End;
Procedure Prime;
Var P: Integer;
Igen: Boolean;
Begin
WriteXY(1,24,'Mely számról akarod tudni, hogy
prim-e? ');
ReadLn(Szam);
I:= 1;
Igen:= True;
Repeat
Inc(I);
If
(Szam Mod I)=0 Then Igen:= False;
Until
(I>Sqrt(Szam)) Or Not Igen;
If
Szam=1 Then Igen:= False;
If
Szam=2 Then Igen:= True;
If
Igen Then WriteXY(55,24,'Igen') Else
Begin
WriteXY(55,24,'Nem,');
If
Szam<>1 Then Write(' Osztja: ',I);
End;
Tunj;
Varj;
End;
Begin
Tabla;
Szitalas;
Prime;
End.
A programnak 3 fő
funkciója van: a tábla felrajzolása, a szitálás valamint egy tetszőleges szám
vizsgálata. A tábla felrajzolását végző Tabla eljárás már sok ismert dolgot
tartalmaz, ezért nem elemezzük. A szitálás eljárásban van egy újdonság, az
eljárásfejben újabb eljárást deklaráltunk, a kikap (K: Byte); eljárást, vagyis
egy eljárásnak lehetnek további saját eljárásai. Ez az eljárás a 15-ös kódú
fehér színről 7-re állítja az írás színét, azaz halványabban írja ki a K
számot. A szitálás alapját a 0-99 indexű logikai tömb adja. A bekapcsolt
állapotnak felel meg a True érték, amely azt mondja, hogy a szám prímszám.
Először minden érték True, csak az eljárás során alakul ki a helyes érték. A
folyamatot Delay(100) lassítja, így nyomon követhető a szitálás. Először a nem
automatizálható 0-t és 1-t kapcsolja ki. Majd a While, elől-tesztelő ciklus végzi a szitálást, mindaddig, amíg P<10.
Először megkeresi a következő prímszámot. Ha ez véletlenül1 túllépett 10-en,
akkor Exit eljárással kilép a Szitalas
eljárásból (az Exit a Halt-hoz hasonló, csak itt az
eljárásból lép ki a gép, a Halt-nál
pedig a programból). Aztán a megtalált prímszámmal, ismét egy While ciklus segítségével, kikapcsolja
a nem prímszámokat. A lépegetést az Inc eljárás eddig nem ismertetett
formájával oldja meg: a második paraméter a növelés mértékét adja, tehát ennek
hiányában egyesével számolna, itt viszont az I-t mindig P-vel növeli. Az
eljárás végén erősen írva maradnak a prímszámok, a nem prímszámok halványan
láthatók a táblázatban.
A Prime eljárás
egyszerűen végignézi (de legfeljebb csak a szám négyzetgyökéig), hogy létezik-e
olyan szám, mellyel a számot osztva maradékul 0-t kapunk (Mod). Az igen True értéke a szám prímszám mivoltát jelzi. Ezért a
leállító Not igen értéke. Az eljárás
a szám legkisebb prímosztóját is meghatározza, hiszen az a nem 1 de legkisebb
szám, ami osztja, biztosan prím (természetesen összetett számnál).