diff -r 4a5b59690f0a -r 87e487ccbd7c main_testing2/wordle.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main_testing2/wordle.scala Wed Nov 09 16:44:16 2022 +0000 @@ -0,0 +1,225 @@ +// Resit Part about an Evil Wordle Clone +//========================================== +// +// Task description are on KEATS +// +// Make sure you use Scala Version 2.13 (not Scala 3) +// +// Upload your submision to OneSpace and give Senir and Christian +// write access to the folder. The folder should have you email +// address as name. Give us write permission by July 25th such +// that we can download your solution by the closing date August 4th. + +object Resit { + +import io.Source +import scala.util._ + +//============================= +// Task 1 [0.25 Marks] + +def get_wordle_list(url: String) : List[String] = { + try{ + val raw = Source.fromURL(url).mkString + raw.split("\n").toList + } + catch { + case e : Exception => List[String]() + } +} + + +// val secrets = get_wordle_list("https://nms.kcl.ac.uk/christian.urban/wordle.txt") +// secrets.length => 12972 +// secrets.filter(_.length != 5) => Nil + +//============================= +// Task 2 [0.25 Marks] + +def removeOne[A](xs: List[A], elem: A) : List[A] = { + val index = xs.indexOf(elem) + val first = xs.take(index) + val second = xs.drop(index + 1) + first ::: second +} + +// removeOne(List(1,2,3,2,1), 3) => List(1, 2, 2, 1) +// removeOne(List(1,2,3,2,1), 2) => List(1, 3, 2, 1) +// removeOne(List(1,2,3,2,1), 1) => List(2, 3, 2, 1) +// removeOne(List(1,2,3,2,1), 0) => List(1, 2, 3, 2, 1) + + +//============================= +// Task 3 [1.5 Marks] + +abstract class Tip +case object Absent extends Tip +case object Present extends Tip +case object Correct extends Tip + +def pool(secret: String, word: String) : List[Char]= { + for (i <- (0 to 4).toList + if secret(i) != word(i)) + yield secret(i) +} + +def aux(secret: List[Char], word: List[Char], pool: List[Char]) : List[Tip] = (secret, word) match { + case (Nil, Nil) => Nil + case (s::srest, w::wrest) => { + if (s == w) Correct::aux(srest, wrest, pool) + else if (pool.contains(w)) Present::aux(srest, wrest, removeOne(pool, w)) + else Absent::aux(srest, wrest, pool) + } +} + +def score(secret: String, word: String) : List[Tip] = + aux(secret.toList, word.toList, pool(secret, word)) + +/* +def pool(secret: String, word: String) : List[Char] = { + (secret zip word).collect { + case (c1, c2) if c1 != c2 => s"$c1" + }.toList.flatten +} + +def aux2(secret: String, word: String, pool: List[Char], result: List[Tip]) : List[Tip] = { + if (word.length == 0){ + result.reverse + } + else{ + if (word.take(1) == secret.take(1)) { + val updated = Correct :: result + aux2(secret.drop(1), word.drop(1), pool, updated) + } + else { + if(pool.contains(word.take(1)(0))){ + val updated = Present :: result + val removed = removeOne(pool, word.take(1)(0)).mkString.toList + aux2(secret.drop(1), word.drop(1), removed, updated) + } + else{ + val updated = Absent :: result + aux2(secret.drop(1), word.drop(1), pool, updated) + } + } + } +} + +def aux(secret: List[Char], word: List[Char], pool: List[Char]) : List[Tip] = { + aux2(secret.mkString, word.mkString, pool, List()) +} + +def score(secret: String, word: String) : List[Tip] = { + aux(secret.toList, word.toList, pool(secret, word)) +} +*/ + +// score("chess", "caves") +// score("doses", "slide") +// score("chess", "swiss") +// score("chess", "eexss") + + +//============================= +// Task 4 [0.5 Marks] + +def eval(t: Tip) : Int = t match { + case Correct => 10 + case Present => 1 + case Absent => 0 +} + +def iscore(secret: String, word: String) : Int = { + val list = score(secret, word) + val values = list.map(n => eval(n)) + values.sum +} + +// iscore("chess", "caves") +// iscore("doses", "slide") +// iscore("chess", "swiss") +// iscore("chess", "eexss") + +//============================= +// Task 5 [1.5 Mark] + +def lowest(secrets: List[String], word: String, current: Int, acc: List[String]) : List[String] = { + val mapped = secrets.map(x => (x, iscore(x, word))) + val min = mapped.minBy(_._2)._2 + val filt = mapped.filter(_._2 == min) + filt.map(x => x._1) +} + +def evil(secrets: List[String], word: String) : List[String] = { + lowest(secrets, word, Int.MaxValue, List()) +} + +//evil(secrets, "stent").length +//evil(secrets, "hexes").length +//evil(secrets, "horse").length +//evil(secrets, "hoise").length +//evil(secrets, "house").length + + +//============================= +// Task 6 [1 Mark] + +def frequencies(secrets: List[String]) : Map[Char, Double] = { + val all = secrets.flatten + all.groupBy(identity).view.mapValues(1.0D - _.size.toDouble / all.size ).toMap +} + +//frequencies(secrets)('y') + +/* + +def frequencies(secrets: List[String]) : Map[Char, Double] = { + val letters = secrets.flatten + val totalLetters = letters.length.toDouble + val alph = ('a' to 'z').toList + val letterCount = alph.map(x => (x, letters.filter(_ == x).length.toDouble)) + letterCount.map(x => (x._1, 1.0-(letterCount.filter(_._1 == x._1)(0)._2/totalLetters))).toMap +} +*/ + +// frequencies(secrets)('y') +// frequencies(secrets)('e') + +//============================= +// Task 7 [1 Mark] + +def rank(frqs: Map[Char, Double], s: String) = { + s.map(frqs(_)).sum +} + +def ranked_evil(secrets: List[String], word: String) = { + val frqs = frequencies(secrets) + val ev = evil(secrets, word) + ev.groupBy(rank(frqs, _)).toList.sortBy(_._1).reverse.head._2 +} + +/* +def rank(frqs: Map[Char, Double], s: String) : Double = { + val letters = s.toList + val scores = letters.map(x => frqs(x).toDouble) + scores.sum +} + +def ranked_evil(secrets: List[String], word: String) : List[String] = { + val most = evil(secrets, word) + val mapped = most.map(x => (x, rank(frequencies(secrets),x))) + val mx = mapped.maxBy(_._2)._2 + val filt = mapped.filter(_._2 == mx) + filt.map(x => x._1) +} +*/ +//rank(frequencies(secrets), "adobe") +//rank(frequencies(secrets), "gaffe") +//rank(frequencies(secrets), "fuzzy") + +//ranked_evil(secrets, "beats") +//ranked_evil(secrets, "vitae") +//ranked_evil(secrets, "bento") +//ranked_evil(secrets, "belts") + +} \ No newline at end of file