CSE 232 Spring 2015 Programming Project #06 Assignment
Transcription
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.