CSE 232 Spring 2015 Programming Project #06 Assignment

CSE 232
Spring 2015
Programming Project #06
Assignment Overview
In this assignment we will create a program that plays the Countdown game, a text manipulation game. This
assignment is worth 40 points (4.0% of the course grade) and must be completed and turned in before
11:59pm on Monday, March 2nd . In this assignment you will practice using STL maps, as well as more
experience with random numbers and vectors.
Background
Countdown is the first and longest-running TV game show in the world. The program consists of different
sections. For this game we will play our version of the "Letters Round".
http://en.wikipedia.org/wiki/Countdown_(game_show)#Format
Here's the basics of the Letter Round:
•
•
generate a random sequence of letters, consisting of some number of consonants and vowels
to try and make the longest, English word that is a combination of the letters from that random sequence.
For our part, we will fulfill both of those functions. You will generate a random sequence of letters and report
the largest, English word your program can make from those letters. If there is a tie on length, we want the
smallest alphabetically.
Example Game
Let's generate a random sequence of letters: "abdoopr". It is convenient to have them in sorted order. What are
some English words we can generate from this sequence? Quite a lot, especially if we use "words.txt" which has
some pretty strange words in it. Some words we would recognize however would be:
"boo", "boor", "door", "poor", "drab", "droop", "brood", "board", "broad".
In fact, a 5 letter word is the longest English word we can make from the sequence (given our words.txt), and the
smallest (alphabetically) would be "board". That would be our answer!
Anagram
The idea to doing this work is the concept of an anagram, a sequence of letters that can be re-arranged to make
an English word (http://en.wikipedia.org/wiki/Anagram) . Some examples:
•
•
•
covert, corvet, vector
canoes, oceans
apers, apres, asper, pares, parse, pears, rapes, reaps, spare, spear
How does one find anagrams? The key is that, if you sort the letters, that sorted letter sequence is exactly the
same for each anagram word. Observe:
•
•
•
(ceorvt): covert, corvet, vector
(acenos): canoes, oceans
(aeprs): apers, apres, asper, pares, parse, pears, rapes, reaps, spare, spear
So now think map/dictionary. One can make a map of the sorted sequence (the key) against a vector of all the
legal words (the value) that are a rearrangement, an anagram, of that sequence. The sorted sequence is unique
and therefore a great key!
Requirements
Data Structures
You must use a map<string, vector<string>> to encode the anagrams.
Functions
•
•
•
void setup(map<string, vector<string>> &m) : Takes in a map by reference and fills it. It
has the following steps:
o opens a file called words.txt which is provided.
§ Prompting for the name is not required. If words.txt is not found you should throw an error
with a "File not found" message.
§ This file consists of a single line, each with an English language word in lower case. The file
words are in alphabetically increasing order.
o sorts the letters of the word.
§ If the sorted key already exists in the map, it appends to the end of the value, a vector, the
new word.
§ If the sorted key does not yet exist, the key is added to the map and a vector created with the
new word as its only member.
o no return
string generate(int consonant_cnt, int vowel_cnt, long seed) : Takes in a
consonant count, a vowel count and a random number seed.
o you can assume both counts >= 0
o Generates a random letter sequence consisting of the required consonant and vowel counts.
§ vowels are limited to 'a', 'e', 'i', 'o' and 'u'.
o sorts the characters of the string
o returns the new, sorted string.
string longest_anagram(map<string, vector<string>> &m, string target) :
Takes in a filled map reference m (from setup) and a sorted string target (from generate) and finds
the longest combination of target characters that make a legal English word, if any.
o returns the longest word
§ if multiple words of the same length exist, the alphabetically smallest word is returned.
§ if no words can be found, returns the empty string.
Other Stuff
Feel free to create and use other functions as needed. They do not, however, go into the functions-06.h
file as they will be private, to be used somehow by the other functions. The only public functions, and therefore
the only functions used in main, are the listed functions.
Deliverables
- functions-06.cpp
* Your source code solution (remember to include your section, the date, project number and comments).
Remember, you do not provide main-06.cpp.
1. Please be sure to use the specified file names
2. Save a copy of your file in your CSE account disk space (H drive on CSE
computers).
3. You will electronically submit a copy of the file using the "handin" program:
http://www.cse.msu.edu/handin/webclient
Notes
•
•
•
•
the generic algorithm sort which is part of <algorithm> is very useful here
o it might be especially useful to sort on different criteria in the course of the program, for example
string length instead of alphabetical order.
the key algorithm work has to be done in longest_anagram. There are a couple of methods but I would
suggest the following
o make a pass through all the keys of the dictionary and store, in a vector, all the keys that could be
made from the target sequence. For this to be true:
§ all the letters of the key must be found in the target
§ for each common letter, the count of that letter in the key must be <= the count of that letter
in the target. For example, you could construct the word "barbara" from our sequence
"abdoopr" in that the letters "abr" occur in "abdoopr", but the counts have to be correct
as well since we need 3'a's, 2'b's and 2'r's. Thus "barbara" is in fact not correct.
§ using functions for this would be smart
o for the vector of keys, select the longest (or if there are multiple of the same length, all those keys)
o gather all the English words from the map using those longest keys
o sort those words alphabetically, the smallest is the answer
default_random_engine in g++ seems to be flawed. The first element in a
uniform_int_distribution is always the first element in the range. That sucks. Try a different
engine which does work in g++ the Mersenne twister ( http://en.wikipedia.org/wiki/Mersenne_twister ) with
the ridiculous c++11 name mt19937_64. As with default_random_engine, it is part of
<random.h> and takes a single argument, a seed. Look it up!
You are out of your mind if you don't write multiple mains that test each of the individual functions to make
sure they work
o in particular, don't start your work with words.txt. For example, you could look up some
anagrams (like http://www.english-for-students.com/Complete-List-of-Anagrams.html ) and put 10
or so in a beginner words.txt to make sure things work.
o test each function separately to check yourself
o put lots of extra cout statements in strategic places, especially in longest_anagram, to make
sure you are generating all the combinations.