author | Christian Urban <christian.urban@kcl.ac.uk> |
Sat, 11 Mar 2023 22:01:53 +0000 | |
changeset 463 | 0315d9983cd0 |
parent 439 | 97594b9998a8 |
child 475 | 59e005dcf163 |
permissions | -rw-r--r-- |
439 | 1 |
// Main Part 3 about Evil Wordle |
2 |
//=============================== |
|
435
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
3 |
|
439 | 4 |
|
5 |
object M2 { |
|
435
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
6 |
|
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
7 |
import io.Source |
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
8 |
import scala.util._ |
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
9 |
|
439 | 10 |
// ADD YOUR CODE BELOW |
11 |
//====================== |
|
463 | 12 |
// def main(args: Array[String]): Unit = { |
435
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
13 |
|
463 | 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 |
// } |
|
439 | 26 |
|
27 |
//(1) |
|
435
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
28 |
def get_wordle_list(url: String) : List[String] = { |
463 | 29 |
try { |
30 |
Source.fromURL(url).getLines.toList; |
|
31 |
} |
|
32 |
catch { |
|
33 |
case _ : Throwable => List(); |
|
34 |
} |
|
435
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
35 |
} |
fda7c39f3b6a
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") |
439 | 37 |
// secrets.length // => 12972 |
38 |
// secrets.filter(_.length != 5) // => Nil |
|
435
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
39 |
|
439 | 40 |
//(2) |
41 |
def removeN[A](xs: List[A], elem: A, n: Int) : List[A] = { |
|
463 | 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 |
} |
|
435
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
50 |
|
439 | 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) |
|
435
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
55 |
|
439 | 56 |
// (3) |
435
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
57 |
abstract class Tip |
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
58 |
case object Absent extends Tip |
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
59 |
case object Present extends Tip |
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
60 |
case object Correct extends Tip |
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
61 |
|
439 | 62 |
|
63 |
def pool(secret: String, word: String) : List[Char] = { |
|
463 | 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 |
|
435
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
70 |
} |
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
71 |
|
463 | 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) |
|
435
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
94 |
} |
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
95 |
} |
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
96 |
|
463 | 97 |
def score(secret: String, word: String) : List[Tip] = { |
98 |
aux(secret.toList,word.toList,pool(secret,word)) |
|
99 |
} |
|
435
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
100 |
|
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
101 |
|
439 | 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) |
|
435
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
106 |
|
439 | 107 |
// (4) |
463 | 108 |
def eval(t: Tip) : Int = { |
109 |
if (t == Correct) 10 |
|
110 |
else if (t == Present) 1 |
|
111 |
else 0 |
|
435
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
112 |
} |
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
113 |
|
463 | 114 |
def iscore(secret: String, word: String) : Int = { |
115 |
val scoreList = score(secret,word) |
|
116 |
scoreList.map(x =>(eval(x))).toList.sum |
|
117 |
} |
|
439 | 118 |
|
119 |
//iscore("chess", "caves") // => 21 |
|
120 |
//iscore("chess", "swiss") // => 20 |
|
121 |
||
122 |
// (5) |
|
463 | 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)) |
|
439 | 127 |
} |
463 | 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 |
||
435
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
135 |
} |
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
136 |
|
463 | 137 |
def evil(secrets: List[String], word: String) = { |
138 |
lowest(secrets, word, 100, List()) |
|
139 |
} |
|
435
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
140 |
|
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
141 |
|
439 | 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 |
|
435
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
147 |
|
439 | 148 |
// (6) |
435
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
149 |
def frequencies(secrets: List[String]) : Map[Char, Double] = { |
463 | 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 |
||
435
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
154 |
} |
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
155 |
|
439 | 156 |
// (7) |
435
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
157 |
def rank(frqs: Map[Char, Double], s: String) = { |
463 | 158 |
s.map(x => (frqs(x))).toList.sum |
435
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
159 |
} |
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
160 |
|
463 | 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) |
|
435
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
165 |
} |
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
166 |
|
439 | 167 |
|
435
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
168 |
} |
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
169 |
|
439 | 170 |
|
171 |
||
172 |
||
173 |
||
435
fda7c39f3b6a
updated wordle testing
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff
changeset
|
174 |
|
439 | 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. |