So this week, I decided to make things hard on myself and use an esoteric language. I chose LOLCODE since I've never used it before, and it seems pretty popular.
Little did I know, LOLCODE has no support for lists.
So, this weekly became quite a challenge — how can I solve a problem which requires some sort of list-like data structure to solve (to implement a uniqueness check) with a system that has no lists.
Well, my solution was to realize that what I just said was a lie. There are lists in LOLCODE — yarns (or, as boring normal programmers call them, strings).
So my task became a) encoding a list of numbers in a string,and b) figuring out how to compare a number to all the numbers in that "list", and check if there is a match.
These things probably don't sound too hard, but this is an esoteric language so of course it was difficult. The first goal I accomplished by giving each number an arbitrary precision — 10 digits (which seems big enough that you won't run out of space for something like this challenge while keeping the performance modest). I could then simply pad each number up to 10 digits with leading zeroes, and it becomes possible to get any number out of the list. The next goal was not as easy, but through a lot of loops and fun names like
DIJIT I managed to make it work.
So here it is, a bunch of unreadable code that sounds like your cat wrote it, complete with LOLspeak prompts. It doesn't look like much, but don't assume the complexity of an esoteric program based on its size :D
Note 1: Don't give it big numbers, due to the obvious performance downsides of this approach it will get really laggy. Anything over 20x20 starts to get laggy, so I'd keep it around that range at most. (If you're wondering, under no circumstances put anything greater than 99999x99999 — it will max out the 10 digit limit and be frozen forever!)
Note 2: If nothing shows up at first, re-run the program. It appears that sometimes repl's lolcode interpreter doesn't run the first time.
@DynamicSquid 1. If you do it the way you're doing it not, you'd put that in
TravelTree. However, I'd strongly suggest making each AST
node have an
eval method which does what your
TravelTree function does (so remove
TravelTree). Then, instead of calling
TravelTree, you say
rootNode.eval(), and it calls
eval on its subnodes (which may call more
evals on their subnodes, etc) and then it adds/multiplies/does whatever with the return values.
2. If you're doing an AST, make the entire program be represented as an AST! The AST should be your only representation of the entire program once you've parsed the tokens.
A final note: Your recursive descent parser works, but it's kinda ugly and will get really ugly the more you add to it. I'd suggest each task to different functions — rather than try to explain that here, I will (once again :D) direct you to my Sea parser.
I'm kinda busy right now, so I don't have the time to create a full example in C++. When I get the time (which should be soon), I'll make an example to help illustrate my point better.