Érettségi feladat
Törtek
2012-05-14 - emelt szintű érettségi

Feladat leírás
A matematikában sokszor van szükségünk műveletvégzésre a közönséges törtekkel. A legtöbb számológép és számítógépes program csak a tizedes törteket ismeri. Készítsen programot, amely az alábbi – közönséges törtekkel kapcsolatos – feladatokat megoldja! A program forráskódját tort néven mentse! A feladatban csak pozitív számokkal kell dolgoznia, és ennek a tulajdonságnak a feldolgozandó fájlban található számadatok is megfelelnek. A felhasználótól bekérendő és a feldolgozandó fájlban található számokról feltételezheti, hogy legfeljebb kétjegyűek.

Példa:


Feladatok megoldásai:
1. feladat 2. feladat 3. feladat 4. feladat 5. feladat 6. feladat 7. feladat

1. feladat
Kérjen be a felhasználótól két számot, amely egy közönséges tört számlálója és nevezője! Döntse el, hogy az így bevitt tört felírható-e egész számként! Ha igen, írja ki értékét egész számként, ha nem, írja ki „Nem egész”!
print("1. feladat")
a = int(input("Kérem a tört számlálóját: "))
b = int(input("Kérem a tört nevezőjét: "))
if a % b == 0:
    print(int(a/b))
else:
    print("Nem egész")
A % operandus két szám maradékát adja eredményül - például: 4 % 2 = 0 vagy 11 % 3 = 2, mert 11 / 3 = 3 és a maradék 2. Az a/b eredménye valós szám típusú szám. Az int(a/b) egész szám típusúvá alakítja a hányadost.
A python // operandusa pedig képes az egész osztásra is. Vagyis a//b eredménye az egész rész, típusa egész (int).
  
2. feladat

A közönséges törteket úgy tudjuk a legegyszerűbb alakra hozni, ha a számlálóját és nevezőjét elosztjuk a két szám legnagyobb közös osztójával, és az így kapott érték lesz az új számláló, illetve nevező. Az egyszerűsítéshez készítsen egy rekurzív függvényt az alább leírt euklideszi algoritmusnak megfelelően!
Természetesen a Python tudja önállóan az LNKO előállítását is, de ezt most nem használhatjuk.
from fractions import gcd
print(gcd(32, 18))
A legszebb megoldás, de sajnos a feladat nem ezt kéri a következő:

def lnko(m, n):

    if n:
return lnko(n, m%n)
return m
print
(lnko(21, 33))
Ez az Euklideszi algoritmus python leírása.
Röviden ez történik:
Az euklideszi algoritmus két egész szám legnagyobb közös osztójának (lnko) meghatározására szolgál, maradékos osztások egymásutánjával. Először maradékosan elosztjuk az egyik számot a másikkal, majd az osztót a maradékkal, majd a második osztás osztóját a második osztás maradékával, és így tovább egészen addig, amíg a maradék 0 nem lesz.
A maradékos osztás maradékát visszaadó kifejezés jele a Python-ban a % jel, úgyhogy a példában szereplő számokkal az osztások láncolata: 21 % 33 = 21, 33 % 21 = 12, 21 % 12 = 9, 12 % 9 = 3, 9 % 3 = 0. (A hányadosokra jelen esetben nincs szükségünk.)
Az utolsó nem nulla maradék lesz az lnko. Ő ugyanis osztója a láncolatban szereplő összes számnak, tehát a kiinduló két számnak is. És fordítva, a kiinduló két szám minden közös osztója osztója lesz a láncolatban szereplő összes számnak, tehát az utolsó nem nulla maradéknak is. És az algoritmus valamikor biztosan véget ér, mivel a maradékok sorozata szigorúan monoton csökkenő.
Itt találtam: Python haiku

Megoldás a feladat szerint
A feladat azt kéri, hogy ezt az algoritmus használjuk:
tortAlgRekurzio
Ez egy rekurzív függvény, mert önmagát hívja meg egészen addig, amíg az a egyenlő nem lesz b-vel.

Nézzük, hogyan működik:
Algoritmus teszt
a b a = b a < b a > b
21 33 hamis igaz hamis
21 33-21 = 12 hamis hamis igaz
21-12 = 9 12 hamis igaz hamis
9 12 - 9 = 3 hamis hamis igaz
9 - 3 = 6 3 hamis igaz hamis
3 3 igaz hamis hamis
És tényleg a 21 és 33 legnagyobb közös osztója a 3.
  
Megoldás python nyelven
print("2. feladat")
def lnko(a, b)
    if a == b:
        return a
    if a < b:
        return lnko(a, b - a)
    if a > b:
        return lnko(b, a - b)
Az lnko egy saját gyártású függvény, használata a következő:
print(lnko(21, 33))
vagy
x = lnko(21,33)
3. feladat
Az első feladatban bekért törtet hozza a legegyszerűbb alakra a létrehozott függvény segítségével! Amennyiben nem sikerül az előírt függvényt elkészítenie, alkalmazhat más megoldást, hogy a további feladatokat meg tudja oldani. Az eredményt írja ki a következő formában:
24/32 = 3/4
vagy
24/6 = 4
A megoldás
print("3. feladat")
oszto = lnko(a,b)
if int(b / oszto) != 1:
    print("%d/%d = %d/%d"%(a,b,int(a/oszto), int(b/oszto)))
else:
    print("%d/%d = %d"%(a,b,int(a/oszto)))
4. feladat
Két törtet úgy tudunk összeszorozni, hogy a két tört számlálóját összeszorozva kapjuk az eredmény számlálóját, és a két tört nevezőjét összeszorozva kapjuk az eredmény nevezőjét. Kérjen be a felhasználótól egy újabb közönséges törtet a számlálójával és a nevezőjével! Szorozza meg ezzel a törttel az első feladatban bekért törtet! Az eredményt hozza a legegyszerűbb alakra, és ezt írja ki a következő formában:
24/32 * 12/15 = 288/480 =3/5
vagy
24/32 * 8/3 = 192/96 = 2
A megoldás
print("4. feladat")
c = int(input("Kérem a szorzó tört számlálóját: "))
d = int(input("Kérem a szorzó tört nevezőjét: "))
oszto = lnko(a*c,b*d)
if int(b*d / oszto) != 1:
    print("%d/%d * %d/%d = %d/%d = %d/%d"%(a,b,c,d,a*c,b*d,int(a*c/oszto), int(b*d/oszto)))
else:
    print("%d/%d * %d/%d = %d/%d = %d"%(a,b,c,d,a*c,b*d,int(a*c/oszto)))
5. feladat
Két közönséges tört összeadásához a következő lépésekre van szükség:
  • Mindkét számot bővíteni kell, azaz mind a számlálóját, mind a nevezőjét ugyanazzal a számmal kell megszorozni. Ezt a bővítést úgy célszerű elvégezni, hogy a közös nevező a két eredeti nevező legkisebb közös többszöröse legyen. Ez lesz az összeg nevezője.
  • A két bővített alakú tört számlálóját összeadjuk, ez lesz az eredmény számlálója. Ehhez készítsen függvényt az alábbiakban leírtak szerint – a korábban elkészített lnko függvény felhasználásával – a legkisebb közös többszörös meghatározására!
Függvény lkkt(a, b: egész számok) : egész szám
   lkkt := a * b / lnko(a, b)
Függvény vége
Egyszerű matematika: 12 = 2 * 2 * 3 és 18 = 2 * 3 * 3, tehát a legnagyobb közös osztó  2 * 3 = 6. A függvény szerint a legkisebb közös többszörös 12 * 18 / 6 = 36. A matek órán tanultak szerint az összes prímtényező a legmagasabb hatványon a legkisebb közös többszörös. Vagyis 2 * 2 * 3 * 3 = 36. És tényleg.  
  
A megoldás
print("5. feladat")
def lkkt(a, b):
    return int(a * b / lnko(a,b))
6. feladat
A függvény segítségével határozza meg a két bekért tört összegét, és ezt adja meg a következő formában! (Amennyiben nem sikerül az előírt függvényt elkészítenie, alkalmazhat más megoldást, hogy a további feladatokat meg tudja oldani.)
24/32 + 8/3 = 72/96 + 256/96 = 328/96 = 41/12
Amennyiben az eredmény felírható egész számként, akkor ebben az alakban jelenjen meg:
22/4 + 27/6 = 66/12 + 54/12 = 120/12 = 10
A megoldás
print("6. feladat")
_lkkt = lkkt(b,d) #a legkisebb közös többszörös kiszámítása
_a = a * _lkkt / b #az első tag bővített számlálója
_c = c * _lkkt / d #az második tag bővített számlálója
_sz = _a + _c #eredmény számlálója
if int(_lkkt / lnko(_sz, _lkkt)) != 1:
    print("%d/%d + %d/%d = %d/%d + %d/%d = %d/%d = %d/%d"%(a,b,c,d,_a, _lkkt, _c, _lkkt, _sz, _lkkt, int(_sz/lnko(_sz,_lkkt)),int(_lkkt/lnko(_sz,_lkkt))))
else:
    print("%d/%d + %d/%d = %d/%d + %d/%d = %d/%d = %d"%(a,b,c,d,_a, _lkkt, _c, _lkkt, _sz, _lkkt, int(_sz/lnko(_sz,_lkkt))))
7. feladat
Az adat.txt (becsomagolva(zip)) állományban található műveleteket végezze el, és az eredményeket a korábbi, képernyőre kiírt formátumnak megfelelően írja az eredmeny.txt állományba! Az adat.txt fájlnak legfeljebb 100 sora lehet; soronként 4 számot és egy műveleti jelet tartalmaz, melyeket mindenhol egy szóköz választ el egymástól. Műveleti jelként csak összeadás és szorzás szerepel.

A megoldás
Ez  a beolvasás:
print("7. feladat")
feladatok = []
with open("adat.txt","r") as adat:
    for egySor in adat:      
        feladatok.append(list(egySor.strip().split(" ")))
Ez pedig a kiírás:
with open("eredmeny.txt","w") as eredmeny: 
    for egyFeladat in feladatok:
        a = int(egyFeladat[0])
        b = int(egyFeladat[1])
        c = int(egyFeladat[2])
        d = int(egyFeladat[3])
        muvelet = egyFeladat[4]
        if muvelet == "+":
            _lkkt = lkkt(b,d)
            _a = a * _lkkt / b
            _c = c * _lkkt / d
            _sz = _a + _c
            if int(_lkkt / lnko(_sz, _lkkt)) != 1:
                eredmeny.write("%d/%d + %d/%d = %d/%d + %d/%d = %d/%d = %d/%d"%(a,b,c,d,_a, _lkkt, _c, _lkkt, _sz, _lkkt, int(_sz/lnko(_sz,_lkkt)),int(_lkkt/lnko(_sz,_lkkt))))
            else:
                eredmeny.write("%d/%d + %d/%d = %d/%d + %d/%d = %d/%d = %d"%(a,b,c,d,_a, _lkkt, _c, _lkkt, _sz, _lkkt, int(_sz/lnko(_sz,_lkkt))))
        if muvelet == "*":
            oszto = lnko(a*c,b*d)
            if int((b*d) / oszto) != 1:
                eredmeny.write("%d/%d * %d/%d = %d/%d = %d/%d"%(a,b,c,d,a*c,b*d,int(a*c/oszto),int(b*d/oszto)))
            else:
                eredmeny.write("%d/%d * %d/%d = %d/%d = %d"%(a,b,c,d,a*c,b*d,int(a*c/oszto)))
        eredmeny.write("\n")            
Ez a megoldás olyan, mint amikor a diák, nem olvassa el előre a feladatot, nem tervez előre, csak csinálja, csinálja és csinálja. Gyakorlatilag lemásoltam újra az előző feladatok megoldását, a print() utasítást pedig átírtam eredmeny.write() utasításra. Ez gyors, de nem szép programozói megoldás.
A tört feladat megoldás hivatkozás alatt a teljes programot találod a szebbik megoldással.