Two Guys Arguing

Piet Roll Command

Posted in challenge by benjaminplee on 03.15.10

Roll-n-rolling with the Piet ROLL command

Mr. Young and a few others questioned how QuickPiet‘s command worked …. and to be honest, at first I didn’t either.  It turns out that the Piet ROLL command works fairly simply and is extremely powerful (according to npiet which I used as the basis for my testing).

The ROLL command pops two values off of the stack puts nothing back.  The top value from the stack defines how many “turns” the roll executes.  A turn will put the top value on the bottom and shift all other values “up” one place toward the top of the stack.  The second value defines the “depth” of the roll or how many elements should be included in each turn starting at the top of the stack.

As the main Piet page suggests, a ROLL to a depth of X and a single turn will effectively bury the top of the stack down X spots.  If that is as clear as mud, check out this image which shows two roll actions executed on a already populated stack.

Demonstration of the Piet ROLL command

Click to enlarge

[EDIT: Correction, the last roll in the above image shows a roll of depth 5, 2 turns. Not 3.  My bad.)

I used the nPiet command line Win32 interpreter to test this and the following program shown with 1 pixel per codel** and again with 20x20 pixels per codel.  nPiet is the most stable interpreter I have found and has some nice features like creating trace output images, tracing/logging statements, and automatically guessing codel sizes.  Below is the 20x20 codel version and nPiet trace output.

ROLL test program

ROLL test program

$ ./npiet.exe -v -t ben/roll-big.gif
info: verbose set to 1
info: trace set to 1
info: using file ben/roll-big.gif
info: got gif image with 320 x 120 pixel
info: codelsize guessed is 20 pixel
trace: step 0  (0,0/r,l nR -> 1,0/r,l dR):
action: push, value 1
trace: stack (1 values): 1
trace: step 1  (1,0/r,l dR -> 2,0/r,l lR):
action: push, value 2
trace: stack (2 values): 2 1
trace: step 2  (2,0/r,l lR -> 3,0/r,l nR):
action: push, value 3
trace: stack (3 values): 3 2 1
trace: step 3  (3,0/r,l nR -> 4,0/r,l dR):
action: push, value 4
trace: stack (4 values): 4 3 2 1
trace: step 4  (4,0/r,l dR -> 5,0/r,l lR):
action: push, value 5
trace: stack (5 values): 5 4 3 2 1
trace: step 5  (5,0/r,l lR -> 6,0/r,l nR):
action: push, value 3
trace: stack (6 values): 3 5 4 3 2 1
trace: step 6  (6,0/r,l nR -> 7,0/r,l dR):
action: push, value 2
trace: stack (7 values): 2 3 5 4 3 2 1
trace: step 7  (7,0/r,l dR -> 8,0/r,l lB):
action: roll
trace: stack (5 values): 3 5 4 2 1
trace: step 8  (8,0/r,l lB -> 9,0/r,l nB):
action: push, value 3
trace: stack (6 values): 3 3 5 4 2 1
trace: step 9  (9,0/r,l nB -> 10,0/r,l dB):
action: push, value 2
trace: stack (7 values): 2 3 3 5 4 2 1
trace: step 10  (10,0/r,l dB -> 11,0/r,l lG):
action: roll
trace: stack (5 values): 4 3 5 2 1
trace: entering white block at 12,0 (like the perl interpreter would)...
trace: step 11  (11,0/r,l lG -> 12,0/r,l WW):
trace: special case: we at a white codel - continuing
trace: white cell(s) crossed - continuing with no command at 12,2...
trace: step 12  (12,0/r,l WW -> 12,2/d,r lG):
info: program end

** Since small Piet programs are TINY, instead of using 1×1 pixels as the unit block or codel, Piet interpreters should be able to use codels of larger sizes.  Codels of larger sizes allow Piet programs to be easier to see and work with.

Tagged with: , ,
Follow

Get every new post delivered to your Inbox.