Solved problem 54

This problem took a lot longer than I hoped. The problem wasn't tricky,
but my solution may be more complicated than it needs to be, making it a
nightmare to debug. It works fine, but maybe I'll revisit this solution
later to refactor it.