3. Scala kodutöö
Moodle'ist leiad ka lahendusfaili malli Kt3.scala
.
Lihtsaim on lahendage ülesanne vastavalt Moodle-s olevale mallile.
Ära kasuta mutable andmestruktuure ega ka var-muutujaid! Nende asemel kasuta (tavalisi) immutable andmestuktuure, nende (kõrgemat järku) operatsioone ja for avaldisi.
Kasutame mõningaid tüübisünonüüme, sest käsitleme siin tihti numbrid tekstuaalselt (mitte nagu Int):
type Digit = Char type PhoneNumber = String
Telefoninumbrite all on tavaliselt sellised tähed.
Map('1' -> "", '2' -> "AÄBC", '3' -> "DEF", '4' -> "GHI", '5' -> "JKL", '6' -> "MNOÖÕ", '7' -> "PQRSŠ", '8' -> "TUÜV", '9' -> "WXYZŽ")
Alamülesanne 1 (0.5p)
Meil oleks hea kõigepealt pöörata seda teisendust, et saaks sõnestatud numbrist tegeliku numbri kätte. Funktsioon võtab kodeeringu argumendiks ja tagastab vastupidises suunas map tähtedest numbritesse.
Näiteks sisendi Map('1' -> "A", '2' -> "BC", '3' -> "DX")
tulemuseks on järgmine: Map('A' -> '1', 'B' -> '2', 'C' -> '2', 'D' -> '3', 'X' -> '3')
Milline peaks olema meie yield, kui tulemuseks peaks olema map? Millest koosneb map?
def invertMapping(codeTable: Map[Digit, String]): Map[Char, Digit] = { ??? }
Alamülesanne 2 (0.5p)
Siin on meie konkreetne map, charCode
, mis jätab teied sümboleid (näiteks sidekriips, tühik) samaks:
lazy val charCode: Char => Digit = invertMapping(mnemonics).withDefault(x => x)
Nüüd siis funktsioon, mis teisendab phoneword päris telefoninumbriks.
def wordCode(phoneword: String): PhoneNumber = { ??? }
Siis võib ka proovida käivitada:
println(wordCode("1-800-GOT-JUNK"))
println(wordCode("karuala"))
Alamülesanne 3 (0.5p)
Tahaks siis telefoninumbreid transleerida sellisteks sõnedeks. Loeme sisse sõnad ja viskame välja liiga lühikesed sõnad.
lazy val words = Using.resource(io.Source.fromFile("s6nad.txt"))(_.getLines().filter(_.length > 2).toList)
Nüüd natuke raskem ülesanne. Tahame sõnad rühmitada (groupBy
) selle järgi, et igale numbrijupile saaks tagasi kõik sõnad meie sõnaraamatust, mis sellele vastavad.
lazy val wordsForNum: Map[PhoneNumber, Seq[String]] = { ??? }
Selles alamülesandes võib samuti kasu olla Map
-i withDefault
või withDefaultValue
operatsioonidest.
Alamülesanne 4 (1.5p)
See on nüüd põhimeetod, kus üritame telefoninumbrile pakkuda kõik võimalikud sõne-kombinatsioonid. Peame läbi proovima kõik võimalikud viisid numbrid tükeldada ja iga juppi kohta vaadata wordsForNum
-is järgi, mis sõned sellele jupile sobiksid. Tuleb kõik kombinatsioonid kombineerida üheks suureks hulgaks. Sõned kirjutage suurte tähtedega!
Arvestama peaks ka variandiga tükeldada number rohkem kui kaheks jupiks! Selleks on hea kasutada rekursiooni.
Näiteks encode("5278252")
on Set(List(KARV, ALA), List(LAST, ALA), List(LAST, AKA), ... , List(KARV, AKA), List(LAS, TALA))
def encode(number: String): Set[List[String]] = { ??? }
Lisa
Väljastamiseks võib natuke ilusamaks sõneks teisendada:
def translate(number: PhoneNumber): String = { encode(number).map(_ mkString "-").to(SortedSet).mkString(", ") }
Eesti telefoninumbrites esinevad ka ühed ja nullid. Selliste numbritega ei saa hetkel hakkama. Võiks lasta neid eraldi seisvatena telefoninumbris lihtsalt alles jätta. Viimase testi jaoks peab koodi üleval niimoodi muuta, et ka eesti numbritega töötaks.
Näiteks: println(translate("5270252"))