Memory Games
Some friends have been using this website http://andys.org.uk/countryquiz/ to (perhaps) improve their memory by seeing how many of the 192 UN Member States they can name in 10 minutes. I tried it and only managed to get 16 in the two minutes I had before I realised I was meant to be elsewhere.
After coming back from elsewhere I decided to analyse the problem. I wasn’t sure if without time restriction I could name anywhere near that many states. I wasn’t sure if I could type that many states within the time restriction and if I could do the above two, I certainly wouldn’t be able to spell them all flawlessly.
So I cheated. I copied all the countries from the website’s list and then pasted them back one by one, this meant I was typing 5 fixed keyboard commands for each state in contrast to approximately 8.56 varied characters to type each individually. To do this successfully you’d have to average 33 words per minute, where the average is 19 words per minute for composition, and exactly 33 as well for just typing. So even cheating I was about 12 states short when time ran out, so I needed to cheat more.
To do this I wrote a Bookmarklet, a small piece of code which you enter in place of a URL in your browser, it can do just about anything to the client-side representation of a website. Essentially this script finds the input text field, enters a state into it, tells the website you’ve typed one in, then begins on the next state.
javascript: (function() {for(var s in states) {document.getElementsByTagName("input")[1].value = states[s]; checkStates(document.getElementsByTagName("input")[1]);}})();
My Bookmarklet worked! I received the coveted Alert Box of Success, having written my code and executed it within the allotted 10 minutes. However there was a bitterness to my victory, certainly not that I cheated, but that my script had to be run several times sequentially to get all the states validated. I suspect this was because my script was running faster than the User Interface could handle, but I’m not entirely sure.

So I decided to make a version that more closely resembled what a real person would do, or more simply, I made it wait a bit after entering each state. This initially seems trivial, except that JavaScript does not seem to have a function to pause your code for a short duration, and it all has to be written in one line of code.
javascript: (check = new function() {this.foo = states.slice(0);this.go = function() {document.getElementsByTagName("input")[1].value = this.foo.pop();checkStates(document.getElementsByTagName("input")[1]);if (this.foo.length != 0) setTimeout("check.go()", 2);};this.go();})();
I did this by creating a global Functor which periodically updates then yields until it is complete. This new code worked and got all of the states in 3 seconds with only one run of the Bookmarklet. Success! Some of you might be thinking, why not just hack the program and tell it you’ve won, bypassing the User Interface, well that’d be cheating. Furthermore, what I did here is much more likely to teach me something, and will work in an AJAX/Server driven version.
javascript: window.alert("You did it!");

Don’t forget the capital city version
http://enceladus.com.au/capitalquiz/
Tim
November 16, 2010 at 2:23 am
Heh, thanks! Seems that my script works on that one too, unmodified. I’ll have to learn the UN states first before I even consider learning the capitals.
therealbnut
November 16, 2010 at 3:00 am
I have been using the http://jquery.com/ javascript library.
Yes it’s cheating but it makes things much nicer
Hovo
November 16, 2010 at 2:24 am
Nah, using APIs isn’t cheating, although I think it would have taken much longer and been much less elegant to do this with a library like that. You’d have to write to the DOM to load the script, and then wait for it to be loaded, then run the script using their functions.
therealbnut
November 16, 2010 at 3:03 am
When you call setTimeout or setInterval, passing a string as the first parameter causes eval() to be called to parse it, which creates a new Function which is then called. It is faster/safer to use Function.prototype.apply/.call directly.
kyaaa
November 17, 2010 at 2:28 am
Yeah, I was aware that the evaluated code in there was a little expensive, but considered it to be easier to read and not really worth worrying about considering it’s being run 191 times. I’m sure I could have obfuscated it a lot more with javascript syntactical sugar, making it short and speedy (it seems that it was already too fast), but I was more interested in solving a problem in 10 minutes than remembering how to make good web javascript (which I haven’t used in about 5 years).
therealbnut
November 17, 2010 at 5:12 am