See http://cs.smu.ca/~jdeveaux/csci/3465/2014/assign2.html