Használható segédanyagok: Haskell könyvtárainak dokumentációja, (lokális!) Hoogle, a tárgy honlapja és a BE-AD rendszerbe feltöltött beadandók. Ha bármilyen kérdés, észrevétel felmerül, azt a felügyelőknek kell jelezni, nem a diáktársaknak!
A feladatok egymásra épülnek ezért érdemes ezeket a megadásuk sorrendjében megoldani, de legalább megérteni az aktuális feladatot megelőző feladatokat! A függvények definíciójában lehet, sőt javasolt is alkalmazni a korábban definiált függvényeket (függetlenül attól, hogy sikerült-e azokat megadni).
Tekintve, hogy a tesztesetek, bár odafigyelés mellett íródnak, nem fedik le minden esetben a függvény teljes működését, határozottan javasolt még külön próbálgatni a megoldásokat beadás előtt, vagy megkérdezni a felügyelőket!
Részpontszámokat csak az elégséges szint elérése után lehet kapni!
A Kukutyin Dolce Vita pizzéria hálózat szeretne mobil pizzériákat indítani, amelyek napközben kitelepülnek a város különböző pontjaira és a helyszínen kiszolgálják a vevőket, illetve házhozszállítást is végeznek. Céljuk, hogy a pizzériákból minél előbb kiérjen a pizza a megrendelőhöz.
Felkértek bennünket, hogy segítsük Őket az új üzleti modelljük sikerre vitelében. A feladatul azt kaptuk, hogy a pizzériák helyszíneit ismerve, megpróbáljuk a megrendelőket a lehető legközelebbi pizzériából kiszolgálni. Egyszerűsítésként, egyszerre csak egy megrendelést tudnak teljesíteni, azaz nem kötik össze több megrendelés kiszállítását.
A cégtől megkapjuk a legfrissebb útinformációkat és a pizzériák elhelyezkedését. A feladatunk az lesz hogy ennek ismeretében megadjuk, hogy melyik pizzériából és milyen útvonalon kell teljesíteni a különböző megrendeléseket.
A dolgunk megkönnyítése céljából, a kapott leírásból készítettünk egy gráfot. A leírásban szereplő kereszteződéseket a gráf csúcsaiként (vagy csomópontjaiként), a kereszteződéseket összekötő útszakaszok pedig a gráf éleiként fogjuk jelölni. Az élek irányítottak, azaz ha egy a és b között található él, akkor a-ból b-be közvetlenül el tudunk jutni. Ez fordítva nem igaz, hacsak nincs egy b-ből a-ba mutató él is a gráfban. A feladat megoldása során feltételezhetjük, hogy a gráf összefüggő, azaz két tetszőlegesen kiválasztott csúcsa között létezik út.
A gráfot (Map
) egy listával adjuk meg, amelynek rendezett párok az elemei (Section
). Egy rendezett pár (Section
) két csúcsból (Junction
) áll, amely a köztük lévő közvetlen utat adja meg. Ha egy (a,b)
rendezett pár megtalálható a listában, ez azt jelenti hogy az a
-ból b
-be át tudunk jutni közvetlenül.
(A type
kulcsszó segítségével a gráf csúcsainak azonosítására használt Junction
típus az Int
típus, a Section
típus a Node
típusból képzett párok (Node, Node)
típusának egy másik neve lesz. A Map
típus a Edge
típusból alkotott listákat/sorozatokat fogja jelenteni, hasonlóan a String
és [Char]
viszonyához. A programban ez semmilyen további megszorítást nem indukál, csupán a beszédesebb függvénytípusok kialakításában segít.)
A megoldás teszteléséhez bevezetjük a következő két gráfot:
Az egyes műveletekhez és teszteléshez szükségünk lehet a gráfban található összes csomópontra.
Definiáljuk azt a függvényt, amelyik megadja egy gráf összes csomópontját! Az eredmény minden csomópontot egyszer tartalmazzon és ezek érték szerint növekvő sorrendben szerepeljenek!
Adjuk meg azt a függvényt, amely egy adott csúcs szomszédait adja meg! Szomszéd alatt most azokat a csúcsokat értjük, amelyek elérhetőek a megadott csúcsból.
A feladat megoldása során útvonalakat fogunk meghatározni, ezért az kód olvashatóságának növelése céljából bevezetjük a Route
típus. A Route
szinonimával jelzett lista minden esetben egy útvonalat, vagyis szomszédos csúcsok sorozatát fogja jelenteni.
FONTOS: A útvonalak fordított sorrendben adottak, azaz a kiindulópont mindig az utolsó eleme! Tehát, a [4,3,2,1]
útvonal az 1-es csúcsból indul és a 4-es csúcsban ér véget.
Amennyiben egy csúcsból több irányba is tovább tudunk haladni, úgy minden irányhoz egy új útvonalat fogunk megadni.
Adjuk meg azt a műveletet, amely egy adott útvonalat az összes lehetséges módon megpróbál egy újabb rendelkezésre álló szomszédos csúccsal bővíteni!
Ügyeljünk arra, hogy csak olyan csúcsokkal bővítsük az útvonalat, amely még nem szerepel az útvonalban! Amennyiben nincs ennek a feltételnek megfelelő egyetlen csúcs sem, akkor az eredmény egy üres lista legyen!
Segítség:
Amennyiben a jelenlegi útvonalunk [3,1]
úgy a map1
esetében a 2, 4, 5 sorszámú (az ábrán pirossal jelzett) csúcsokkal bővíthetjük az útvonalat.
Tehát az eredmény három útvonalat fog tartalmazni, ez a [[2, 3, 1], [4, 3, 1], [5, 3, 1]]
lista. Szemléltetve:
Adott egy útvonalsorozat, amelynek minden elemét folytatni szeretnénk.
Definiáljuk azt a függvényt, amely egy útvonalsorozat minden elemét az összes lehetséges módon megpróbál bővíteni! Használjuk a step
műveletet!
A feladat ezen részében megpróbáljuk megadni egy a csúcsból induló b csúcsban végződő legrövidebb utat vagy utakat (amennyiben több is van belőle).
Adott egy útvonalakat tartalmazó sorozat és szeretnénk tudni, hogy ezek közül melyik útvonalak érnek véget a megadott kereszteződésben.
Definiáljuk azt a műveletet, amely csak az adott pontban végződő útvonalakat adja meg!
Megjegyzés: Ne feledjük, hogy az útvonalak fordított sorrendben adottak.
Adjuk meg azt a függvényt, amely igazat ad vissza, ha a megadott sorozatban van olyan útvonal, amelyik a megadott pontban végződik!
Adjuk meg azt a függvényt, amely inicializál egy útvonal-sorozatot a megadott csúcsból! A függvény eredménye egy lista, amely egy egy elemű útvonalat tartalmaz (a megadott kiindulóponttal).
Amennyiben a csúcs nem szerepel a megadott térképen, úgy adjunk egy hibaüzenetet az error
függvény segítségével!
Segítség: Az error
függvénynek egy String
típusú értéket kell paraméterül adni, amely maga a hiba szövege.
Adjuk meg azt a függvényt, amely megadja az összes legrövidebb útvonalat a kiindulópontból a megadott végpontig!
A működés:
ismételjük a steps
műveletet a kezdeti csúcsból indulva mindaddig, amíg nincs legalább egy megfelelő útvonal az eredményben (azaz a megadott pontban végződik),
az eredményből válogassuk ki a megfelelő útvonalakat.
Megjegyzések:
Mivel a feladatban feltettük, hogy a gráfok összefüggőek, azért előbb-utóbb lesz legalább egy útvonal, ami a megfelelő csúcsban végződik.
A leírt módszerrel egy egyszerű szélességi keresést végzünk a gráfban.
A függvényeink könnyebb olvashatósága érdekében, bevezetünk a Pizzeria
szinonimát. Ezzel olyan kereszteződéseket fogunk jelölni, amelyekben található kitelepült pizzéria.
A feladatunk az lesz, hogy több pizzéria helyszínét ismerve, adjuk meg a legközelebbi pizzériából induló útvonalat a megrendelőhöz.
Adott a pizzériák pozícióinak nemüres listája és a megrendeléshez legközelebbi kereszteződés azonosítója.
Adjuk meg azt az útvonalat amely a legkevesebb csomópontot tartalmazza! Amennyiben több azonos hosszúságú legrövidebb út is létezik, adjuk meg az elsőt ezek közül.
A pizzéria minőségbiztosítási osztálya szeretné tudni, hogy a nap folyamán melyik pizzéria mennyi megrendelést teljesített. Az eddig ismerteken túl, kapunk egy listát, amelyben megtalálhatók a rendelések helyszínei (OrderList
).
Adjuk meg azt a függvényt, amely a megrendelés listából előállítja csoportosítva, hogy melyik pizzéria teljesítette a megrendelést! Az eredmény egy rendezett párokból ((Pizzeria, OrderList)
) álló sorozat, amely a kiszolgálást végző pizzériák szerint osztja szét a megrendelések listáját.
A működés:
határozzuk meg minden megrendeléshez a kiszolgáló éttermet,
rendezzük össze csoportokba ezt az információt,
csoportonként összesítsük az adatokat.