(As of 2021, I have started to add Leetcode problems to the mix -- so, wherever you see "Topcoder", you can also substitute "Leetcode").
For each topcoder problem, I will give you a web link to one of my directories. For example, the first one that I will give you in lab is to the problem "FauxPalindromes". This was from SRM #564 (Topcoder tournaments are called "Single Round Matches" or SRMs). It was in Division two (there are two divisions, D1 for experts and D2 for novices), worth 250 points (typically there are three problems: 250, 500 and 1000 points).
Here's the link: http://web.eecs.utk.edu/~jplank/topcoder-writeups/2012/FauxPalindromes/index.html.
The web pages that I give you will have links to the description of the problem on Topcoder. You can try that link, but sometimes it doesn't work. I'll also have a section entitled "In Case Topcoder's Servers Are Down," which gives you a summary description of the problem, and then examples. Then, I have a few files to help you:
UNIX> ls -l total 40 -rw-r--r--@ 1 jplank staff 322 Aug 28 17:39 FauxPalindromes.cpp -rw-r--r--@ 1 jplank staff 947 Aug 28 17:39 answers.txt -rw-r--r--@ 1 jplank staff 965 Aug 28 17:39 main.cpp -rw-r--r--@ 1 jplank staff 5614 Aug 28 17:36 tests.sh UNIX> head -n 1 main.cpp #include "FauxPalindromes.cpp" UNIX>That is not something you normally want to do, but it is convenient here. If you compile main.cpp, it will include FauxPalindromes.cpp and compile into an a.out that you can use for testing. Let's look at FauxPalindromes.cpp
#include <string> #include <vector> #include <list> #include <cmath> #include <algorithm> #include <map> #include <set> #include <iostream> #include <cstdio> #include <cstdlib> using namespace std; class FauxPalindromes { public: string classifyIt(string word); }; string FauxPalindromes::classifyIt(string word) { return ""; } |
We compile it by compiling main.cpp (which includes it):
UNIX> g++ main.cpp UNIX> ls -l a.out -rwxr-xr-x 1 plank staff 21460 Aug 28 17:42 a.out UNIX>Now when we run it, we can give the example number on the command line:
UNIX> ./a.out 0 UNIX>We can also give it the argument "-", and enter an example string on standard input:
UNIX> echo FRED | ./a.out - UNIX>Of course, in both cases, it prints an empty line. That's because the return value of FauxPalindromes::classifyIt(), is the empty string. Let's modify FauxPalindromes.cpp so that it returns the string word:
UNIX> vi FauxPalindromes.cpp # Change the program so that it returns word instead of "". UNIX> g++ main.cpp UNIX> ./a.out 0 ANA UNIX> ./a.out 1 AAAAANNAA UNIX> echo FRED | ./a.out - FRED UNIX>Now, let's solve the problem. The way I'll solve it is to create three additional strings:
#include <iostream> using namespace std; class FauxPalindromes { public: string classifyIt(string word); }; string FauxPalindromes::classifyIt(string word) { string rword, p, r; size_t i; int j; for (j = word.size()-1; j >= 0; j--) rword.push_back(word[j]); // rword is the reverse of word. if (word == rword) return "PALINDROME"; p.push_back(word[0]); // p is word, but without any repeated characters. for (i = 1; i < word.size(); i++) { if (word[i] != word[i-1]) p.push_back(word[i]); } for (j = p.size()-1; j >= 0; j--) r.push_back(p[j]); // r is the reverse of p. if (r == p) return "FAUX"; return "NOT EVEN FAUX"; } |
Now, when we compile main.cpp, it incorporates the changes, and we are getting answers correct!
UNIX> g++ main.cpp UNIX> ./a.out 0 PALINDROME UNIX> ./a.out 1 FAUX UNIX> echo ABBA | ./a.out - PALINDROME UNIX> echo AAAABA | ./a.out - FAUX UNIX> echo FRED | ./a.out - NOT EVEN FAUX UNIX>Now, the shell script tests.sh runs a bunch of examples. It assumes that your program is compiled to a.out. Run it as follows:
UNIX> sh tests.sh NOT EVEN FAUX FAUX PALINDROME FAUX .... UXNI>Now, to test yourself, run tests.sh and redirect standard output to a file (I'll use junk.txt). Then compare this file to answers.txt using the program diff or openssl:
UNIX> sh tests.sh > junk.txt UNIX> diff junk.txt answers.txt # If they are identical, this will produce no output UNIX> openssl md5 junk.txt answers.txt # If they are identical, their MD5 hashes will be identical MD5(junk.txt)= 6e0336d91bff65fa3938c2ed9a5919c2 MD5(answers.txt)= 6e0336d91bff65fa3938c2ed9a5919c2 UNIX>tests.sh is not hard to read -- it just does a test per line:
UNIX> head tests.sh echo ICJGJCFGEGHIAFFFFAIHGEGFCJGJC | ./a.out - echo ENHPIECCMPEGPJJJPGEPMCEIPHNE | ./a.out - echo OOCBCLDNCEMOFDALNLADFOMECNDLCBCOO | ./a.out - echo CPPRRXXAGGGKKSUUUMUUUUUSSSKGGAAAXRPC | ./a.out - echo JKKKNFKLNFHJJGPIMMMGJGMMIPPGJHFFNLKKFNNKKJJ | ./a.out - echo DBBMMMBBIIIMMBDQQMMMMMQQDDBMMIIIBBMMMBBBDD | ./a.out - echo BAEBAFFCGDEGDDGEDGCFFABEAB | ./a.out - echo DDIAHDCBBDBGDADGBDBBCDHAIDD | ./a.out - echo JLDNFNFGEOFNCCNFOEGFNFNDLJ | ./a.out - echo KCKAAGMGGIGJJKKKGCDDJCOIIIOOCJDCGKKKJGIGGMMGAAKKCK | ./a.out - UNIX>In lab, you need to demonstrate to your TA that your program works. I include MD5 hashes for tests.sh and answers.txt so that you cannot modify them.
In this set of lecture notes, I will go over an example of doing this, how you sometimes have to fight topcoder, and how you can do a problem without Topcoder's servers working.
Suppose in lab, I say to do the problem "FauxPalindromes". Often, I will give you a URL to some notes on the problem, for example: http://web.eecs.utk.edu/~jplank/topcoder-writeups/2012/FauxPalindromes/index.html.
This is how I anticipate that you do the problem. First, you'll need to create an account with topcoder. Then, go to https://arena.topcoder.com. You'll see a screen something like the following:
Now, move your mouse to the green icon, which is the icon circled below, and click on it. That should get you to the "practice problems" page:
The "practice problems" page looks like the screenshot below:
Type "FauxPalindromes" into the search bar, and you'll see the problem, click on it, and you'll get a screen that looks as follows (As they warn you, this may take a minute or two. When I was writing these notes, it took over a minute. Evidently, Topcoder uses a server farm of Raspberry Pi's to hold their problems.)
Go ahead and read the problem description, including the constraints and examples. Think about how to solve it. My strategy for solving this problem would be as follows:
Start off by defining the class, and implementing the method so that it simply returns an empty string. I've done that below (I clicked on the icon to expand the "coding area"):
Click on "compile" to make sure that you have these details correct. You'll get a warning (since you didn't use the argument "word"), but that's fine. Now you're ready to actually write code. Here's my implementation. The comments are for you, by the way. I typically don't comment when I'm doing Topcoder. (Oh, and if you click on the picture, you can see the screenshot in its full size -- that's true with most of the screenshots here).
Compile this, and then click on the "Test Panel". This allows you to run your program on the examples. I clicked on the "Click All" button and then ran, and the window brings up that I failed cases two and four. Crap!!!
You can debug however you want. I pretty much knew my error right away -- I'm calling r.push_back(p[i]) instead of r.push_back(p[j]). If you put cout or printf() statements into your code, you'll see standard output in the window after clicking "Run". When you're satisfied and you want to submit, then you click "submit" and it will tell you how many points you've gotten. That doesn't mean that your program is right, though. To see that, click on "Run System Tests". If all has gone well, then you'll see the following:
Otherwise, you'll have to go back, fix your code and resubmit. When you fail, it doesn't appear to tell you why. That's a drag. Also, if you want to add test cases to the "Test Panel," click on "+Add" and you can create your own test cases.