I have been trying to get my feet wet programming in Rust.
A month and a half ago, I thought “Maybe I will hack up an Earley parser in a variety of languages, including Rust.” That sent me down a long path of learning about how Earley parsing works; I have not yet written up my results from that investigation, and I still have not written the Rust version of the code.
Last weekend, I sat down and said, “Let’s try a simpler goal: A couple simple exercies, maybe taken from Knuth’s TAOCP” This was indeed a much simpler goal, but it was more difficult than I had expected.
So, here is a Rust hacking puzzle that I struggled with.
I am representing piles of playing cards via linked structures. Here are the data structure declarations:
1 2 3 4 |
|
Note that the next
field is an (optional) owned pointer to the
next card in the pile. Option<~card>
will be generally used to
represent a potentially empty pile (or “stack”, “deck” or “hand”, as
the context dictates), while ~card
is a non-empty pile (or, when its
next
is None
, a single card, again as context dictates)
The goal
I want to write four functions: place_top
, place_bot
, pop_top
,
and pop_bot
, which respectively:
place_top(stack, c)
pushes a cardc
onto the top of the stack, represented by return the new top of the stack.place_bot(stack, c)
places a card beneath the stack. For an empty stack, the placed card is returned as the top of the newly formed stack; otherwise, the old stack top is returned (since the stack is imperatively modified).pop_top(stack)
pops the top of the stack, returning a tuple of the popped card and the remaining, potentially empty stack.pop_bot(stack)
removes the bottom of the stack (i.e. “deals from the bottom of the deck”), returning a tuple of the removed card and the new, potentially empty stack.
In code, here are the signatures for the desired functions, as well as one-line reminders of the behavior for each.
1 2 3 4 5 6 7 8 9 10 11 |
|
(Some non-critical helper infrastructure follows, showing off Rust as language)
Here is some example code that puts together a hand and does a few manipulations using the above operations (as well as some printing routines to make looking at these cards nicer in the terminal output)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
|
In my terminal, I get the following output from the above main
function:
initial hand: 2♦,3♠,10♣
place top: A♦
new hand: A♦,2♦,3♠,10♣
place bot: 6♦
new hand: A♦,2♦,3♠,10♣,6♦
popped top: A♦
new hand: 2♦,3♠,10♣,6♦
popped bot: 6♦
new hand: 2♦,3♠,10♣
(I will post my initial “solution” to the puzzle in a follow-up post; I wanted to share this first because I know my current solution is non-optimal and wanted to see what others had to offer for how to solve this first.)