xref: /minix3/usr.bin/sed/TEST/hanoi.sed (revision f789fee254bfd8e2872f294ed742b61d548759f1)
1*f789fee2SBen Gras# Towers of Hanoi in sed.
2*f789fee2SBen Gras#
3*f789fee2SBen Gras#	from: @(#)hanoi.sed	8.1 (Berkeley) 6/6/93
4*f789fee2SBen Gras#	$NetBSD: hanoi.sed,v 1.3 1997/01/09 20:21:35 tls Exp $
5*f789fee2SBen Gras#
6*f789fee2SBen Gras#
7*f789fee2SBen Gras# Ex:
8*f789fee2SBen Gras# Run "sed -f hanoi.sed", and enter:
9*f789fee2SBen Gras#
10*f789fee2SBen Gras#	:abcd: : :<CR><CR>
11*f789fee2SBen Gras#
12*f789fee2SBen Gras# note -- TWO carriage returns, a peculiarity of sed), this will output the
13*f789fee2SBen Gras# sequence of states involved in moving 4 rings, the largest called "a" and
14*f789fee2SBen Gras# the smallest called "d", from the first to the second of three towers, so
15*f789fee2SBen Gras# that the rings on any tower at any time are in descending order of size.
16*f789fee2SBen Gras# You can start with a different arrangement and a different number of rings,
17*f789fee2SBen Gras# say :ce:b:ax: and it will give the shortest procedure for moving them all
18*f789fee2SBen Gras# to the middle tower.  The rules are: the names of the rings must all be
19*f789fee2SBen Gras# lower-case letters, they must be input within 3 fields (representing the
20*f789fee2SBen Gras# towers) and delimited by 4 colons, such that the letters within each field
21*f789fee2SBen Gras# are in alphabetical order (i.e. rings are in descending order of size).
22*f789fee2SBen Gras#
23*f789fee2SBen Gras# For the benefit of anyone who wants to figure out the script, an "internal"
24*f789fee2SBen Gras# line of the form
25*f789fee2SBen Gras#		b:0abx:1a2b3 :2   :3x2
26*f789fee2SBen Gras# has the following meaning: the material after the three markers :1, :2,
27*f789fee2SBen Gras# and :3 represents the three towers; in this case the current set-up is
28*f789fee2SBen Gras# ":ab :   :x  :".  The numbers after a, b and x in these fields indicate
29*f789fee2SBen Gras# that the next time it gets a chance, it will move a to tower 2, move b
30*f789fee2SBen Gras# to tower 3, and move x to tower 2.  The string after :0 just keeps track
31*f789fee2SBen Gras# of the alphabetical order of the names of the rings.  The b at the
32*f789fee2SBen Gras# beginning means that it is now dealing with ring b (either about to move
33*f789fee2SBen Gras# it, or re-evaluating where it should next be moved to).
34*f789fee2SBen Gras#
35*f789fee2SBen Gras# Although this version is "limited" to 26 rings because of the size of the
36*f789fee2SBen Gras# alphabet, one could write a script using the same idea in which the rings
37*f789fee2SBen Gras# were represented by arbitrary [strings][within][brackets], and in place of
38*f789fee2SBen Gras# the built-in line of the script giving the order of the letters of the
39*f789fee2SBen Gras# alphabet, it would accept from the user a line giving the ordering to be
40*f789fee2SBen Gras# assumed, e.g. [ucbvax][decvax][hplabs][foo][bar].
41*f789fee2SBen Gras#
42*f789fee2SBen Gras#			George Bergman
43*f789fee2SBen Gras#			Math, UC Berkeley 94720 USA
44*f789fee2SBen Gras
45*f789fee2SBen Gras# cleaning, diagnostics
46*f789fee2SBen Grass/  *//g
47*f789fee2SBen Gras/^$/d
48*f789fee2SBen Gras/[^a-z:]/{a\
49*f789fee2SBen GrasIllegal characters: use only a-z and ":".  Try again.
50*f789fee2SBen Grasd
51*f789fee2SBen Gras}
52*f789fee2SBen Gras/^:[a-z]*:[a-z]*:[a-z]*:$/!{a\
53*f789fee2SBen GrasIncorrect format: use\
54*f789fee2SBen Gras\	: string1 : string2 : string3 :<CR><CR>\
55*f789fee2SBen GrasTry again.
56*f789fee2SBen Grasd
57*f789fee2SBen Gras}
58*f789fee2SBen Gras/\([a-z]\).*\1/{a\
59*f789fee2SBen GrasRepeated letters not allowed.  Try again.
60*f789fee2SBen Grasd
61*f789fee2SBen Gras}
62*f789fee2SBen Gras# initial formatting
63*f789fee2SBen Grash
64*f789fee2SBen Grass/[a-z]/ /g
65*f789fee2SBen GrasG
66*f789fee2SBen Grass/^:\( *\):\( *\):\( *\):\n:\([a-z]*\):\([a-z]*\):\([a-z]*\):$/:1\4\2\3:2\5\1\3:3\6\1\2:0/
67*f789fee2SBen Grass/[a-z]/&2/g
68*f789fee2SBen Grass/^/abcdefghijklmnopqrstuvwxyz/
69*f789fee2SBen Gras:a
70*f789fee2SBen Grass/^\(.\).*\1.*/&\1/
71*f789fee2SBen Grass/.//
72*f789fee2SBen Gras/^[^:]/ba
73*f789fee2SBen Grass/\([^0]*\)\(:0.*\)/\2\1:/
74*f789fee2SBen Grass/^[^0]*0\(.\)/\1&/
75*f789fee2SBen Gras:b
76*f789fee2SBen Gras# outputting current state without markers
77*f789fee2SBen Grash
78*f789fee2SBen Grass/.*:1/:/
79*f789fee2SBen Grass/[123]//gp
80*f789fee2SBen Grasg
81*f789fee2SBen Gras:c
82*f789fee2SBen Gras# establishing destinations
83*f789fee2SBen Gras/^\(.\).*\1:1/td
84*f789fee2SBen Gras/^\(.\).*:1[^:]*\11/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\31/
85*f789fee2SBen Gras/^\(.\).*:1[^:]*\12/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\33/
86*f789fee2SBen Gras/^\(.\).*:1[^:]*\13/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\32/
87*f789fee2SBen Gras/^\(.\).*:2[^:]*\11/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\33/
88*f789fee2SBen Gras/^\(.\).*:2[^:]*\12/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\32/
89*f789fee2SBen Gras/^\(.\).*:2[^:]*\13/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\31/
90*f789fee2SBen Gras/^\(.\).*:3[^:]*\11/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\32/
91*f789fee2SBen Gras/^\(.\).*:3[^:]*\12/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\31/
92*f789fee2SBen Gras/^\(.\).*:3[^:]*\13/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\33/
93*f789fee2SBen Grasbc
94*f789fee2SBen Gras# iterate back to find smallest out-of-place ring
95*f789fee2SBen Gras:d
96*f789fee2SBen Grass/^\(.\)\(:0[^:]*\([^:]\)\1.*:\([123]\)[^:]*\1\)\4/\3\2\4/
97*f789fee2SBen Grastd
98*f789fee2SBen Gras# move said ring (right, resp. left)
99*f789fee2SBen Grass/^\(.\)\(.*\)\1\([23]\)\(.*:\3[^ ]*\) /\1\2 \4\1\3/
100*f789fee2SBen Grass/^\(.\)\(.*:\([12]\)[^ ]*\) \(.*\)\1\3/\1\2\1\3\4 /
101*f789fee2SBen Grastb
102*f789fee2SBen Grass/.*/Done!  Try another, or end with ^D./p
103*f789fee2SBen Grasd
104