| author | Christian Urban <christian.urban@kcl.ac.uk> | 
| Sat, 11 Mar 2023 23:22:05 +0000 | |
| changeset 465 | 3c5a3166b091 | 
| parent 460 | f5c0749858fd | 
| child 472 | fbff6f601370 | 
| permissions | -rw-r--r-- | 
| 436 | 1  | 
// Main Part 3 about Evil Wordle  | 
2  | 
//===============================  | 
|
| 
432
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
3  | 
|
| 436 | 4  | 
|
5  | 
object M2 { 
 | 
|
| 
432
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
6  | 
|
| 
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
7  | 
import io.Source  | 
| 
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
8  | 
import scala.util._  | 
| 
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
9  | 
|
| 436 | 10  | 
// ADD YOUR CODE BELOW  | 
11  | 
//======================  | 
|
| 460 | 12  | 
// def main(args: Array[String]): Unit = {
 | 
| 
432
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
13  | 
|
| 460 | 14  | 
//     val secrets = get_wordle_list("https://nms.kcl.ac.uk/christian.urban/wordle.txt")
 | 
15  | 
//     println(ranked_evil(secrets, "beats")== List("fuzzy"))
 | 
|
16  | 
//     println(ranked_evil(secrets, "vitae") == List("fuzzy"))
 | 
|
17  | 
//     println(ranked_evil(secrets, "bento") == List("fuzzy"))
 | 
|
18  | 
//     println(ranked_evil(secrets, "belts") == List("fuzzy"))
 | 
|
19  | 
//     println(ranked_evil(secrets, "abbey") == List("whizz"))
 | 
|
20  | 
//     println(ranked_evil(secrets, "afear") == List("buzzy"))
 | 
|
21  | 
//     println(ranked_evil(secrets, "zincy") == List("jugum"))
 | 
|
22  | 
//     println(ranked_evil(secrets, "zippy") == List("chuff"))
 | 
|
23  | 
||
24  | 
||
25  | 
// }  | 
|
| 436 | 26  | 
|
27  | 
//(1)  | 
|
| 
432
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
28  | 
def get_wordle_list(url: String) : List[String] = {
 | 
| 460 | 29  | 
    try {
 | 
30  | 
Source.fromURL(url).getLines.toList;  | 
|
31  | 
}  | 
|
32  | 
    catch {
 | 
|
33  | 
case _ : Throwable => List();  | 
|
34  | 
}  | 
|
| 
432
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
35  | 
}  | 
| 
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
36  | 
// val secrets = get_wordle_list("https://nms.kcl.ac.uk/christian.urban/wordle.txt")
 | 
| 436 | 37  | 
// secrets.length // => 12972  | 
38  | 
// secrets.filter(_.length != 5) // => Nil  | 
|
| 
432
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
39  | 
|
| 436 | 40  | 
//(2)  | 
41  | 
def removeN[A](xs: List[A], elem: A, n: Int) : List[A] = {
 | 
|
| 460 | 42  | 
    if (xs.isEmpty || n == 0 || !xs.contains(elem)){
 | 
43  | 
xs  | 
|
44  | 
}  | 
|
45  | 
    else{
 | 
|
46  | 
val (newLst,newLst2) = xs.splitAt(xs.indexOf(elem))  | 
|
47  | 
removeN(newLst ++ newLst2.tail,elem, n-1)  | 
|
48  | 
}  | 
|
49  | 
}  | 
|
| 
432
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
50  | 
|
| 436 | 51  | 
// removeN(List(1,2,3,2,1), 3, 1) // => List(1, 2, 2, 1)  | 
52  | 
// removeN(List(1,2,3,2,1), 2, 1) // => List(1, 3, 2, 1)  | 
|
53  | 
// removeN(List(1,2,3,2,1), 1, 1) // => List(2, 3, 2, 1)  | 
|
54  | 
// removeN(List(1,2,3,2,1), 0, 2) // => List(1, 2, 3, 2, 1)  | 
|
| 
432
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
55  | 
|
| 436 | 56  | 
// (3)  | 
| 
432
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
57  | 
abstract class Tip  | 
| 
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
58  | 
case object Absent extends Tip  | 
| 
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
59  | 
case object Present extends Tip  | 
| 
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
60  | 
case object Correct extends Tip  | 
| 
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
61  | 
|
| 436 | 62  | 
|
63  | 
def pool(secret: String, word: String) : List[Char] = {
 | 
|
| 460 | 64  | 
//print(secret.toList, word.toList)  | 
65  | 
    val lst= ((0 to 4).map(x => {
 | 
|
66  | 
if(!secret(x).equals(word(x))) Some(secret(x)) else None  | 
|
67  | 
||
68  | 
}).toList)  | 
|
69  | 
lst.flatten  | 
|
| 
432
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
70  | 
}  | 
| 
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
71  | 
|
| 460 | 72  | 
|
73  | 
def aux(secret: List[Char], word: List[Char], pool: List[Char]) : List[Tip] = {
 | 
|
74  | 
||
75  | 
    if (secret.length == 1){
 | 
|
76  | 
        if (secret.head == word.head){
 | 
|
77  | 
List(Correct)  | 
|
78  | 
}  | 
|
79  | 
        else if (pool.contains(word.head)){
 | 
|
80  | 
List(Present)  | 
|
81  | 
}  | 
|
82  | 
        else {
 | 
|
83  | 
List(Absent)  | 
|
84  | 
}  | 
|
85  | 
}  | 
|
86  | 
    else if (secret.head == word.head){
 | 
|
87  | 
List(Correct) ++ aux(secret.tail, word.tail, pool)  | 
|
88  | 
}  | 
|
89  | 
    else if (pool.contains(word.head)){
 | 
|
90  | 
List(Present) ++ aux(secret.tail, word.tail, removeN(pool, word.head, 1))  | 
|
91  | 
}  | 
|
92  | 
    else {
 | 
|
93  | 
List(Absent) ++ aux(secret.tail, word.tail, pool)  | 
|
| 
432
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
94  | 
}  | 
| 
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
95  | 
}  | 
| 
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
96  | 
|
| 460 | 97  | 
def score(secret: String, word: String) : List[Tip] = {
 | 
98  | 
aux(secret.toList,word.toList,pool(secret,word))  | 
|
99  | 
}  | 
|
| 
432
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
100  | 
|
| 
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
101  | 
|
| 436 | 102  | 
// score("chess", "caves") // => List(Correct, Absent, Absent, Present, Correct)
 | 
103  | 
// score("doses", "slide") // => List(Present, Absent, Absent, Present, Present)
 | 
|
104  | 
// score("chess", "swiss") // => List(Absent, Absent, Absent, Correct, Correct)
 | 
|
105  | 
// score("chess", "eexss") // => List(Present, Absent, Absent, Correct, Correct)
 | 
|
| 
432
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
106  | 
|
| 436 | 107  | 
// (4)  | 
| 460 | 108  | 
def eval(t: Tip) : Int = {
 | 
109  | 
if (t == Correct) 10  | 
|
110  | 
else if (t == Present) 1  | 
|
111  | 
else 0  | 
|
| 
432
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
112  | 
}  | 
| 
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
113  | 
|
| 460 | 114  | 
def iscore(secret: String, word: String) : Int = {
 | 
115  | 
val scoreList = score(secret,word)  | 
|
116  | 
scoreList.map(x =>(eval(x))).toList.sum  | 
|
117  | 
}  | 
|
| 436 | 118  | 
|
119  | 
//iscore("chess", "caves") // => 21
 | 
|
120  | 
//iscore("chess", "swiss") // => 20
 | 
|
121  | 
||
122  | 
// (5)  | 
|
| 460 | 123  | 
def lowest(secrets: List[String], word: String, current: Int, acc: List[String]) : List[String] = {
 | 
124  | 
if(secrets.isEmpty) acc  | 
|
125  | 
    else if (iscore(secrets.head,word)<current){
 | 
|
126  | 
lowest(secrets.tail, word, iscore(secrets.head,word), List(secrets.head))  | 
|
| 436 | 127  | 
}  | 
| 460 | 128  | 
    else if (iscore(secrets.head,word)==current){
 | 
129  | 
lowest(secrets.tail, word, current, acc :+ secrets.head)  | 
|
130  | 
}  | 
|
131  | 
    else {
 | 
|
132  | 
lowest(secrets.tail, word, current, acc)  | 
|
133  | 
}  | 
|
134  | 
||
| 
432
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
135  | 
}  | 
| 
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
136  | 
|
| 460 | 137  | 
def evil(secrets: List[String], word: String) = {
 | 
138  | 
lowest(secrets, word, 100, List())  | 
|
139  | 
}  | 
|
| 
432
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
140  | 
|
| 
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
141  | 
|
| 436 | 142  | 
//evil(secrets, "stent").length  | 
143  | 
//evil(secrets, "hexes").length  | 
|
144  | 
//evil(secrets, "horse").length  | 
|
145  | 
//evil(secrets, "hoise").length  | 
|
146  | 
//evil(secrets, "house").length  | 
|
| 
432
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
147  | 
|
| 436 | 148  | 
// (6)  | 
| 
432
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
149  | 
def frequencies(secrets: List[String]) : Map[Char, Double] = {
 | 
| 460 | 150  | 
val totalChar = secrets.flatMap(_.toList).size.toDouble  | 
151  | 
val freqMap = secrets.flatMap(_.toList).groupBy(identity)  | 
|
152  | 
freqMap.map(x => (x._1, (1-(x._2.size.toDouble/ totalChar))))  | 
|
153  | 
||
| 
432
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
154  | 
}  | 
| 
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
155  | 
|
| 436 | 156  | 
// (7)  | 
| 
432
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
157  | 
def rank(frqs: Map[Char, Double], s: String) = {
 | 
| 460 | 158  | 
s.map(x => (frqs(x))).toList.sum  | 
| 
432
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
159  | 
}  | 
| 
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
160  | 
|
| 460 | 161  | 
def ranked_evil(secrets: List[String], word: String) : List[String]= {
 | 
162  | 
val evilWords = evil(secrets,word)  | 
|
163  | 
val returnVal = evilWords.map(x => (x, rank(frequencies(secrets),x))).toMap.maxBy(_._2)._1  | 
|
164  | 
List(returnVal)  | 
|
| 
432
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
165  | 
}  | 
| 
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
166  | 
|
| 436 | 167  | 
|
| 
432
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
168  | 
}  | 
| 
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
169  | 
|
| 436 | 170  | 
|
171  | 
||
172  | 
||
173  | 
||
| 
432
 
87e487ccbd7c
updated wordle testing
 
Christian Urban <christian.urban@kcl.ac.uk> 
parents:  
diff
changeset
 | 
174  | 
|
| 436 | 175  | 
// This template code is subject to copyright  | 
176  | 
// by King's College London, 2022. Do not  | 
|
177  | 
// make the template code public in any shape  | 
|
178  | 
// or form, and do not exchange it with other  | 
|
179  | 
// students under any circumstance.  |