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 ArrayOf 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 RepeatUntil 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 minden 15 értékre növekszik eggyel. Jegyezzük meg tehát, az X értéket a Mod, az Y értéket a Div segítségével állíthatjuk elő. A pontos értékek beállítását az adja, hogy i=1-re X=5-öt és Y=2-t kell kapni, valamint az X koordinátának 5-ösével, az Y-nak 2-esével kell változnia. (Első próbaként az X értékét (I Mod 15)*5, Y értékét (I Div 15)*2 képletekkel próbáljuk meg beállítani.)

 

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: CaseOfElseEnd; 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 CaseEnd;-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).