Egy matematika érettségi feladat megoldása programozással 2023

érettségi logó

érettségi logó

A 2023-as középszintű matematika érettségi feladatsorból az 5. feladat alkalmasnak bizonyult arra, hogy a programozás eszköztárával oldjuk meg. Rögtön többféleképpen is, hogy összehasonlíthatóak legyenek egymással. Érdekes belegondolni, hogy mennyire más lehetne a problémamegoldás, ha programozhatnánk a matematika érettségi vizsgán. A teljes feladatsor letölthető az oktatas.hu-ról.

5. feladat

Adja meg a 420 és az 504 legnagyobb közös osztóját! Megoldását részletezze!

Íme kulcsszavakban, mit érdemes átgondolni a megoldás előtt: számelmélet alaptétele, prímfelbontás (prímtényezős felbontás, faktorizáció), osztópár, prímek szorzata, prímtényezők szorzata, kanonikus alak, euklideszi algoritmus.

1. megoldás

Az első megoldás az euklideszi algoritmus alkalmazása. A metódus paraméterezhető. Pozitív paramétereket vár és képes kiírni a konzolra a két szám legnagyobb közös osztóját. A módszer alapötlete: a legnagyobb közös osztó nem változik, ha a nagyobb számot a két szám különbségével helyettesítjük. Ezzel csökken a nagyobb szám, így a cserék ismétlésével egyre kisebb számokat kapunk, amíg a két szám egyenlővé nem válik. Ez az eddigi számpároknak, így az eredeti számpárnak is a legnagyobb közös osztója. Az eredményt az utolsó nem nulla maradék while(m!=0) adja meg int lnko=b;. Az algoritmus lépésszáma csökkenthető, ha a>b, de ennek ellenőrzése nélkül is működik. Mivel a feladat kéri a megoldás részletezését, így aktiválva a megjegyzésbe tett forráskódokat, a kiírásból könnyen érthető, mi és hogyan történik:

A konkrét esetben a metódus eredménye: lnko (420; 504) = 84. Nagyobb számok esetében „beszédesebb” a program kiírása, több lépésben írja ki a megoldáshoz vezető utat, ezért érdemes többféle paraméterrel is tesztelni a metódust.

2. megoldás

A második megoldás a prímtényezős felbontásokon alapul. Mindkét szám esetén gyűjtsük össze listában ezeket, majd vegyük a két lista közös részét. (Ha lista helyett halmazok lennének, akkor metszet programozási tétel lenne.) A generikus listákba prímszámok kerülnek és bármelyik többször is előfordulhat. (Ezért most a leghosszabb közös részsorozat(ok) előállítása szükséges.) Addig osztjuk a számot 2-vel, amíg lehet, utána következik a többi prímosztó, amíg vannak. Érdemes több metódusra szétosztani a megoldást, mert jóval áttekinthetőbb és karbantarthatóbb Java forráskódot eredményez. A beszédes változó, objektum és metódusnevek is segítenek a megértésben. A második megoldás természetesen ugyanazt az eredményt adja, mint az első megoldás. Aktiválva a megjegyzésbe tett forráskódokat, a kiírásból most is könnyen érthetővé válik (középiskolás matematikaóra-szerűen), mi és hogyan történik:

Kanonikus alakban: 420 = 22 * 3 * 5 * 7, 504 = 23 * 32 * 7, így lnko (420; 504) = 22 * 3 * 7. Azaz összeszorozzuk a közös prímtényezőket az előforduló legkisebb hatványon.
A megoldás erősen épít a generikus kollekciók esetén jól használható Stream API lambda kifejezéseire. Ezeket most nem részletezem, helyette ajánlom a szakmai blogból a lambda kifejezés címkét.

Érdemes átgondolni

  • Nagy prímszámok esetén az euklideszi algoritmus nem hatékony. Az algoritmus végrehajtása kifejezetten lassú például a Fibonacci-számok esetén. A prímtényezőkre bontás feltételezett bonyolultságát számos kriptográfiai algoritmus használja ki. Vannak különleges esetek is, például: egyforma számok, az egyik szám 1, a két szám egymás többszöröse.
  • A feladat nem kérte a legkisebb közös többszörös meghatározását, de ha tudjuk a lnko(a, b)-t, akkor abból könnyen adódik a lkkt(a, b)=a*b/lnko(a, b).
  • A legnagyobb közös osztó tulajdonságait megismerve az euklideszi algoritmus könnyen optimalizálható. Számos esetben ellenőrzést végezhetünk, illetve triviális alapesetek is vannak. Létezik kiterjesztett euklideszi algoritmus is.

A bejegyzéshez tartozó teljes forráskódot ILIAS e-learning tananyagban tesszük elérhetővé tanfolyamaink résztvevői számára.

Ajánljuk matematika érettségi feladat címkénket, mert a témában évről-évre blogolunk.

A feladat a Java SE szoftverfejlesztő tanfolyam szakmai moduljának 5-8. óra: Vezérlési szerkezetek, 9-12. óra: Metódusok, rekurzió, valamint 17-28. óra: Objektumorientált programozás alkalmaihoz kötődik.

Sankey-diagram készítése

A Sankey-diagram alkalmas kétféle adatsor közötti N:M fokszámú kapcsolat, összefüggés és a köztes átmenet ábrázolására. Hangsúlyozza a fő átvitelt vagy áramlatokat egy rendszeren belül. Az áramlás irányát nyíllal szemlélteti és az áramlatok szélessége arányos az áramlási mennyiségekkel.

Feladat

Jelenítsük meg HTML formátumú weboldalként a magyarországi régiókban a foglalkoztatottak számát nemzetgazdasági szektorok szerint a KSH 2018-as adatsora alapján! Automatizáljuk egy Java programmal úgy a feladatot, hogy az év paraméterként megadható legyen!

Tervezés

A KSH témastruktúrában a táblázat elérési útja:

  • 5. Területi adatok,
  • 5.1. A munkaerő-piaci tendenciák Magyarország régióiban,
  • 5.1.3. A foglalkoztatottak száma nemzetgazdasági szektorok szerint, nemenként (2008–)

Online böngészhető táblázat:
https://www.ksh.hu/docs/hun/xstadat/xstadat_hosszu/h_qlf017.html

Letölthető táblázat (XLS formátumban):
https://www.ksh.hu/docs/hun/xstadat/xstadat_hosszu/xls/h5_1_3.xls

A táblázatban lévő adatforrás szükséges része látható az ábrán:

KSH adatforrás Sankey-diagramhoz

A táblázatban a régiók az A105:A112 cellatartományban találhatók. A hozzájuk tartozó 3 nemzetgazdasági szektor a B-C-D oszlopok azonos soraiból olvashatók ki. POJO-k létrehozása mindenképpen hasznos a megvalósításhoz, például new SankeyData("Közép-Dunántúl", "Szolgáltatás", 253.89). Ezekből generikus listát is célszerű építeni: List<SankeyData> sankeyDataList.

Többféleképpen is hozzájuthatunk az adatokhoz attól függően, hogy milyen előismeretekkel rendelkezünk a különböző tanfolyamainkon:

  • A Java SE szoftverfejlesztő tanfolyamon „kézzel” letölthetjük a projekt files mappájába az XLS fájlt. Ezután akár manuálisan is összeállítható a POJO lista, vagy a JExcel API-val is hatékonyan feldolgozható a XLS fájl aktuális munkalapja. Fájlkezelés előtt az összeállított HTML fájlt kiírathatjuk a konzolra, ahonnan „kézzel” vágólapozva létrehozhatjuk belőle a szükséges HTML fájlt. Fájlkezeléssel persze adott mappába, adott fájlnévvel, kivételkezeléssel a java.io vagy java.nio csomagot használva a HTML fájl generálása is automatizálható.
  • A Java EE szoftverfejlesztő tanfolyamon megvalósítható, hogy a program kivételkezeléssel hálózati kapcsolatot épít, majd letölti az XLS fájlt és ezzel a feladat visszavezethető az előző esetekre. Azt is megtehetjük, hogy az XLS fájlt nem töltjük le, hanem olvasunk belőle közvetlenül a webről. Ekkor is rendelkezésünkre áll a POJO lista. Itt már tudunk HTML fájlt is automatikusan generálni.

Tanulmányoznunk kell a Google Charts galériában a Sankey diagram dokumentációját! Meg kell ismernünk a paraméterezési lehetőségeit és JavaScript forráskódját!

Megvalósítás

A createSankeyDiagram() függvény létrehozza a HTML fájl szöveges tartalmát. Átveszi adatforrásként a sankeyDataList generikus POJO listát. A String típusú sankeyData objektum tartalmazza a Stream API-val hatékonyan összefűzött – POJO-któl elkért – toString() szövegeket. Ezek a diagramhoz szükséges adatok ( addRows …). Például: "['Közép-Dunántúl', 'Szolgáltatás', 253.89]". A  String típusú  html objektum kezdetben tartalmazza a diagramhoz nem szükséges fix részeket, a diagram alapbeállításait, valamint a diagram fejlécéhez szükséges metaadatokat ( addColumnRégió, Nemzetgazdasági szektor, Foglalkoztatottak száma (ezer fő)). A függvény végül a html objektum #SankeyData# részét cseréli a sankeyData-val és az adatfüggő résszel frissített HTML tartalommal tér vissza.

Eredmény

Az egyik eredmény a generált HTML fájl (benne a grafikonhoz tartozó JavaScript) forráskódját tartalmazza:

A másik eredmény a Sankey-diagram képernyőképe, amelyről kiválóan leolvashatók az értékek:

Sankey-diagram

A böngészőben megjelenő HTML oldalon a Sankey-diagram dinamikusan – az egérkurzor pozíciójától függően – képes az aktuális adatok megjelenítésére, mintegy lebegő jelmagyarázatként.

A bejegyzéshez tartozó teljes forráskódot ILIAS e-learning tananyagban tesszük elérhetővé tanfolyamaink résztvevői számára.

Naprendszer szimuláció – megvalósítás Java nyelven

Naprendszer szimulációt terveztünk és valósítottunk meg Java nyelven, amit három részből álló blog bejegyzés sorozatban mutatunk be (ez a 3. rész):

A Naprendszer szimuláció megvalósítása Java nyelven

Fejlesztőeszközként a Java Swinges projekthez a JDK+JRE aktuális verziót támogató NetBeans IDE-t használtuk. Hibakeresés során, a modell adatainak ellenőrzését és a működés helyességének egyszerű tesztelését, debuggolást konzolra történő szöveges kiírással oldottuk meg. A megvalósítás során az előre megtervezett osztálydiagramok alapján készült el Java nyelven a forráskód. Az MVC modell szerint elkülönített programrészek külön csomagokba kerültek, ezzel is kiemelve a funkciók szerinti szétválasztást – eleget téve a terv követelményeinek.

Részlet a Java forráskódból

Megmutatjuk a Java forráskódnak azt a részét, ami megvalósítja az elméleti háttérnél ismertetett transzformációs mátrix alkalmazását X tengely körüli elforgatásra, a nézőponttól való távolság függvényében az égitest látható méretének kiszámítását, valamint a 3D→2D leképezést.

A teljes és megjegyzésekkel ellátott forráskód ILIAS e-learning tananyagban hozzáférhető, letölthető, tesztelhető tanfolyamaink résztvevői számára.

Az elkészült Java Swinges alkalmazás felhasználói felülete

Tapasztalatok

  • A Java nyelv erősen típusos, így a kötelező és sok lebegőpontos/egész átalakítás miatt észrevehető, hogy a legkisebb égitest (Hold) kissé ugrál.
  • Az OO szempontból szép Java megvalósítás könnyen módosítható és bővíthető, a funkciók jól csoportosítottak, a felelősségi kör egyértelműen meghatározott.
  • A projekt megtervezéséhez és elkészítéséhez magasabb szintű absztrakciós készség szükséges.
  • A példaprogram alkalmas a különböző szakterületek, témakörök (matematika – lineáris algebra, fizika, számítógépes grafika, virtuális valóság modellezése) közötti kapcsolatok felismertetésére, megerősítésére, a (legalább részben) egymásra épülések felderítésére.
  • A ter­v átgondolásával, implementálásával gyors, látványos eredmény érhető el, a sikerélmény hamar jelentkezik.

Továbbfejlesztési lehetőségek

  • Célszerű ötlet a hardveres gyorsítás és 3D megjelenítés megvalósítása.
  • Felkínálható lenne a felhasználó számára több paraméter módosítása.
  • Az égitestek lehetnének textúrázhatók is.
  • Az égitestek pozíciója kiinduló helyzetben lehetne valós.
  • A szimuláció szükség esetén lehetne elindítható, leállítható, újraindítható, gyorsítható, lassítható.
  • A terv könnyen implementálható lehet Java3D techno­lógia alkalmazásával, illetve DirectX és/vagy OpenGL támogatással is.
  • Az égitestek pozíciója és mozgása demonstrálhatna/modellezhetne nevezetes együttállást is, külön esettanulmányként.
  • A program paraméterezhető lehetne konfigurációs fájlból (amelynek formátuma tetszőleges: INI, XML).
  • Fejlettebb matematikai modell is alkalmazható lenne.

Forrás

  • Friedel, A.; Kaczur, S. (előadó: Friedel, A.): Naprendszer szimuláció a Virtuális valóság modellezése tantárgyban, Informatika Korszerű Technikái Konferencia, Dunaújváros, Dunaújvárosi Főiskola, 2012. november 16-17. (előadás hazai konferencián)
  • Friedel, A.; Kaczur, S.: Naprendszer szimuláció a Virtuális valóság modellezése tantárgyban, Cserny, L.; Hadaricsné Dudás, N.; Nagy, B. (szerk): Dunakavics Könyvek 2. – Az Informatika Korszerű Technikái, Dunaújvárosi Főiskola, Új Mandátum Könyvkiadó, 2014, ISBN 978 963 287 069 4, ISSN 2064-3837, p. 72-84 (magyar nyelvű szakcikk)

Naprendszer szimuláció – objektumorientált tervezés

Naprendszer szimulációt terveztünk és valósítottunk meg Java nyelven, amit három részből álló blog bejegyzés sorozatban mutatunk be (ez a 2. rész):

A Naprendszer szimuláció objektumorientált tervezése

A Naprendszer égitestjeinek ábrázolása a valódi világban előforduló méretük és távolságuk szerint történik azért, hogy a szimuláció stabil legyen. A példában a Nap és a három belső bolygó szerepel, valamint a Hold. Utóbbi igazolja, hogy nem csak Nap középpontú égitestekre működőképes a modell. A szimuláció diszkrét lépések véges sorozataként valósul meg, az egyes lépések között az égitestek a virtuális térben egyenes vonalú egyenletes mozgást végeznek. Olyan lépésközt kell választani, amely rövid idő alatt kellően nagy változást képes bemutatni, ilyen például az 1 számítási ciklus / 1 nap érték. 10 képkocka / másodperces megjelenítést feltételezve – melyet egy időzítő biztosít – egy virtuális év kb. 37 másodperc alatt telik el, vagyis a Föld ennyi idő alatt tesz meg egy teljes fordulatot a Nap körül. Az égitestek kezdő pozíciója fiktív, nem függ konkrét dátumtól, együttállástól, méretük a jobb láthatóság érdekében torzított.

A program indításakor a szimuláció automatikusan indul, és nincs lehetőség a leállításra. Az alkalmazás felületének tetején foglalnak helyet a kezelő nyomógombok, a többi részt a megjelenítés/transzformált modelltér tölti ki. Futás közben – egyszerű ese­mény­ke­zelést megvalósítva – lehet változtatni a méretarányt és a nézőpontot, így az ekliptika síkját felülről és elbillentve is ábrázolhatjuk.

Kivételkezelés nem szükséges a programhoz, mert ez egy önálló demonstrációs eszköz, nem épül rá több elem, nem érhetőek el a szolgáltatásai külső programok számára.

Meghatározott cél és a szempontok: a Java projektben a csomagokat az MVC szerint hozzuk létre, a funkciókat logikusan osszuk szét, csoportosítsuk, tartsuk be az objektumorientált szemléletmód elveit, használjunk interfészt, biztosítsuk az egység­bezárást, legyen öröklődés, alkalmazzuk a polimorfizmust, legyen szép és elegáns megoldás, legyen a jelölésrendszer UML osztálydiagram. Mindez grafikus asztali Java alkalmazásként valósuljon meg.

A modell csomag (M – Model)

A modellhez 1 interfész és 5 osztály tartozik:


Az AdatInterfesz tárolja a modell számításhoz és megjelenítéshez tartozó konstansait (ezek a szimuláció paraméterei), és metódusfejet nem tartalmaz. A Pont2D osztály egy kétdimenziós pont sémája, valós x és y koordinátapárral, eltol() és túlterhelt tavolsag() metódusokkal. Ennek leszármazottja a Pont3D osztály, amely mindezt három dimenzióban biztosítja, valamint pozícióként és sebességvektorként is használható. Az Egitest osztályból létrehozott objektumnak van mérete, pozíciója, sebessége, színe és tömege. Az interfészt implementálja az Adattar osztály, amelynek egitestLista nevű generikus listája elérhetővé és egységesen kezel­hetővé teszi a tervben felsorolt 5 égitestet. A ZIndex osztályú objektumok az égitestek kirajzolásakor szükséges mélységpufferbeli adatot képesek kezelni.

A nézet csomag (V – View)

A nézet 2 osztályból áll:


Az Ablak osztály egy javax.swing.JFrame le­szár­mazott, az alkalmazás teljes grafikus felületét biztosítja, valamint előkészíti az eseménykezelést. Tartalompanelje négy vezérlő nyomógombot tartalmaz és rajta található a rajzpanel objektum, a vaszon. A RajzPanel osztály egy javax.swing.JPanel leszármazott, amely kapcsolatban áll az adattárral, és kezeli a mélységpuffert. Ez felel a szimulált 3D térben lévő objektumok 2D-beli leképezéséért, figyelembe véve a nézőpont elmozdulását is. A rajzolást a felüldefiniált (öröklődés) paintComponent() metódus végzi el.

Az Ablak osztályú objektum elsődleges szerepet tölt be a megjelenítésben, keretbe foglalva a látható komponenseket, vagyis a kezelő nyomógombokat és a modellteret. Az objektum megvalósít egy ActionListener eseménykezelőt, így a program reagálni tud a felhasználó által kiváltott eseményekre. Az ablakobjektum nagyítás és forgatás üzenetek küldésével saját vásznát – és csak azt – frissíti.

A vezérlő csomag (C – Controller)

A vezérlőt 2 osztály valósítja meg:

A Main osztály összefogja a projektet, ez a végrehajtás belépési pontja. Szükség szerint átadja az MVC szerinti objektumok referenciáit egymásnak, ezzel biztosítva a kommunikációt közöttük, valamint el is indítja a szimulációt. A Logika osztály képes az égitestek gyorsulásának és vonzásának kiszámítására, az égitestek mozgatására, továbbá a megjelenítésért felelős komponenst megfelelő időközönként értesíti a képernyő frissítésének szükségességéről, ami az alapbeállítás szerint 30 frissítés másod­percenként.

Kockadobás kliens-szerver alkalmazás

Fejlesszünk elosztott, hálózatos, datagram alapú üzenetküldéssel megvalósított Java alkalmazást!

A kockadobás kliens egyszerre két szabályos dobókockával dob, amit ezerszer megismétel és a dobott számok összegét datagram típusú üzenetküldéssel folyamatosan elküldi a szervernek. A szerver localhost-on fut és egy megadott porton keresztül várja a klienstől. A szerver és a kliens egyaránt szálkezelést alkalmazó konzolos alkalmazás.

A projektben van egy swing GUI-s alkalmazás, amely JFreeChart oszlopdiagramon – folyamatosan frissítve – megjeleníti az összesített adatokat, mindez a szerver üzenetküldésével irányítva (amint beérkezik egy dobott (2-12-ig) összeg).

A kommunikációnak – a lehetőségekhez képes – biztonságosnak és – a hálózati adatforgalmat tekintve – takarékosnak kell lennie! Ennek részeként szükséges egy azonosító és egy egyszerű szabály (protokoll).

Tekintsük át mondatszerűen a szálkezelést használó kliens és szerver kommunikációhoz kötődő feladatait:

Ezek működését összefogja egy központi vezérlőosztály és ez a fejlesztőeszköz projektablakában így jelenik meg (egyetlen MVC Java projektként):

A program két felületen kommunikál. A háttérben konzolosan logol a kliens, és a háttérben futó szerver időnként frissítteti a grafikus felhasználói felületen (GUI, ablak) megjelenő grafikont:

Kockadobás - Java kliens-szerver alkalmazás működésa

Aki kedvet kapott: bátran készítse el a fenti terv/koncepció/specifikáció alapján az MVC Java projektet. Érdemes alaposan tesztelni: külön a szervert, külön a klienst, először indítva az egyiket, majd a másikat, leállítani az egyiket majd fordítva. Átgondoltan indokolni is hasznos, vajon mi, hogyan és miért történik.

A bejegyzéshez tartozó forráskódot ILIAS e-learning tananyagban tesszük elérhetővé tanfolyamaink résztvevői számára.

A feladat a Java EE szoftverfejlesztő tanfolyam 1-8. óra: Elosztott alkalmazások, webszolgáltatások, szálkezelés, párhuzamosság alkalmához kapcsolódik. Amikor itt járunk a tananyagban, akkor a GUI felület és a grafikon tervezése, megvalósítása már magabiztosan megy, így elegendő a hálózati kommunikációra helyezni a fókuszt.