@@ -33,10 +33,12 @@ object Anagrams extends AnagramsInterface {
33
33
*
34
34
* Note: you must use `groupBy` to implement this method!
35
35
*/
36
- def wordOccurrences (w : Word ): Occurrences = ???
36
+ def wordOccurrences (w : Word ): Occurrences =
37
+ w.toLowerCase.toSeq.groupBy(identity).map({case (c, l) => (c, l.length)}).toList.sorted
38
+
37
39
38
40
/** Converts a sentence into its character occurrence list. */
39
- def sentenceOccurrences (s : Sentence ): Occurrences = ???
41
+ def sentenceOccurrences (s : Sentence ): Occurrences = wordOccurrences(s.mkString)
40
42
41
43
/** The `dictionaryByOccurrences` is a `Map` from different occurrences to a sequence of all
42
44
* the words that have that occurrence count.
@@ -53,10 +55,12 @@ object Anagrams extends AnagramsInterface {
53
55
* List(('a', 1), ('e', 1), ('t', 1)) -> Seq("ate", "eat", "tea")
54
56
*
55
57
*/
56
- lazy val dictionaryByOccurrences : Map [Occurrences , List [Word ]] = ???
58
+ lazy val dictionaryByOccurrences : Map [Occurrences , List [Word ]] =
59
+ dictionary.groupBy(w => wordOccurrences(w))
57
60
58
61
/** Returns all the anagrams of a given word. */
59
- def wordAnagrams (word : Word ): List [Word ] = ???
62
+ def wordAnagrams (word : Word ): List [Word ] =
63
+ dictionaryByOccurrences(wordOccurrences(word))
60
64
61
65
/** Returns the list of all subsets of the occurrence list.
62
66
* This includes the occurrence itself, i.e. `List(('k', 1), ('o', 1))`
@@ -80,7 +84,14 @@ object Anagrams extends AnagramsInterface {
80
84
* Note that the order of the occurrence list subsets does not matter -- the subsets
81
85
* in the example above could have been displayed in some other order.
82
86
*/
83
- def combinations (occurrences : Occurrences ): List [Occurrences ] = ???
87
+ def combinations (occurrences : Occurrences ): List [Occurrences ] = occurrences match {
88
+ case Nil => List (List ())
89
+ case (c, n):: os =>
90
+ for (
91
+ i <- (0 to n).toList;
92
+ ot <- combinations(os)
93
+ ) yield if (i == 0 ) ot else (c, i):: ot
94
+ }
84
95
85
96
/** Subtracts occurrence list `y` from occurrence list `x`.
86
97
*
@@ -92,7 +103,14 @@ object Anagrams extends AnagramsInterface {
92
103
* Note: the resulting value is an occurrence - meaning it is sorted
93
104
* and has no zero-entries.
94
105
*/
95
- def subtract (x : Occurrences , y : Occurrences ): Occurrences = ???
106
+ def subtract (x : Occurrences , y : Occurrences ): Occurrences = (x, y) match {
107
+ case (Nil , _) => Nil
108
+ case (_, Nil ) => x
109
+ case ((x1, m):: xs, (y1, n):: ys) =>
110
+ if (x1 == y1) (if (m <= n) subtract(xs, ys) else (x1, m - n):: subtract(xs, ys))
111
+ else if (x1 < y1) (x1, m):: subtract(xs, y)
112
+ else subtract(x, ys)
113
+ }
96
114
97
115
/** Returns a list of all anagram sentences of the given sentence.
98
116
*
@@ -134,7 +152,19 @@ object Anagrams extends AnagramsInterface {
134
152
*
135
153
* Note: There is only one anagram of an empty sentence.
136
154
*/
137
- def sentenceAnagrams (sentence : Sentence ): List [Sentence ] = ???
155
+ def sentenceAnagrams (sentence : Sentence ): List [Sentence ] =
156
+ {
157
+ val occurrences = sentenceOccurrences(sentence)
158
+ def anagrams (occurrences : Occurrences ): List [Sentence ] =
159
+ if (occurrences == Nil ) List (Nil )
160
+ else for (
161
+ occurrence <- combinations(occurrences) if dictionaryByOccurrences.contains(occurrence);
162
+ word <- dictionaryByOccurrences(occurrence);
163
+ sentence <- anagrams(subtract(occurrences, occurrence))
164
+ ) yield word :: sentence
165
+
166
+ anagrams(occurrences)
167
+ }
138
168
}
139
169
140
170
object Dictionary {
0 commit comments