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

Reply via email to