We have acquired some Dance Dance Revolution software that will display on a screen the sequence of arrows for a dance. The software requires as input a string of characters; each character is an instruction for what to display for one beat of the song. The characters are:
A full Dance Dance Revolution system has dances requiring a player to step on two different arrows at the same time (using both feet), and requiring several steps per beat (corresponding to eighth and sixteenth notes). For this project, we will assume something simpler: All dances require stepping on at most one arrow per beat. A step is either a tap, where the player steps on the arrow and then lifts the foot on the same beat, or a freeze, where the player steps on the arrow on one beat, and then keeps it there, lifting it off at a later beat.
Now for the bad news: The artists who design the dances are used to expressing them a different way. For them, a dance is expressed as a string like u//d/3r///d/, where a slash terminates every beat. This means "For the first beat, tap up. Nothing is required for the second beat. For the third beat, tap down. Starting on the fourth beat, freeze on the right arrow for three beats (the fourth, fifth, and sixth). For the seventh beat, tap down."
* l, d, u, or r, meaning to display an arrow indicating that the dancer should tap the left, down, up, or right arrow on the dance pad.
* L, D, U, or R, meaning to display an symbol indicating that the dancer should freeze a foot on the left, down, up, or right arrow on the dance pad.
* x, meaning to display nothing for this beat, indicating that the dancer is not required to step anywhere for this beat.
A well-formed dance is a sequence of zero or more beats. Here are some examples of well-formed dances:
* zero beats
* /// three beats
Your task ...
For this project, you will implement the following two functions, using the exact function names, parameters types, and return types shown in this specification. (The parameter names may be different if you wish.)
bool isDanceWellFormed(string dance)
This function returns true if its parameter is a well-formed dance, and false otherwise.
int translateDance(string dance, string& instructions, int& badBeat)
If the parameter dance is translatable, the function sets instructions to the translation of the dance, leaves badBeat unchanged, and returns 0. In all other cases, the function leaves instructions unchanged. If dance is not well-formed, the function leaves badBeat unchanged and returns 1. If dance is well-formed but while a freeze is in effect, a beat not consisting of only a slash is present, badBeat is set to the number of that beat (where the first beat of the whole dance is number 1, etc.), and the function returns 2. If dance is well-formed but ends prematurely, badBeat is set to one more than the number of beats in the string, and the function returns 3. If dance is well-formed but a beat specifies a freeze of length less than 2, badBeat is set to the number of that beat, and the function returns 4. If the dance is well-formed but not translatable for more than one reason, report the leftmost occuring problem. (For example, if dance is 3r//u/0d//2u/, set badBeat to 3 and return 2.)
These are the only two functions you are required to write. (Hint: translateDance may well call isDanceWellFormed.) Your solution may use functions in addition to these three. While we won't test those additional functions separately, their use may help you structure your program more readably. Of course, to test them, you'll want to write a main routine that calls your functions. During the course of developing your solution, you might change that main routine many times. As long as your main routine compiles correctly when you turn in your solution, it doesn't matter what it does, since we will rename it to something harmless and never call it (because we will supply our own main routine to throroughly test your functions).
Your functions must not use any global variables.
When you turn in your solution, neither of the two required functions, nor any functions they call, may write any output to cout. (Of course, during development, you may have them write whatever you like to help you debug.) If you want to print things out for debugging purposes, write to cerr instead of cout. cerr is the standard error destination; items written to it by default go to the screen. When we test your program, we will cause everything written to cerr to be discarded instead -- we will never see that output, so you may leave those debugging output statements in your program if you wish.