mirror of
https://github.com/jlengrand/FunctionalProgrammingScalaCoursera.git
synced 2026-03-10 08:21:22 +00:00
I don't understand what I've been doing. Enough for today
This commit is contained in:
@@ -10,146 +10,153 @@ object Anagrams {
|
|||||||
type Sentence = List[Word]
|
type Sentence = List[Word]
|
||||||
|
|
||||||
/** `Occurrences` is a `List` of pairs of characters and positive integers saying
|
/** `Occurrences` is a `List` of pairs of characters and positive integers saying
|
||||||
* how often the character appears.
|
* how often the character appears.
|
||||||
* This list is sorted alphabetically w.r.t. to the character in each pair.
|
* This list is sorted alphabetically w.r.t. to the character in each pair.
|
||||||
* All characters in the occurrence list are lowercase.
|
* All characters in the occurrence list are lowercase.
|
||||||
*
|
*
|
||||||
* Any list of pairs of lowercase characters and their frequency which is not sorted
|
* Any list of pairs of lowercase characters and their frequency which is not sorted
|
||||||
* is **not** an occurrence list.
|
* is **not** an occurrence list.
|
||||||
*
|
*
|
||||||
* Note: If the frequency of some character is zero, then that character should not be
|
* Note: If the frequency of some character is zero, then that character should not be
|
||||||
* in the list.
|
* in the list.
|
||||||
*/
|
*/
|
||||||
type Occurrences = List[(Char, Int)]
|
type Occurrences = List[(Char, Int)]
|
||||||
|
|
||||||
/** The dictionary is simply a sequence of words.
|
/** The dictionary is simply a sequence of words.
|
||||||
* It is predefined and obtained as a sequence using the utility method `loadDictionary`.
|
* It is predefined and obtained as a sequence using the utility method `loadDictionary`.
|
||||||
*/
|
*/
|
||||||
val dictionary: List[Word] = loadDictionary
|
val dictionary: List[Word] = loadDictionary
|
||||||
|
|
||||||
/** Converts the word into its character occurrence list.
|
/** Converts the word into its character occurrence list.
|
||||||
*
|
*
|
||||||
* Note: the uppercase and lowercase version of the character are treated as the
|
* Note: the uppercase and lowercase version of the character are treated as the
|
||||||
* same character, and are represented as a lowercase character in the occurrence list.
|
* same character, and are represented as a lowercase character in the occurrence list.
|
||||||
*
|
*
|
||||||
* Note: you must use `groupBy` to implement this method!
|
* Note: you must use `groupBy` to implement this method!
|
||||||
*/
|
*/
|
||||||
def wordOccurrences(w: Word): Occurrences = w.toLowerCase().groupBy(c => c).map{ case(k, v) => (k, v.length)}.toList.sorted
|
def wordOccurrences(w: Word): Occurrences = w.toLowerCase().groupBy(c => c).map { case (k, v) => (k, v.length) }.toList.sorted
|
||||||
|
|
||||||
/** Converts a sentence into its character occurrence list. */
|
/** Converts a sentence into its character occurrence list. */
|
||||||
def sentenceOccurrences(s: Sentence): Occurrences = wordOccurrences(s.reduceLeft((x, y) => x +y ))
|
// def sentenceOccurrences(s: Sentence): Occurrences = wordOccurrences(s.reduceLeft((x, y) => x + y))
|
||||||
|
def sentenceOccurrences(s: Sentence): Occurrences = wordOccurrences(s.mkString)
|
||||||
|
|
||||||
/** The `dictionaryByOccurrences` is a `Map` from different occurrences to a sequence of all
|
/** The `dictionaryByOccurrences` is a `Map` from different occurrences to a sequence of all
|
||||||
* the words that have that occurrence count.
|
* the words that have that occurrence count.
|
||||||
* This map serves as an easy way to obtain all the anagrams of a word given its occurrence list.
|
* This map serves as an easy way to obtain all the anagrams of a word given its occurrence list.
|
||||||
*
|
*
|
||||||
* For example, the word "eat" has the following character occurrence list:
|
* For example, the word "eat" has the following character occurrence list:
|
||||||
*
|
*
|
||||||
* `List(('a', 1), ('e', 1), ('t', 1))`
|
* `List(('a', 1), ('e', 1), ('t', 1))`
|
||||||
*
|
*
|
||||||
* Incidentally, so do the words "ate" and "tea".
|
* Incidentally, so do the words "ate" and "tea".
|
||||||
*
|
*
|
||||||
* This means that the `dictionaryByOccurrences` map will contain an entry:
|
* This means that the `dictionaryByOccurrences` map will contain an entry:
|
||||||
*
|
*
|
||||||
* List(('a', 1), ('e', 1), ('t', 1)) -> Seq("ate", "eat", "tea")
|
* List(('a', 1), ('e', 1), ('t', 1)) -> Seq("ate", "eat", "tea")
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
lazy val dictionaryByOccurrences: Map[Occurrences, List[Word]] = dictionary.groupBy(w => wordOccurrences(w))
|
lazy val dictionaryByOccurrences: Map[Occurrences, List[Word]] = dictionary.groupBy(w => wordOccurrences(w))
|
||||||
|
|
||||||
/** Returns all the anagrams of a given word. */
|
/** Returns all the anagrams of a given word. */
|
||||||
def wordAnagrams(word: Word): List[Word] = dictionaryByOccurrences(wordOccurrences(word))
|
def wordAnagrams(word: Word): List[Word] = dictionaryByOccurrences(wordOccurrences(word))
|
||||||
|
|
||||||
/** Returns the list of all subsets of the occurrence list.
|
/** Returns the list of all subsets of the occurrence list.
|
||||||
* This includes the occurrence itself, i.e. `List(('k', 1), ('o', 1))`
|
* This includes the occurrence itself, i.e. `List(('k', 1), ('o', 1))`
|
||||||
* is a subset of `List(('k', 1), ('o', 1))`.
|
* is a subset of `List(('k', 1), ('o', 1))`.
|
||||||
* It also include the empty subset `List()`.
|
* It also include the empty subset `List()`.
|
||||||
*
|
*
|
||||||
* Example: the subsets of the occurrence list `List(('a', 2), ('b', 2))` are:
|
* Example: the subsets of the occurrence list `List(('a', 2), ('b', 2))` are:
|
||||||
*
|
*
|
||||||
* List(
|
* List(
|
||||||
* List(),
|
* List(),
|
||||||
* List(('a', 1)),
|
* List(('a', 1)),
|
||||||
* List(('a', 2)),
|
* List(('a', 2)),
|
||||||
* List(('b', 1)),
|
* List(('b', 1)),
|
||||||
* List(('a', 1), ('b', 1)),
|
* List(('a', 1), ('b', 1)),
|
||||||
* List(('a', 2), ('b', 1)),
|
* List(('a', 2), ('b', 1)),
|
||||||
* List(('b', 2)),
|
* List(('b', 2)),
|
||||||
* List(('a', 1), ('b', 2)),
|
* List(('a', 1), ('b', 2)),
|
||||||
* List(('a', 2), ('b', 2))
|
* List(('a', 2), ('b', 2))
|
||||||
* )
|
* )
|
||||||
*
|
*
|
||||||
* Note that the order of the occurrence list subsets does not matter -- the subsets
|
* Note that the order of the occurrence list subsets does not matter -- the subsets
|
||||||
* in the example above could have been displayed in some other order.
|
* in the example above could have been displayed in some other order.
|
||||||
*/
|
*/
|
||||||
def combinations(occurrences: Occurrences): List[Occurrences] = {
|
def combinations(occurrences: Occurrences): List[Occurrences] = {
|
||||||
def op(e1: List[(Char, Int)], e2: List[Occurrences] ): List[Occurrences] = {
|
def op(e1: List[(Char, Int)], e2: List[Occurrences]): List[Occurrences] = {
|
||||||
e2 :::
|
e2 :::
|
||||||
(for{
|
(for {
|
||||||
i <- e1
|
i <- e1
|
||||||
j <- e2
|
j <- e2
|
||||||
} yield (i :: j))
|
} yield (i :: j))
|
||||||
}
|
}
|
||||||
|
|
||||||
val subsets = (occurrences.map( x => (
|
val subsets = (occurrences.map(x => (
|
||||||
for(
|
for (
|
||||||
i <- 1 until (x._2+1)
|
i <- 1 until (x._2 + 1)
|
||||||
)
|
)
|
||||||
yield (x._1,i)).toList))
|
yield (x._1, i)).toList))
|
||||||
subsets.foldRight(List[Occurrences](Nil))(op)
|
subsets.foldRight(List[Occurrences](Nil))(op)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Subtracts occurrence list `y` from occurrence list `x`.
|
/** Subtracts occurrence list `y` from occurrence list `x`.
|
||||||
*
|
*
|
||||||
* The precondition is that the occurrence list `y` is a subset of
|
* The precondition is that the occurrence list `y` is a subset of
|
||||||
* the occurrence list `x` -- any character appearing in `y` must
|
* the occurrence list `x` -- any character appearing in `y` must
|
||||||
* appear in `x`, and its frequency in `y` must be smaller or equal
|
* appear in `x`, and its frequency in `y` must be smaller or equal
|
||||||
* than its frequency in `x`.
|
* than its frequency in `x`.
|
||||||
*
|
*
|
||||||
* Note: the resulting value is an occurrence - meaning it is sorted
|
* Note: the resulting value is an occurrence - meaning it is sorted
|
||||||
* and has no zero-entries.
|
* and has no zero-entries.
|
||||||
*/
|
*/
|
||||||
def subtract(x: Occurrences, y: Occurrences): Occurrences = ???
|
def subtract(x: Occurrences, y: Occurrences): Occurrences = {
|
||||||
|
y.toMap.foldLeft(x.toMap) {
|
||||||
|
(acc, el) => acc.updated(el._1, acc(el._1) - el._2)
|
||||||
|
}.filter(_._2 > 0).toList
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns a list of all anagram sentences of the given sentence.
|
/** Returns a list of all anagram sentences of the given sentence.
|
||||||
*
|
*
|
||||||
* An anagram of a sentence is formed by taking the occurrences of all the characters of
|
* An anagram of a sentence is formed by taking the occurrences of all the characters of
|
||||||
* all the words in the sentence, and producing all possible combinations of words with those characters,
|
* all the words in the sentence, and producing all possible combinations of words with those characters,
|
||||||
* such that the words have to be from the dictionary.
|
* such that the words have to be from the dictionary.
|
||||||
*
|
*
|
||||||
* The number of words in the sentence and its anagrams does not have to correspond.
|
* The number of words in the sentence and its anagrams does not have to correspond.
|
||||||
* For example, the sentence `List("I", "love", "you")` is an anagram of the sentence `List("You", "olive")`.
|
* For example, the sentence `List("I", "love", "you")` is an anagram of the sentence `List("You", "olive")`.
|
||||||
*
|
*
|
||||||
* Also, two sentences with the same words but in a different order are considered two different anagrams.
|
* Also, two sentences with the same words but in a different order are considered two different anagrams.
|
||||||
* For example, sentences `List("You", "olive")` and `List("olive", "you")` are different anagrams of
|
* For example, sentences `List("You", "olive")` and `List("olive", "you")` are different anagrams of
|
||||||
* `List("I", "love", "you")`.
|
* `List("I", "love", "you")`.
|
||||||
*
|
*
|
||||||
* Here is a full example of a sentence `List("Yes", "man")` and its anagrams for our dictionary:
|
* Here is a full example of a sentence `List("Yes", "man")` and its anagrams for our dictionary:
|
||||||
*
|
*
|
||||||
* List(
|
* List(
|
||||||
* List(en, as, my),
|
* List(en, as, my),
|
||||||
* List(en, my, as),
|
* List(en, my, as),
|
||||||
* List(man, yes),
|
* List(man, yes),
|
||||||
* List(men, say),
|
* List(men, say),
|
||||||
* List(as, en, my),
|
* List(as, en, my),
|
||||||
* List(as, my, en),
|
* List(as, my, en),
|
||||||
* List(sane, my),
|
* List(sane, my),
|
||||||
* List(Sean, my),
|
* List(Sean, my),
|
||||||
* List(my, en, as),
|
* List(my, en, as),
|
||||||
* List(my, as, en),
|
* List(my, as, en),
|
||||||
* List(my, sane),
|
* List(my, sane),
|
||||||
* List(my, Sean),
|
* List(my, Sean),
|
||||||
* List(say, men),
|
* List(say, men),
|
||||||
* List(yes, man)
|
* List(yes, man)
|
||||||
* )
|
* )
|
||||||
*
|
*
|
||||||
* The different sentences do not have to be output in the order shown above - any order is fine as long as
|
* The different sentences do not have to be output in the order shown above - any order is fine as long as
|
||||||
* all the anagrams are there. Every returned word has to exist in the dictionary.
|
* all the anagrams are there. Every returned word has to exist in the dictionary.
|
||||||
*
|
*
|
||||||
* Note: in case that the words of the sentence are in the dictionary, then the sentence is the anagram of itself,
|
* Note: in case that the words of the sentence are in the dictionary, then the sentence is the anagram of itself,
|
||||||
* so it has to be returned in this list.
|
* so it has to be returned in this list.
|
||||||
*
|
*
|
||||||
* Note: There is only one anagram of an empty sentence.
|
* Note: There is only one anagram of an empty sentence.
|
||||||
*/
|
*/
|
||||||
def sentenceAnagrams(sentence: Sentence): List[Sentence] = ???
|
def sentenceAnagrams(sentence: Sentence): List[Sentence] = {
|
||||||
|
List(List())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user