main_testing2/wordle.scala
changeset 463 0315d9983cd0
parent 439 97594b9998a8
child 475 59e005dcf163
--- a/main_testing2/wordle.scala	Sun Jan 15 10:58:13 2023 +0000
+++ b/main_testing2/wordle.scala	Sat Mar 11 22:01:53 2023 +0000
@@ -1,7 +1,6 @@
 // Main Part 3 about Evil Wordle
 //===============================
 
-// test bash
 
 object M2 { 
 
@@ -10,31 +9,44 @@
 
 // ADD YOUR CODE BELOW
 //======================
+// def main(args: Array[String]): Unit = {
 
-// test import
-
+//     val secrets = get_wordle_list("https://nms.kcl.ac.uk/christian.urban/wordle.txt")
+//     println(ranked_evil(secrets, "beats")== List("fuzzy"))
+//     println(ranked_evil(secrets, "vitae") == List("fuzzy"))
+//     println(ranked_evil(secrets, "bento") == List("fuzzy"))
+//     println(ranked_evil(secrets, "belts") == List("fuzzy"))
+//     println(ranked_evil(secrets, "abbey") == List("whizz"))
+//     println(ranked_evil(secrets, "afear") == List("buzzy"))
+//     println(ranked_evil(secrets, "zincy") == List("jugum"))
+//     println(ranked_evil(secrets, "zippy") == List("chuff"))
+   
+    
+//    }
 
 //(1)
 def get_wordle_list(url: String) : List[String] = {
-  Try(Source.fromURL(url)("ISO-8859-1").getLines().toList).getOrElse(Nil)
+    try {
+        Source.fromURL(url).getLines.toList;
+    }
+    catch {
+        case _ : Throwable => List();
+    }    
 }
-
-
 // val secrets = get_wordle_list("https://nms.kcl.ac.uk/christian.urban/wordle.txt")
 // secrets.length // => 12972
 // secrets.filter(_.length != 5) // => Nil
 
 //(2)
 def removeN[A](xs: List[A], elem: A, n: Int) : List[A] = {
-    if (n == 0) xs 
-    else xs match {
-        case Nil => Nil
-        case x::xs => 
-            if (x == elem) removeN(xs, x, n - 1) 
-            else x::removeN(xs, elem, n)
-    } 
-}    
-
+    if (xs.isEmpty || n == 0 || !xs.contains(elem)){
+        xs
+    }
+    else{
+        val (newLst,newLst2) = xs.splitAt(xs.indexOf(elem))
+        removeN(newLst ++ newLst2.tail,elem, n-1)
+    }
+}
 
 // removeN(List(1,2,3,2,1), 3, 1)  // => List(1, 2, 2, 1)
 // removeN(List(1,2,3,2,1), 2, 1)  // => List(1, 3, 2, 1)
@@ -49,23 +61,42 @@
 
 
 def pool(secret: String, word: String) : List[Char] = {
-  for (i <- (0 to 4).toList 
-       if secret(i) != word(i))
-  yield secret(i) 
+    //print(secret.toList, word.toList)
+    val lst= ((0 to 4).map(x => {
+        if(!secret(x).equals(word(x))) Some(secret(x)) else None
+        
+        }).toList)
+    lst.flatten
 }
 
-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, removeN(pool, w, 1))
-        else  Absent::aux(srest, wrest, pool)
+
+def aux(secret: List[Char], word: List[Char], pool: List[Char]) : List[Tip] = {
+   
+    if (secret.length == 1){
+        if (secret.head == word.head){
+            List(Correct)
+        }
+        else if (pool.contains(word.head)){
+            List(Present) 
+        }
+        else {
+            List(Absent) 
+        }
+    }
+    else if (secret.head == word.head){
+        List(Correct) ++ aux(secret.tail, word.tail, pool)
+    }
+    else if (pool.contains(word.head)){
+        List(Present) ++ aux(secret.tail, word.tail, removeN(pool, word.head, 1))
+    }
+    else {
+        List(Absent) ++ aux(secret.tail, word.tail, pool)
     }
 }
 
-
-def score(secret: String, word: String) : List[Tip] = 
-  aux(secret.toList, word.toList, pool(secret, word))
+def score(secret: String, word: String) : List[Tip] = {
+    aux(secret.toList,word.toList,pool(secret,word))
+}
 
 
 // score("chess", "caves") // => List(Correct, Absent, Absent, Present, Correct)
@@ -74,31 +105,38 @@
 // score("chess", "eexss") // => List(Present, Absent, Absent, Correct, Correct)
 
 // (4)
-def eval(t: Tip) : Int = t match {
-    case Correct => 10
-    case Present => 1
-    case Absent => 0
+def eval(t: Tip) : Int = {
+    if (t == Correct) 10
+    else if (t == Present) 1
+    else 0
 }
 
-def iscore(secret: String, word: String) : Int = 
-  score(secret, word).map(eval).sum
+def iscore(secret: String, word: String) : Int = {
+    val scoreList = score(secret,word)
+    scoreList.map(x =>(eval(x))).toList.sum
+}
 
 //iscore("chess", "caves") // => 21
 //iscore("chess", "swiss") // => 20
 
 // (5)
-def lowest(secrets: List[String], word: String, current: Int, acc: List[String]) : List[String] = secrets match {
-    case Nil => acc
-    case s::srest => {
-        val nscore = iscore(s, word)
-        if (nscore < current) lowest(srest, word, nscore, List(s)) 
-        else if (nscore == current) lowest(srest, word, current, s::acc)
-        else  lowest(srest, word, current, acc)
+def lowest(secrets: List[String], word: String, current: Int, acc: List[String]) : List[String] = {
+    if(secrets.isEmpty) acc
+    else if (iscore(secrets.head,word)<current){
+        lowest(secrets.tail, word, iscore(secrets.head,word), List(secrets.head))
     }
+    else if (iscore(secrets.head,word)==current){
+        lowest(secrets.tail, word, current, acc :+ secrets.head)
+    }
+    else {
+        lowest(secrets.tail, word, current, acc)
+    }
+
 }
 
-def evil(secrets: List[String], word: String) = 
-  lowest(secrets, word, Int.MaxValue, Nil)
+def evil(secrets: List[String], word: String) = {
+    lowest(secrets, word, 100, List())
+}
 
 
 //evil(secrets, "stent").length
@@ -109,20 +147,21 @@
 
 // (6)
 def frequencies(secrets: List[String]) : Map[Char, Double] = {
-    val all = secrets.flatten
-    all.groupBy(identity).view.mapValues(1.0D - _.size.toDouble / all.size ).toMap
+    val totalChar = secrets.flatMap(_.toList).size.toDouble
+    val freqMap = secrets.flatMap(_.toList).groupBy(identity)
+    freqMap.map(x => (x._1, (1-(x._2.size.toDouble/ totalChar))))
+
 }
 
 // (7)
 def rank(frqs: Map[Char, Double], s: String) = {
-    s.map(frqs(_)).sum
+    s.map(x => (frqs(x))).toList.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 ranked_evil(secrets: List[String], word: String) : List[String]= {
+    val evilWords = evil(secrets,word)
+    val returnVal = evilWords.map(x => (x, rank(frequencies(secrets),x))).toMap.maxBy(_._2)._1
+    List(returnVal)
 }