out of 100 points, 110 points hard cap
In this project, you will decrypt simple but uncommon cipher, which encodes a secret message in seemingly normal text. Given the encrypted message, the most frequent character of each line is a character of the original message. Each message will be preceded by a number on its own line, telling you how many lines are in the input.
Let’s look at the following text:
7
Unlike you I take umbrage with gnu!
To think and code well tantalizes the mind.
birds fly together and chirp.
George Orwell was wrong about 1984.
Can your cat code?
Kick the kilos.
snakes sneakily slither.
AAAaaaaAaaAaAAaaaaaaa!!!!!!
For this text, the output would be
u 4
t 5
r 3
o 4
c 3
k 3
s 4
Note that the last line is discarded because the initial line indicated that we should only use seven lines of input.
Description #
Your program should read text from the standard input. For each line read, you should print out the most frequent character and its frequency to standard output. All characters should be printed out in lowercase. Here are additional rules to (hopefully) keep things simple:
- Uppercase and lowercase characters are treated as the same, that is, “O” and “o” both contribute to the count of the letter “o”.
- You may ignore punctuation and whitespace
- If a line has no counted characters on it (e.g. is all punctuation or whitespace), ignore it and move on to the next one.
- Ties should be resolved by picking the lowest valued ASCII character.
Direction and Hints #
Reading Input #
Before you start to code the main logic, first make sure you are able to get
the input task working. Your first step should be to get your program to read
the input. There are many ways to read text in C++, but the simplest approach
for this program uses std::getline:
std::string line;
while (std::getline(std::cin, line)){
// process the line
}
std::getline reads a single line from std::cin (standard input) until there is
no more input, at which point it will return false and the loop will
terminate. The variable line holds the contents of the current line inside
the loop body.
The std::string class
has a lot of functions to access the characters, so read the documentation,
talk to your peers, and ask questions on Piazza, in class, and at office hours!
Counting Letter Frequency #
You should write a function that takes a std::string and returns the
most frequent letter character, or some special character if the line is blank
or only has non-letters. You may find the following functions useful:
std::isalpha and
std::tolower. You
can write a separate function that takes a std::string and a character,
and returns the number of times the character appears in the line.
Testing #
When testing in interactive mode, your code may print one result for every line you enter. This can be a little hard to read. Instead, I suggest you pass your test case as a single block to echo, then pipe it to your test executable. For example,
echo "Let's get down to business
To defeat the Huns" | myprogram
This will make it easier to view your output, and is how your executable will be tested when actually grading.
A Note About std::string and const char*
#
Due to compatibility reasons dating all the way back to the 1970’s (no really!),
C++ has two different string types: the std::string and the char *
(sometimes shown as a char[] or a const char*)1.
While we won’t dive too much into the details in this class, in modern C++, it’s
considered good style to work with std::string as much as possible.
If you find that you have one of the following types:
const char*char[]char*
and would like to convert it into an std::string, you can wrap it in a
constructor call, e.g. std::string my_str(my_char_arr).
Conversely, if you have an std::string and need to convert it into a
char* for use with older library functions, use the c_str() method of
std::string, e.g. char* my_char_ptr = my_str.c_str().
Submission And Grading #
Make sure to read the general project grading rules.
For this project, you will need to submit two files: a cpp file and a README. In future projects, there will be skeleton code provided–for those, you will just submit your modifications to the skeleton code.
C++ File #
The C++ file, as with all our projects, must compile with no warnings. Since warnings and errors vary between compilers and OSses, I will be using the basement lab computers to compile your code. The following command will be used on the basement computers:
clang++ --std=c++11 -Wall -Wextra -Werror -o project0 project0.cpp
If you code does not compile, you may receive zero points for this assignment.
README File #
The README should include the following information:
- Your name
- Your EID
- The number of slip days you’re using on this project
- The number of slip days you’ve used in the course so far
- Any stretch goals you attempted, and how to enable them in your code
Other Notes About Grading #
You should submit a single tarball called project0.tar.gz which contains a
folder inside called project0. Inside project0 should be a single source
file called project0.cpp and your README.
I should be able to do the following in an automated manner:
tar -xf project0.tar.gz
cd project0
clang++ --std=c++11 -Wall -Wextra -Werror -o project0 project0.cpp
./project0
<test input>
If you have any questions about the assignment, please ask on Piazza.
Stretch Objectives #
If you finish the project early and have time to burn, you might consider trying one of these stretch goals. They will give you small amounts of bonus points, capped at 10 points (that is, even if you do everything perfectly, you cannot possibly get more than 110/100 on this project).
Fair warning: these stretch goals are not easy, and are more designed so that those of you who want to learn a little more about the weird fringes of C++ can cut your teeth. You will get many more points from implementing the main project well and testing it thoroughly than you will get from these bonuses.
If you attempt these, you must make sure your code still compiles on the lab machines and does not interfere with the correctness of the results. For this project ONLY, you may make several different source files. Make sure to leave a comment in the README telling me how to build/run your stretch code.
Finally, note that stretch goals are here so that you can, if you so choose, explore more advanced programming/CS concepts. If you look at a stretch and think that it looks cool, but you’re not entirely sure how to get started, come talk to me! I can give you some hints and/or modify the stretch slightly to suit your goals.
Stretch A: iostream not included (4pts)
#
Rewrite your program so that you do not include iostream. There are several
ways to accomplish this–the most common is to use stdio.h and
printf/fgets, but there are other ways to do it as well.
Stretch B: Look Ma, No Loops! (10pts) #
Rewrite your program without using loop constructs or recursion. To be clear: you may call standard library functions that use loops or recursion, but the loop statements or recursive functions may not appear in your code.
Note that to achieve this, you may find it helpful to write a lot of helper functions that aggregate work. In addition, the <algorithm> functions will be invaluable to you.
It may help for this Stretch if you use the C++14 standard for lambda function
support. If you opt do this, you must note it in the README.
-
This is an utter lie: C++ has a bajillion string types, including
std::string,char*,wchar_t*,char16_t *,char32_t *, and at least one implementation ofTwine. However, in most code that deals with ASCII,char*andstd::stringare the standard, and we will stick to these two string types for this class. ↩︎