Lottó programozás feladat – 2005. május

Feladat leírás


Magyarországon 1957 óta lehet ötös lottót játszani. A játék lényege a következő: a lottószelvényeken 90 szám közül 5 számot kell a fogadónak megjelölnie. Ha ezek közül 2 vagy annál több megegyezik a kisorsolt számokkal, akkor nyer. Az évek során egyre többen hódoltak ennek a szerencsejátéknak és a nyeremények is egyre nőttek. Adottak a lottosz.dat szöveges állományban a 2003. év 51 hetének ötös lottó számai. Az első sorában az első héten húzott számok vannak, szóközzel elválasztva, a második sorban a második hét lottószámai vannak stb.

Például:
 37 42 44 61 62
 18 42 54 83 89
 ...
 9 20 21 59 68

A lottószámok minden sorban emelkedő számsorrendben szerepelnek.

Megoldások:

  1. feladat
  2. feladat
  3. feladat
  4. feladat
  5. feladat
  6. feladat
  7. feladat
  8. feladat
  9. feladat
  10. Az összes megoldás: Lottó feladat állományai

1. feladat

Kérje be a felhasználótól az 52. hét megadott lottószámait!

Az állományból kimaradtak az 52. hét lottószámai. Ezek a következők voltak: 89 24 34 11 64.

Elméleti megoldás

A feladat 5 db egész szám beolvasását kéri a billentyűzetről, amelyet egy tömbben (Listában) a legegyszerűbb tárolni.

számok = []   #Üres lista létrehozása
Ciklus i=1-től 5-ig   #Számlálós ciklus, a ciklus változó i értékei rendre 1,2,3,4,5
   szamok[i] = adatBekérés() #A lista i. elemét beolvasom a billentyűzetről
Ciklus vége

Megoldás python nyelven

print("1. feladat")
print("Kérem az 52. heti LOTTÓ számokat!")
szamok =[]
for i in range(0,5):
    szamok.append(int(input("%d. kihúzott szám: "%(i+1))))

2. feladat

A program rendezze a bekért lottószámokat emelkedő sorrendbe! A rendezett számokat írja ki a képernyőre!

print("2. feladat - Rendezett lista")
szamok.sort() 
print(", ".join([str(i) for i in szamok]))

3. feladat

Kérjen be a felhasználótól egy egész számot 1-51 között! A bekért adatot nem kell ellenőrizni!

print("3. feladat")
het = int(input("Hányadik hét számaira kíváncsi (1-51)? "))

4. feladat

Írja ki a képernyőre a bekért számnak megfelelő sorszámú hét lottószámait, a lottosz állományban lévő adatok alapján! (csomagold ki a lotto.zip állományt)

Adatforrás megnyitása

with open('lottosz.dat','r',encoding='utf-8') as lottoFile:

A felhasznált utasítások:
with -> Ez egy olyan utasítás, amely abban segít, hogy ne a programozónak keljen a fájl lezárásával törődni-e.
open(‘útvonal\állomány.név’,’adatáramlás iránya’, [encoding=”])
‘útvonal\állomány.név’ –> az állomány, amelyte meg kívánunk nyitni
‘adatáramlás iránya’ –> ‘r’ – olvasásra, ‘w’ – írásra (mindíg új állomány jön létre), ‘a’ – hozzáfűzés (létező állomány végére)

Adatok beolvasása listába

print("4. feladat")
osszesHet=[]
with open('lottosz.dat','r',encoding='utf-8') as lottoFile:
    for egySor in lottoFile:
        osszesHet.append(list(map(int, egySor.strip().split(' '))))

A felhasznált utasítások:
Az osszesHet egy üres lista, ebben fogjuk tárolni a beolvasott lottószámokat.
A lottoFile egy logikai leképezése a lottosz.dat fizikai állománynak. Az with open() as parancssor hozza létre ez az adatfolyamnak is nevezett objektumot.
A for in vezérlőszerkezet bejárja a lottoFile  adatfolyamot (szekvenciális) az elejétől a végéig. A kiolvasott sort elhelyezi az egySor szövegváltozóba (string)
strip() –> levágja a sortörés (‘/n’) karaktert a szövegváltozó (string) végéről
split(‘ ‘) –> a szóközök mentén szétvágja a szöveg változót (string) és elhelyezi egy listában
map(int, egysor.strip().split(‘ ‘)) –> a feldarabolt, most már listaként létező lottószámokat, amelyek még stringek, átalakítjuk (konvertáljuk) egészszámmá (int).
list(map(..))–>a map típusú objektumot listává alakítja.
osszesHet.append() –> elhelyezi a feldarabolt lottószámok listáját (egy hét számai) az osszesHet listában

A bekért hét nyerőszámainak kiírása

het = int(input('Melyik hét számaira kíváncsi? '))-1
print(", ".join('{: >2}'.format(str(e)) for e in osszesHet[het]))

A felhasznált utasítások:
Az utolsó sor, miután bekértünk egy egész számot a felhasználótól (a kért hét sorszámát) a kiírja a számokat vesszővel elválasztva, pontosan két karakter hosszan.
for in bejárja az adott hét listáját.
az egyes számok az e változóba kerülnek.
az str(e) átalakítja szövegváltozóvá, a számot.
format() a megadott megjelenésűvé alakítja ‘{: >2}’. A kettős pont után egy szóköz van. Ha a kiírt szám csak egyjegyű, akkor 2 karakterre egészíti ki szóközzel.
join() pedig a számokat hozzáfűzi a a “, ”  stringhez.

Ez lesz a kiírás eredménye:
18,  2, 54, 83, 89

5. feladat

A lottosz.dat állományból beolvasott adatok alapján döntse el, hogy volt-e olyan szám, amit egyszer sem húztak ki az 51 hét alatt! A döntés eredményét (Van/Nincs) írja ki a képernyőre!

Gondolatok a megoldáshoz

1. gondolat

Az gondoltam, hogy az egyik megoldás az lehetne, ha összegyűjteném az összes előforduló számot az osszesHet listában, és ha az összegyűjtött számok száma 90 darab, akkor mindegyiket kihúzták, ha kevesebb, akkor van olyan, amelyiket nem húztak ki.

Előnye, hogy a megoldás viszonylag egyszerű, mert megyek végig az összes kihúzott számon és egy listába pakolom azokat a számokat, amelyek még nem szerepelnek benne. A végén a lista hosszát vizsgálom.

Hátránya végig kell mennem az összes kihúzott számon ráadásul a végén nem tudom meg, hogy melyiket nem húzták ki, csak azt hogy van olyan.

Vizsgálatok száma: 5 * 52 = 160 és állandó.

2. gondolat

A másik megoldás, ami szóba jöhet, hogy a végig megyek a kihúzható számokon és megnézem, hogy kihúzták-e.

Ez a bonyolultabb megoldás, hiszen itt 3 ciklust kell kezelnem. Megy végig a lehetséges számokon (1..90) és megnézem, hogy kihúzták-e. Ha nem, akkor megtalálta, ha igen fogom a következő számot és azt vizsgálom.

Előnye, lehet, hogy már nagyon hamar meg lesz az, amit nem húztak ki és tudom is, hogy melyik szám az.

Hátrány a megoldás komplexebb és lehet, hogy hosszabb is a végrehajtási ideje, hiszen, ha mindet kihúzták, akkor 90-szer vizsgálom meg a listát, ha nem is megyek végig rajta.

Vizsgálatok száma: minimum: <52, maximum: 90*52*5 = 23 400

Ezek szerint az 1. gondolat a jó gondolat. Valósítsuk meg azt.

Az 1. gondolat megoldása

print('5. feladat')
vanLista = []                   # üres lista  
for egySor in osszesHet:        # Bejárom a heteket
   for szam in egySor:          # Bejárom a hét számait
      if szam not in vanLista:  # ha a szám nincs benne a listában beleteszem
          vanLista.append(szam)
if len(vanLista) == 90:         # Ha a listában 90 érték van, akkor mindet kihúzták 
    print("Nincs")
else:
    print("Van")

A 2. gondolat megoldása

2. elgondolás

6. feladat

A lottosz.dat állományban lévő adatok alapján állapítsa meg, hogy hányszor volt páratlan szám a kihúzott lottószámok között! Az eredményt a képernyőre írja ki!

Az elgondolás

Végig nézem az összes hetet és a heteken belül a számokat, ha kihúzott szám 2-es maradéka (modulus) egyenlő 1-el akkor növelek egyet egy változó értékén.

páratlanok = 0
Ciklus 1 héttől osszesHet hosszáig
   Ciklus 1 számtól a hét utolsó számáig
      Ha szám osztási maradéka = 1 akkor
            páratlanok = páratlanok + 1

A megoldás

Ez egy megszámlálás tétel alkalmazása!

print('6. feladat')
paratlan = 0
for het in osszesHet:
    for szam in het:
        if szam % 2 == 1:
            paratlan += 1
print("A páratlankihúzott számok száma: %d"%paratlan)

7. feladat

Fűzze hozzá a lottosz.dat állományból beolvasott lottószámok után a felhasználótól bekért, és rendezett 52. hét lottószámait, majd írja ki az összes lottószámot a lotto52.ki szöveges fájlba! A fájlban egy sorba egy hét lottószámai kerüljenek, szóközzel elválasztva egymástól!

Az első elgondolás

Az egyszerű bár nem ezt várják az érettségi feladatok kigondolói, de el kell fogadniuk megoldás a következő:

import shutil #az shutil objektum osztály kezeli az állományokat ezért beimportálom
majd
shutil.copy(“lottosz.dat”, “lotto52.ki”) #Lemásolom az egész lottosz.dat állományt a lotto52.ki állományba
majd
open(‘lotto52.ki’,’a’, encoding=’utf-8′ as lottoFile) #megnyitom hozzáfűzésre az új állományt
majd
lottoFile.write(” “.join([str(e) for e in szamok])) #a régen (2. feladat) bekért szamok listát kiírom

Együtt pythonban

import shutil

...

print('7. feladat')
shutil.copy("lottosz.dat", "lotto52.ki")
with open('lotto52.ki','a',encoding='utf-8') as lottoFile:
    lottoFile.write('\n')
    lottoFile.write(" ".join([str(e) for e in szamok]))

Második elgondolás

2. Ha megnyitom írásra az új “lotto52.ki” állományt beleírom az osszesHet list tartalmát és még a szamok listát is!

3. Sőt, hivatalosan az osszesHet listához hozzáfűzhetném a számokat és akkor csak az osszesHet listát kellene kiírnom az új állományba.
Ám ez azért veszélyes, mert akkor a következő feladatot esetleg egy “általam” (értsd: felhasználó) bővített listával kellene megoldanom, ami veszélyes, mert sehol nem ellenőriztem a bekért adatokat.

Egyébként ez lesz a legjobb megoldás, mert a nyolcadik feladat mind az 52 hét adataival akar majd dolgoztatni.

Tehát a 2. verziót fogom megoldani

print('7. feladat')
with open('lotto52.ki','w',encoding='utf-8') as lottoFile:
    for het in osszesHet:
        lottoFile.write(" ".join([str(e) for e in het]))
        lottoFile.write('\n')
    lottoFile.write(" ".join([str(e) for e in szamok]))

Vagy a 3. verzió megoldása

print('7. feladat')
osszesHet.append(szamok)
with open('lotto52.ki','w',encoding='utf-8') as lottoFile:
    for het in osszesHet:
        lottoFile.write(" ".join([str(e) for e in het]))
        lottoFile.write('\n')

8. feladat

Határozza meg a lotto52.ki állomány adatai alapján, hogy az egyes számokat hányszor húzták ki 2003-ban. Az eredményt írja ki a képernyőre a következő formában: az első sor első eleme az a szám legyen ahányszor az egyest kihúzták! Az első sor második eleme az az érték legyen, ahányszor a kettes számot kihúzták stb.! (Annyit biztosan tudunk az értékekről, hogy mindegyikük egyjegyű.)

Példa egy lehetséges eredmény elrendezésére (6 sorban, soronként 15 érték).

szamsor

Az elgondolás

Végig megyek az összes kihúzott számon és fogok egy listát és azon indexű elemeinek értékét növelem, amelyik egyenlő egy kihúzott számmal.

újlista feltöltve 0-kal
Ciklus 1 héttől összeshétig
  Ciklus  1 számtól a hétszámáig
       újlista[szám] = újlista[szám] + 1

Már csak a kiírással kell megbirkózni

Ciklus i=0-tól 5-ig
  Ciklus j=i*15 -től i*15+15-ig
       kiírni újLista[j]
  kiírni sortörés

A megoldás

print('8. feladat')
ujLista = [0 for i in range(0,90)]
for het in osszesHet:
    for szam in het:
        ujLista[szam-1] += 1

A kiírása

for i in range(0,6):
    print(" ".join([str(e) for e in ujLista[i*15:i*15+15]]))

9. feladat

Adja meg, hogy az 1-90 közötti prímszámokból melyiket nem húzták ki egyszer sem az elmúlt évben. A feladat megoldása során az itt megadott prímszámokat felhasználhatja vagy előállíthatja! (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89.)

Az előző feladatban minden egyes számról megtudtam hányszor fordult elő, csak végig kell mennem a lista azon  indexű elemein, amelyek prímszámok és megvizsgálni nulla-e a bennük tárolt érték.

primek = 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89
Ciklus egyprim a primek listában
   ha újLista[egyprim] = 0 akkor kiir "ezt nem húzták ki"

A megoldás

print('9. feladat')
primek = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89]
joPrim = []
for egyPrim in primek:
    if ujLista[egyPrim-1] == 0:
        joPrim.append(egyPrim)
print('A prímek, amelyeket nem húztak ki: ')
print(', '.join(str(e) for e in joPrim))

 

3 thoughts on “Lottó programozás feladat – 2005. május”

    1. Kedves Tamás! Sajnos a C++ nem tartozik az erősségeim közé, de biztos vagyok benne, ha a megfelelő szintaktikát vagyis az utasításokat egyezteted, a megoldások menete vagyis az algoritmus, ugyanúgy működni fog.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöljük.