main_testing2/wordle.scala
changeset 435 fda7c39f3b6a
child 439 97594b9998a8
--- /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