FANDOM


ÁttekintésSzerkesztés

Nem akarok háromdimenziós adathalmazzal dolgozni, ezért a megoldásokat egydimenziós listaként kezelem, és ezekből lesz egy szótár. Ez egy absztrakció, amelynek következtében a szomszédságokat és láthatóságokat algebrai feltételként lehet megfogalmazni; talán kevésbé szemléletes, mint a kétdimenziós listák listája, de szerintem olvashatóbb kódot eredményez.

A megoldásban bemutatott érdekes nyelvi elemek:

  • Az extend használata lista bővítésére másik listával
  • Maradékos osztás használata az egydimenziós lista és a kétdimenziós tábla koordinátái közötti megfeleltetéshez
  • A lambdafüggvény
  • A filter és a map függvény (vigyázat, ezek Python2-ben listát, Python3-ban iterátort adnak vissza, ezért itt listává kell alakítanunk az eredményt!)
  • Feltételes kifejezés (... if ... else ... -- más nyelvekben ?: szerkezet)
  • Feltételes kifejezés másként a redukt listában -- tuple logikai kifejezéssel indexelve
  • Lista szeletelése adott lépésközzel (oszlopok kivágásához)
  • Másolat készítése listáról a szur függvényben (a paraméter nem válik lokálissá)
  • A szótár adatszerkezet (akkor kellemes, ha a sorrend nem számít)

Első megoldásSzerkesztés

Check Tesztelve a 3.4.3 verzióban.

# -*- coding: utf-8 -*-
"""
Idegen nyelvű érettségi, 2011. május, Rejtvény feladat
Előfeltétel: csak 10*10-es mátrixokkal dolgozunk, és semmilyen bemenő
adatot nem kell ellenőrizni, a mintának megfelelőek.
"""

# Konkrétan megadott adatok:
N = 10 # Egyelőre négyzet, lehetne tovább általánosítani.
HAJOK = 12 # Ennyit várunk el a megoldásban.

def feladat(i):
    print('%d. feladat' % i)

feladat(1)
sor = int(input('Hányadik sorban van a torony? '))
oszlop = int(input('Hányadik oszlopban van a torony? '))
darab = int(input('Hány hajó lehet látható a toronyból? '))
if darab > 3:
    print('Nehéz torony.')

feladat(2)
print('Tiltott helyek:') # Csak a táblán belül mozgunk!
for i in range(max(sor-1, 1), min(sor+2, N+1)):
    for j in range(max(oszlop-1, 1), min(oszlop+2, N+1)):
        if not (i == sor and j == oszlop):
            print('%d,%d' % (i, j))
            
def beolvasegyet(f):
    l = []
    for i in range(N):
        sor = f.readline().replace('\n', '')
        l.extend([int(x) for x in sor.split(' ')])
    return l

feladat(3)
# Beolvasások
feladvanyInput = open('feladvany.txt')
megoldasInput = open('megoldas.txt')
feladvany = beolvasegyet(feladvanyInput)
megoldas = {}
mdarab = int(megoldasInput.readline())
for megoldo in range(mdarab):
    user = megoldasInput.readline().split('\n')[0]
    megoldas[user] = beolvasegyet(megoldasInput)
# Feldolgozás
hetimegoldok = []
for user in megoldas:
    redukt = list(map((lambda elem:((elem, 0)[elem == 11])), megoldas[user]))
    if redukt == feladvany:
        hetimegoldok.append(user)
    else:
        print(user)
if len(hetimegoldok) == mdarab:
    print('Mindegyik megoldás erre a heti feladványra érkezett.')
    
feladat(4)
hetimegoldok12hajoval = []
for user in hetimegoldok:
    if megoldas[user].count(11) == HAJOK:
        hetimegoldok12hajoval.append(user)
hiba = len(hetimegoldok) - len(hetimegoldok12hajoval)
print('Hibás megoldások száma: %d' % hiba)

feladat(5)
hetimegoldokJoszomszedsag = []
# Vegyük észre, hogy a szomszédban levő hajók és világítótornyok egyformák.
# Csak az számít, van-e ott valami, ami nem 0.
# Készítsünk egy szűrőfüggvényt az adott pozícióhoz, amely az érdekes mezőket tartja meg!
# Ravasz módon a tábla mezői felől közelítjük meg, mert így nem kell
# esetszétválasztást rendezni aszerint, hogy a tábla szélén van-e a hajó.
# Kicsit lassabb, de sokkal egyszerűbb kódolni.
def myfilter(pos):
    mf = []
    for i in range(len(feladvany)):
        mf.append(
            True if i != pos and abs(i%N - pos%N) < 2 and abs(i//N - pos//N) < 2
            else False)
    return mf

def szur(lista, hol):
    l = lista[:] # Másolatot kell készítenünk róla, különben elrontjuk!
    f = myfilter(hol)
    for j in range(len(l)):
        if not f[j]:
            l[j] = False
    return l
    
for user in hetimegoldok12hajoval:
    m = megoldas[user]
    rosszhelyen = 0
    i = 0
    while rosszhelyen == 0 and i < N * N:
        if m[i] == 11:
            rosszhelyen += sum(szur(m, i))
        i += 1
    if rosszhelyen == 0:
        hetimegoldokJoszomszedsag.append(user)
hiba = len(hetimegoldok12hajoval) - len(hetimegoldokJoszomszedsag)
print('Hibás megoldások száma: %d' % hiba)

feladat(6)
jomegoldok = []
for user in hetimegoldokJoszomszedsag:
    m = megoldas[user]
    OK = True
    for i in range(len(feladvany)):
        if feladvany[i]:
            oszlop = m[i%N : : N]
            sor = m[(i//10) * N : (i//10 + 1) * N]
            latotthajok = len(list(filter(lambda elem:elem==11, oszlop + sor)))
            if latotthajok != feladvany[i]:
                OK = False
                break
    if OK:
        jomegoldok.append(user)
print('Helyesen oldották meg: \n%s' % '\n'.join(jomegoldok))

Második megoldásSzerkesztés

Alternatív megoldás a myfilter() függvényre: itt nem a tábla, hanem a hajó felől közelítjük meg. Gyorsabban fut, mert nem kell végigmennie az egész táblán, de sokkal több idő lekódolni, mert esetszétválasztásokat kell csinálni aszerint, hogy melyik szélén van a hajó a táblának. Nem is túl szép, mert indextúllépés következtében a tábla másik helyére írhat, ha a bal vagy a jobb szélén vagyunk, de biztos, hogy ilyenkor False értéket ír felül False-szal, tehát csak elvi problémát okoz. Nem véletlenül cseréltem le.

# Készítsünk egy szűrőfüggvényt az adott pozícióhoz, amely az érdekes mezőket tartja meg!
def myfilter_old(pos):
    # 0 <= pos < N*N
    alap = [False] * N * N
    if pos > N - 1: # Nem a felső sor
        alap[pos - N - 1] = pos % N > 0
        alap[pos - N] = True
        alap[pos - N + 1] = pos % N < 9
    if pos < N * N - N: # Nem az alsó sor
        alap[pos + N - 1] = pos % N > 0
        alap[pos + N] = True
        alap[pos + N + 1] = pos % N < 9
    # Mellette levők
    if pos % N > 0:
        alap[pos - 1] = True
    if pos % N < 9:
        alap[pos + 1] = True
    return alap

Ez a szócikk forráskódot tartalmaz, amely egy WikiMedia-kiegészítés segítségével olyan színesen jeleníthető meg, mint például ebben a Wikipédia-cikkben. A kiegészítést a Wikia-stáb ígérete szerint 2010 végéig frissítik, addig türelmet kérünk a fapados kinézet miatt.

Érettségi feladatok programozásból
2004 Személyazonosító jel

2005 LottóVigenère-tábla 2006 TelefonszámlaFehérjeZenei adók 2007 SMS-szavakFoci 2008 SMSRobot 2009 LiftAutomataÚtépítés 2010 HelyjegyTelekAnagramma 2011 SzójátékRejtvényPitypang 2012 FutárTörtekSzín-kép 2013 VálasztásokSzámokKözúti ellenőrzés 2014 IPv6CéllövészetNézőtér 2015 ExpedícióLatin táncokFej vagy írás 2016 ÖtszázZárTelefonos ügyfélszolgálat 2017 TesztversenyFürdő

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.