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