xref: /csrg-svn/usr.bin/sed/TEST/hanoi.sed (revision 62226)
145312Sbostic# Towers of Hanoi in sed.
245312Sbostic#
3*62226Sbostic#	@(#)hanoi.sed	8.1 (Berkeley) 06/06/93
445312Sbostic#
545312Sbostic#
645312Sbostic# Ex:
745312Sbostic# Run "sed -f hanoi.sed", and enter:
845312Sbostic#
945312Sbostic#	:abcd: : :<CR><CR>
1045312Sbostic#
1145312Sbostic# note -- TWO carriage returns, a peculiarity of sed), this will output the
1245312Sbostic# sequence of states involved in moving 4 rings, the largest called "a" and
1345312Sbostic# the smallest called "d", from the first to the second of three towers, so
1445312Sbostic# that the rings on any tower at any time are in descending order of size.
1545312Sbostic# You can start with a different arrangement and a different number of rings,
1645312Sbostic# say :ce:b:ax: and it will give the shortest procedure for moving them all
1745312Sbostic# to the middle tower.  The rules are: the names of the rings must all be
1845312Sbostic# lower-case letters, they must be input within 3 fields (representing the
1945312Sbostic# towers) and delimited by 4 colons, such that the letters within each field
2045312Sbostic# are in alphabetical order (i.e. rings are in descending order of size).
2145312Sbostic#
2245312Sbostic# For the benefit of anyone who wants to figure out the script, an "internal"
2345312Sbostic# line of the form
2445312Sbostic#		b:0abx:1a2b3 :2   :3x2
2545312Sbostic# has the following meaning: the material after the three markers :1, :2,
2645312Sbostic# and :3 represents the three towers; in this case the current set-up is
2745312Sbostic# ":ab :   :x  :".  The numbers after a, b and x in these fields indicate
2845312Sbostic# that the next time it gets a chance, it will move a to tower 2, move b
2945312Sbostic# to tower 3, and move x to tower 2.  The string after :0 just keeps track
3045312Sbostic# of the alphabetical order of the names of the rings.  The b at the
3145312Sbostic# beginning means that it is now dealing with ring b (either about to move
3245312Sbostic# it, or re-evaluating where it should next be moved to).
3345312Sbostic#
3445312Sbostic# Although this version is "limited" to 26 rings because of the size of the
3545312Sbostic# alphabet, one could write a script using the same idea in which the rings
3645312Sbostic# were represented by arbitrary [strings][within][brackets], and in place of
3745312Sbostic# the built-in line of the script giving the order of the letters of the
3845312Sbostic# alphabet, it would accept from the user a line giving the ordering to be
3945312Sbostic# assumed, e.g. [ucbvax][decvax][hplabs][foo][bar].
4045312Sbostic#
4145312Sbostic#			George Bergman
4245312Sbostic#			Math, UC Berkeley 94720 USA
4345312Sbostic
4445312Sbostic# cleaning, diagnostics
4545312Sbostics/  *//g
4645312Sbostic/^$/d
4745312Sbostic/[^a-z:]/{a\
4845312SbosticIllegal characters: use only a-z and ":".  Try again.
4945312Sbosticd
5045312Sbostic}
5145312Sbostic/^:[a-z]*:[a-z]*:[a-z]*:$/!{a\
5245312SbosticIncorrect format: use\
5345312Sbostic\	: string1 : string2 : string3 :<CR><CR>\
5445312SbosticTry again.
5545312Sbosticd
5645312Sbostic}
5745312Sbostic/\([a-z]\).*\1/{a\
5845312SbosticRepeated letters not allowed.  Try again.
5945312Sbosticd
6045312Sbostic}
6145312Sbostic# initial formatting
6245312Sbostich
6345312Sbostics/[a-z]/ /g
6445312SbosticG
6545312Sbostics/^:\( *\):\( *\):\( *\):\n:\([a-z]*\):\([a-z]*\):\([a-z]*\):$/:1\4\2\3:2\5\1\3:3\6\1\2:0/
6645312Sbostics/[a-z]/&2/g
6745312Sbostics/^/abcdefghijklmnopqrstuvwxyz/
6845312Sbostic:a
6945312Sbostics/^\(.\).*\1.*/&\1/
7045312Sbostics/.//
7145312Sbostic/^[^:]/ba
7245312Sbostics/\([^0]*\)\(:0.*\)/\2\1:/
7345312Sbostics/^[^0]*0\(.\)/\1&/
7445312Sbostic:b
7545312Sbostic# outputting current state without markers
7645312Sbostich
7745312Sbostics/.*:1/:/
7845312Sbostics/[123]//gp
7945312Sbosticg
8045312Sbostic:c
8145312Sbostic# establishing destinations
8245312Sbostic/^\(.\).*\1:1/td
8345312Sbostic/^\(.\).*:1[^:]*\11/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\31/
8445312Sbostic/^\(.\).*:1[^:]*\12/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\33/
8545312Sbostic/^\(.\).*:1[^:]*\13/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\32/
8645312Sbostic/^\(.\).*:2[^:]*\11/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\33/
8745312Sbostic/^\(.\).*:2[^:]*\12/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\32/
8845312Sbostic/^\(.\).*:2[^:]*\13/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\31/
8945312Sbostic/^\(.\).*:3[^:]*\11/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\32/
9045312Sbostic/^\(.\).*:3[^:]*\12/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\31/
9145312Sbostic/^\(.\).*:3[^:]*\13/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\33/
9245312Sbosticbc
9345312Sbostic# iterate back to find smallest out-of-place ring
9445312Sbostic:d
9545312Sbostics/^\(.\)\(:0[^:]*\([^:]\)\1.*:\([123]\)[^:]*\1\)\4/\3\2\4/
9645312Sbostictd
9745312Sbostic# move said ring (right, resp. left)
9845312Sbostics/^\(.\)\(.*\)\1\([23]\)\(.*:\3[^ ]*\) /\1\2 \4\1\3/
9945312Sbostics/^\(.\)\(.*:\([12]\)[^ ]*\) \(.*\)\1\3/\1\2\1\3\4 /
10045312Sbostictb
10145312Sbostics/.*/Done!  Try another, or end with ^D./p
10245312Sbosticd
103