Morzekódok

Használható segédanyagok: Haskell könyvtárainak dokumentációja, Hoogle, a tárgy honlapja és a BE-AD rendszerbe feltöltött beadandók. Ha bármi kérdés, észrevétel felmerül azt a gyakorlatvezetőnek jelezzétek, NE a mellettetek ülőnek!

Feladat összefoglaló leírása

Ebben a feladatban morzekódolást segítő függvényeket kell megvalósítani. A feladatok egy része egymásra épül, ezeket megadás sorrendjében oldjátok meg, de a többi esetben ez nem kötelező!

A morzekód (angolul: Morse code) olyan kommunikációs kód, mely latin betűs írott szöveg átvitelét teszi lehetővé kétállapotú kommunikációs csatornán (a kommunikációs eszköz egy adott időpontban vagy ki-, vagy bekapcsolt állapotban van; ilyen eszköz például a távíró vagy egy lámpa).

Morse a pontokból és vonásokból álló, betűket és írásjeleket jelentő jelcsoportjait nem véletlenszerűen határozta meg. Egyik rokona nyomdász volt, aki a kész betűket rekeszekből álló tárolókban tartotta. Morse megfigyelte, hogy bizonyos betűkre és jelekre többször volt szükség, másokat pedig ritkábban használtak fel. Az angol ábécé leggyakrabban használt betűjének, az “E”-nek egy pont lett a jele, míg a második leggyakoribb betűnek, a “T”-nek egy vonás. Az “O” betű három vonás, míg a következő rövid betű, az “A” egy pontból és egy vonásból áll össze. Az “N” betű ennek épp fordítottja lett, egy vonás és egy pont.

A morzekódokat tartalmazó táblát nem kell létrehozni, mert az az alábbi konstansban adott. A tábla csak nagybetűket és a hozzá tartozó morzekódokat, ‘.’ és ‘-’ karakterek sorozatát tartalmazzák.

morseTab :: [(Char, String)]
morseTab =
  [('A',".-"),('B',"-..."),('C',"-.-."),('D',"-.."),('E',".")
  ,('F',"..-."),('G',"--."),('H',"...."),('I',".."),('J',".---")
  ,('K',"-.-"),('L',".-.."),('M',"--"),('N',"-."),('O',"---")
  ,('P',".--."),('Q',"--.-"),('R',".-."),('S',"..."),('T',"-")
  ,('U',"..-"),('V',"...-"),('W',".--"),('X',"-..-")
  ,('Y',"-.--"),('Z',"--..")
  ,('0',"-----"),('1',".----"),('2',"..---"),('3',"...--"),('4',"....-")
  ,('5',"....."),('6',"-...."),('7',"--..."),('8',"---.."),('9',"----.")
  ]

A kódolandó szöveg normalizálása (1 pont)

Mivel a táblában csak nagy latin karakterek és számjegyek szerepelnek (más karakterekkel jelenleg nem kívánunk dolgozni), adjuk meg azt a függvényt, amely egy szövegből csak az előbb megadott táblában fellelhető karaktereket szűri ki, vagy alakítja azokat át. Például: az ‘a’..’z’ karaktert ‘A’..’Z’ karakterekké alakítja, de az írásjeleket, whitespace-eket, stb. elhagyja belőle.

normalizeText :: String -> String

Test>
"SOS" :: String
Test>
"7" :: String
Test>
[] :: String
Test>
"SAVEOURSOULS" :: String
Test>
"KOMBKOM" :: String

Kódolás (1 pont)

Ahhoz, hogy egy latin karakterekből és számjegyekből álló szöveget a későbbiekben morzekóddá alakíthassunk, adjuk meg azt a függvényt, amely egy latin vagy számjegyet karaktert a hozzá rendelt morzekóddá konvertálja!

charToCode :: [(Char, String)] -> Char -> String

Test>
".-" :: String
Test>
"-." :: String
Test>
"--.." :: String
Test>
"-----" :: String
Test>
"-...." :: String
Test>
"???" :: String

Szöveg kódszavakká kódolása (1 pont)

Adjuk meg azt a függvényt, amely egy latin karakterekből és számjegyekből álló szöveget morzekódokból álló szavakká konvertál!

encodeToWords :: String -> [String]

Test>
["...", "---", "..."] :: [String]
Test>
["...", ".-", "...-", ".", "---", "..-", ".-.", "...", "---", "..-", ".-..", "..."] :: [String]
Test>
[] :: [String]
Test>
["--", ".", ".", "-", ".-", "-", "---..", ".--.", "--"] :: [String]

Kódolás szöveggé (1 pont)

Az előző függvényt továbbfejlesztve adjuk meg a szöveget morzekód szöveggé konvertáló függvényt!

encodeString :: String -> String

Test>
"....-...-.---..-.-....---..-.-....." :: String
Test>
[] :: String
Test>
"--..-.-----...--.--" :: String

Visszakódolás (1 pont)

Adjuk meg a charToCode függvényünk inverz műveletét, amely egy morzekódhoz meghatározza a hozzá rendelt karaktert!

codeToChar :: [(a,String)] -> String -> a

Test>
'V' :: Char
Test>
'A' :: Char

Kódszavak visszakódolása (1 pont)

Adjuk meg az encodeToWords függvény inverz műveletét, amely morzekód szavak sorozatából előállít egy latin karakterekből álló szöveget!

decodeWords :: [String] -> String

Test>
"SAVEOURSOULS" :: String
Test>
"V" :: String
Test>
[] :: String

Legrövidebb kód (3 pont)

Adjuk meg azt a függvényt, amely visszaadja az összes olyan karaktert egy kódokat tartalmazó táblából, amelyekhez a legrövidebb kód tartozik! A függvényt általánosan kell megírni, hogy az tetszőleges tábla esetén is jól működjön!

withShortestCodes :: [(Char,String)] -> [Char]

Test>
"ET" :: [Char]
Test>
"A" :: [Char]
Test>
"IMN" :: [Char]

A szöveg elejére illeszkedő kódok megtalálása (2 pont)

Mivel a morzekódok lehetnek prefixei egymásnak (Pl. egy “.-.” jelsorozat kezdőbetűje lehet az ‘A’, ‘E’ és ‘R’ karakter is), így nem egyértelmű egy ömlesztett jelsorozatból, hogy melyik betűről van szó. Adjuk meg azt a függvényt, amely megadja a lehetséges helyettesítéséket a megadott szöveg kezdőbetűjének.

getPossiblePrefixes :: [(Char,String)] -> String -> [(Char,String)]

Test>
[('A', ".-"), ('E', "."), ('R', ".-.")] :: [(Char, String)]
Test>
[('E', "."), ('I', ".."), ('S', "...")] :: [(Char, String)]
Test>
[] :: [(Char, String)]
Test>
[('E', ".")] :: [(Char, String)]
Test>
[('T', "-")] :: [(Char, String)]

A lehetséges értelmezések előállítása (5 pont)

Mint az már korábban is elhangzott a morzekódokkal adott szöveg visszafejtése nem egyértelmű, hiszen az egyes kódok prefixei lehetnek egy másik kódnak. Adjuk meg azt a függvényt, amely egy morzekód sorozatból előállítja az összes lehetséges visszafejtést.

decodeString :: String -> [String]

Test>
["EEE", "EI", "IE", "S"] :: [String]
Test>
["AE", "EN", "ETE", "R"] :: [String]
Test>
True :: Bool
Test>
False :: Bool

Pontozás