Towers of Hanoi in parrot assembler. Feel free to use it as an example,
or just as a test-case for PerlArrays.
Enjoy!
++t
#
# Towers of hanoi in parrot assembler
#
# Author: Tony Payne
# Date: 05/15/2002
#
# Data structure:
#
# P0 is a PerlArray with three entries. Each entry is a PerlArray PMC
# which represents a tower (column) of hanoi
#
# The towers are arrays of integers. 0 indicates no disk is present
# A positive integer indicates the diameter of the disk occupying
# the inicated slot.
#
# So this setup
#
# || || ||
# ==== || ||
# ====== || ==
#
# is represented as
# [[0, 2, 3], [0, 0, 0], [0, 0, 1]]
#
# In pseudocode:
#
# main() {
# size = argv[0]
# int arr[] = [[], [], []]
# arr[0] = [1..size]
# arr[1] = [(0) x size]
# arr[2] = [(0) x size]
# move_stack(arr, size, size, 0, 2, 1)
# }
#
# move_stack(array, size, num, start, target, storage) {
# if(num == 1) {
# move(array, size, start, target)
# } else {
# # move all but the largest disk to storage
# move_stack(array, size, num-1, start, storage, target)
# # move the largest disk to target
# move(array, size, start, target)
# # move all but the largest disk from storage to target
# move_stack(array, size, num-1, storage, target, start)
# }
#
# move(array, size, start, target) {
# /* okay, so it's not pseudocode... */
# # find the first non-empty slot on the start column (smallest disk)
# for(i=0; i<size; i++) if(array[start_col][i]) break;
# start_row = i;
#
# # find the last empty slot on the target column
# for(i=1; i<size; i++) if(array[dest_col][i]) break;
# dest_row = i - 1;
#
# # do the move
# array[dest_col][dest_row] = array[start_col][start_row];
# array[start_col][start_row] = 0;
#
# #print the results
# print(array, size);
# }
MAIN:
get_keyed I5, P0, 1 #I5 = argv[0]
new P0, PerlArray
new P1, PerlArray
new P2, PerlArray
new P3, PerlArray
set_keyed P0, 0, P1 #P0 = [[],[],[]]
set_keyed P0, 1, P2
set_keyed P0, 2, P3
set I0, 0
loop_populate:
add I1, I0, 1
set_keyed P1, I0, I1 #P0=[[1,2,3,...],[0,0,0...],[0,0,0...]]
set_keyed P2, I0, 0
set_keyed P3, I0, 0
inc I0, 1
lt I0, I5, loop_populate
set I1, I5 # size
set I2, 0 # start_col
set I3, 2 # target_col
set I4, 1 # storage_col
bsr MOVE_STACK
END: end
#Params
# P0 = array (const)
# I0 = size (const)
PRINT: # vars used: I1, I2, I3, I4, I5, I6, P1
set I1, 0 #I1 = i
set I2, 0 #I2 = j
set I3, 0 #I3 = k
loop_rows:
set I2, 0
loop_cols:
get_keyed P1,P0,I2 #P1 = P0[j]
get_keyed I4,P1,I1 #I4 = cursize; cursize=array[j][i]
sub I5, I0, I4 #I5 = size-cursize
repeat S0, " ", I5
print S0
mul I6, I4, 2 #I6 = cursize * 2
repeat S0, "=", I6
print S0
repeat S0, " ", I5
print S0
inc I2, 1 # j++
eq I2, 3, done_loop
print " | "
if 1, loop_cols # j < 3
done_loop:
print "\n"
inc I1, 1 # i++
lt I1, I0, loop_rows # i < size
print "\n"
ret
# params
# P0 = array
# I0 = size
# I2 = start_col
# I3 = dest_col
MOVE: #vars used: I4, I5, I6, I7, I8, P1, P2
set I4, 0 #I4 = i
get_keyed P1, P0, I2 #P1 = array[start_col]
loop_find_start_row:
get_keyed I7, P1, I4 #I7 = array[start_col][i]
ne I7, 0, found_start_row
inc I4, 1 # i++
lt I4, I0, loop_find_start_row # i < size
found_start_row:
set I5, I4 #I5 = start_row = i
get_keyed P2, P0, I3 #P2 = array[dest_col]
set I4, 0 # for( i = 0
loop_find_dest_row:
get_keyed I8, P2, I4 #I8 = array[dest_col][i]
ne I8, 0, found_dest_row # if(array[dest_col][i])
inc I4, 1 # i++
lt I4, I0, loop_find_dest_row # i < size
found_dest_row:
sub I6, I4, 1 #I6 = dest_row = i - 1
set_keyed P2, I6, I7 # array[dc][dr]=array[sc][sr]
set_keyed P1, I5, 0 # array[sc][sr]=0
bsr PRINT
ret
# P0 = array
# I0 = size
# I1 = num
# I2 = start_col
# I3 = target_col
# I4 = storage_col
MOVE_STACK:
gt I1, 1, move_multiple # if num == 1
bsr MOVE # return move(...)
ret
move_multiple:
save I1
dec I1, 1
save I4
save I3
save I2
set I5, I3
set I3, I4
set I4, I5
bsr MOVE_STACK #move_stack(...)
restore I2
restore I3
restore I4
restore I1
save I1
save I4
save I3
save I2
bsr MOVE #move(...)
restore I2
restore I3
restore I4
restore I1
save I1
save I4
save I3
save I2
dec I1, 1
set I5, I2
set I2, I4
set I4, I5
bsr MOVE_STACK #move_stack(...)
restore I2
restore I3
restore I4
restore I1
ret