diff options
Diffstat (limited to 'runtime/macros/maze')
-rw-r--r-- | runtime/macros/maze/Makefile | 7 | ||||
-rw-r--r-- | runtime/macros/maze/README.txt | 49 | ||||
-rw-r--r-- | runtime/macros/maze/README.txt.info | bin | 0 -> 734 bytes | |||
-rw-r--r-- | runtime/macros/maze/maze.c | 7 | ||||
-rw-r--r-- | runtime/macros/maze/maze_5.78 | 16 | ||||
-rw-r--r-- | runtime/macros/maze/maze_5.78.info | bin | 0 -> 972 bytes | |||
-rw-r--r-- | runtime/macros/maze/maze_mac | 271 | ||||
-rw-r--r-- | runtime/macros/maze/mazeansi.c | 7 | ||||
-rw-r--r-- | runtime/macros/maze/mazeclean.c | 22 | ||||
-rw-r--r-- | runtime/macros/maze/poster | 37 | ||||
-rw-r--r-- | runtime/macros/maze/poster.info | bin | 0 -> 734 bytes |
11 files changed, 416 insertions, 0 deletions
diff --git a/runtime/macros/maze/Makefile b/runtime/macros/maze/Makefile new file mode 100644 index 0000000..c34e115 --- /dev/null +++ b/runtime/macros/maze/Makefile @@ -0,0 +1,7 @@ +# It's simple... + +maze: mazeansi.c + cc -o maze mazeansi.c + +mazeclean: mazeclean.c + cc -o mazeclean mazeclean.c diff --git a/runtime/macros/maze/README.txt b/runtime/macros/maze/README.txt new file mode 100644 index 0000000..be8e8ef --- /dev/null +++ b/runtime/macros/maze/README.txt @@ -0,0 +1,49 @@ +To run the maze macros with Vim: + + vim -u maze_mac maze_5.78 + press "g" + +The "-u maze.mac" loads the maze macros and skips loading your .vimrc, which +may contain settings and mappings that get in the way. + + +The original README: + +To prove that you can do anything in vi, I wrote a couple of macros that +allows vi to solve mazes. It will solve any maze produced by maze.c +that was posted to the net recently. + +Just follow this recipe and SEE FOR YOURSELF. + 1. run uudecode on the file "maze.vi.macros.uu" to + produce the file "maze.vi.macros" + (If you can't wait to see the action, jump to step 4) + 2. compile maze.c with "cc -o maze maze.c" + 3. run maze > maze.out and input a small number (for example 10 if + you are on a fast machine, 3-5 if slow) which + is the size of the maze to produce + 4. edit the maze (vi maze.out) + 5. include the macros with the vi command: + :so maze.vi.macros + 6. type the letter "g" (for "go") and watch vi solve the maze + 7. when vi solves the maze, you will see why it lies + 8. now look at maze.vi.macros and all will be revealed + +Tested on a sparc, a sun and a pyramid (although maze.c will not compile +on the pyramid). + +Anyone who can't get the maze.c file to compile, get a new compiler, +try maze.ansi.c which was also posted to the net. +If you can get it to compile but the maze comes out looking like a fence +and not a maze and you are using SysV or DOS replace the "27" on the +last line of maze.c by "11" +Thanks to John Tromp (tromp@piring.cwi.nl) for maze.c. +Thanks to antonyc@nntp-server.caltech.edu (Bill T. Cat) for maze.ansi.c. + +Any donations should be in unmarked small denomination bills :^)=. + + ACSnet: gregm@otc.otca.oz.au +Greg McFarlane UUCP: {uunet,mcvax}!otc.otca.oz.au!gregm +|||| OTC || Snail: OTC R&D GPO Box 7000, Sydney 2001, Australia + Phone: +61 2 287 3139 Fax: +61 2 287 3299 + + diff --git a/runtime/macros/maze/README.txt.info b/runtime/macros/maze/README.txt.info Binary files differnew file mode 100644 index 0000000..263ddcd --- /dev/null +++ b/runtime/macros/maze/README.txt.info diff --git a/runtime/macros/maze/maze.c b/runtime/macros/maze/maze.c new file mode 100644 index 0000000..b917453 --- /dev/null +++ b/runtime/macros/maze/maze.c @@ -0,0 +1,7 @@ +char*M,A,Z,E=40,J[40],T[40];main(C){for(*J=A=scanf(M="%d",&C); +-- E; J[ E] =T +[E ]= E) printf("._"); for(;(A-=Z=!Z) || (printf("\n|" +) , A = 39 ,C -- +) ; Z || printf (M ))M[Z]=Z[A-(E =A[J-Z])&&!C +& A == T[ A] +|6<<27<rand()||!C&!Z?J[T[E]=T[A]]=E,J[T[A]=A-Z]=A,"_.":" |"];} diff --git a/runtime/macros/maze/maze_5.78 b/runtime/macros/maze/maze_5.78 new file mode 100644 index 0000000..dbe3d27 --- /dev/null +++ b/runtime/macros/maze/maze_5.78 @@ -0,0 +1,16 @@ +._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._ +| ._| . . ._| | |_._._. . ._|_._._._._. ._|_. ._|_._. ._| . ._|_. | . ._._. | +| ._|_| |_. | | | | ._._|_._|_._. . |_. | | | ._._| |_._._| | ._. ._| . . |_| +|_._._._. | ._|_. ._._._. | | ._. |_._. . | ._._| |_. | ._._._. |_. | |_|_| | +| | . |_._| . ._._._| ._._. ._._| | | |_| . | |_. . ._|_| ._._. |_._|_| . | | +|_._|_._._._|_._._._|_|_._._._|_._|_._._._|_._._._|_._._._|_._._._._._._|_._| + +See Vim solve a maze! + + type ":so maze_mac<RETURN>" to load the macros + + type "g" to start + +to interrupt type "<CTRL-C>" + to quit type ":q!<RETURN>" + diff --git a/runtime/macros/maze/maze_5.78.info b/runtime/macros/maze/maze_5.78.info Binary files differnew file mode 100644 index 0000000..fd65cef --- /dev/null +++ b/runtime/macros/maze/maze_5.78.info diff --git a/runtime/macros/maze/maze_mac b/runtime/macros/maze/maze_mac new file mode 100644 index 0000000..621aeec --- /dev/null +++ b/runtime/macros/maze/maze_mac @@ -0,0 +1,271 @@ +" These macros 'solve' any maze produced by the a-maze-ing maze.c program. +" +" First, a bit of maze theory. +" If you were put into a maze, a guaranteed method of finding your way +" out of the maze is to put your left hand onto a wall and just keep walking, +" never taking your hand off the wall. This technique is only guaranteed to +" work if the maze does not have any 'islands', or if the 'exit' is on the +" same island as your starting point. These conditions hold for the mazes +" under consideration. +" +" Assuming that the maze is made up of horizontal and vertical walls spaced +" one step apart and that you can move either north, south, east or west, +" then you can automate this procedure by carrying out the following steps. +" +" 1. Put yourself somewhere in the maze near a wall. +" 2. Check if you have a wall on your left. If so, go to step 4. +" 3. There is no wall on your left, so turn on the spot to your left and step +" forward by one step and repeat step 2. +" 4. Check what is directly in front of you. If it is a wall, turn on the +" spot to your right by 90 degrees and repeat step 4. +" 5. There is no wall in front of you, so step forward one step and +" go to step 2. +" +" In this way you will cover all the corridors of the maze (until you get back +" to where you started from, if you do not stop). +" +" By examining a maze produced by the maze.c program you will see that +" each square of the maze is one character high and two characters wide. +" To go north or south, you move by a one character step, but to move east or +" west you move by a two character step. Also note that in any position +" there are four places where walls could be put - to the north, to the south, +" to the east and to the west. +" A wall exists to the north of you if the character to the north of +" you is a _ (otherwise it is a space). +" A wall exists to the east of you if the character to the east of you +" is a | (otherwise it is a .). +" A wall exists to the west of you if the character to the west of you +" is a | (otherwise it is a .). +" A wall exists to the south of you if the character where you are +" is a _ (otherwise it is a space). +" +" Note the difference for direction south, where we must examine the character +" where the cursor is rather than an adjacent cell. +" +" If you were implementing the above procedure is a normal computer language +" you could use a loop with if statements and continue statements, +" However, these constructs are not available in vi macros so I have used +" a state machine with 8 states. Each state signifies the direction you +" are going in and whether or not you have checked if there is a wall on +" your left. +" +" The transition from state to state and the actions taken on each transition +" are given in the state table below. +" The names of the states are N1, N2, S1, S2, E1, E2, W1, W2, where each letter +" stands for a direction of the compass, the number 1 indicates that the we +" have not yet checked to see if there is a wall on our left and the number 2 +" indicates that we have checked and there is a wall on our left. +" +" For each state we must consider the existence or not of a wall in a +" particular direction. This direction is given in the following table. +" +" NextChar table: +" state direction vi commands +" N1 W hF +" N2 N kF +" S1 E lF +" S2 S F +" E1 N kF +" E2 E lF +" W1 S F +" W2 W hF +" +" where F is a macro which yanks the character under the cursor into +" the NextChar register (n). +" +" State table: +" In the 'vi commands' column is given the actions to carry out when in +" this state and the NextChar is as given. The commands k, j, ll, hh move +" the current position north, south, east and west respectively. The +" command mm is used as a no-op command. +" In the 'next state' column is given the new state of the machine after +" the action is carried out. +" +" current state NextChar vi commands next state +" N1 . hh W1 +" N1 | mm N2 +" N2 _ mm E1 +" N2 space k N1 +" S1 . ll E1 +" S1 | mm S2 +" S2 _ mm W1 +" S2 space j S1 +" E1 space k N1 +" E1 _ mm E2 +" E2 | mm S1 +" E2 . ll E1 +" W1 space j S1 +" W1 _ mm W2 +" W2 | mm N1 +" W2 . hh W1 +" +" +" Complaint about vi macros: +" It seems that you cannot have more than one 'undo-able' vi command +" in the one macro, so you have to make lots of little macros and +" put them together. +" +" I'll explain what I mean by an example. Edit a file and +" type ':map Q rXY'. This should map the Q key to 'replace the +" character under the cursor with X and yank the line'. +" But when I type Q, vi tells me 'Can't yank inside global/macro' and +" goes into ex mode. However if I type ':map Q rXT' and ':map T Y', +" everything is OK. I`m doing all this on a Sparcstation. +" If anyone reading this has an answer to this problem, the author would +" love to find out. Mail to gregm@otc.otca.oz.au. +" +" The macros: +" The macro to run the maze solver is 'g'. This simply calls two other +" macros: I, to initialise everything, and L, to loop forever running +" through the state table. +" Both of these macros are long sequences of calls to other macros. All +" of these other macros are quite simple and so to understand how this +" works, all you need to do is examine macros I and L and learn what they +" do (a simple sequence of vi actions) and how L loops (by calling U, which +" simply calls L again). +" +" Macro I sets up the state table and NextChar table at the end of the file. +" Macro L then searches these tables to find out what actions to perform and +" what state changes to make. +" +" The entries in the state table all begin with a key consisting of the +" letter 's', the current state and the NextChar. After this is the +" action to take in this state and after this is the next state to change to. +" +" The entries in the NextChar table begin with a key consisting of the +" letter 'n' and the current state. After this is the action to take to +" obtain NextChar - the character that must be examined to change state. +" +" One way to see what each part of the macros is doing is to type in the +" body of the macros I and L manually (instead of typing 'g') and see +" what happens at each step. +" +" Good luck. +" +" Registers used by the macros: +" s (State) - holds the state the machine is in +" c (Char) - holds the character under the current position +" m (Macro) - holds a vi command string to be executed later +" n (NextChar) - holds the character we must examine to change state +" r (Second Macro) - holds a second vi command string to be executed later +" +set remap +set nomagic +set noterse +set wrapscan +" +"================================================================ +" g - go runs the whole show +" I - initialise +" L - then loop forever +map g IL +" +"================================================================ +" I - initialise everything before running the loop +" G$?.^M - find the last . in the maze +" ^ - replace it with an X (the goal) +" GYKeDP - print the state table and next char table at the end of the file +" 0S - initialise the state of the machine to E1 +" 2Gl - move to the top left cell of the maze +map I G$?.
^GYKeDP0S2Gl +" +"================================================================ +" L - the loop which is executed forever +" Q - save the current character in the Char register +" A - replace the current character with an 'O' +" ma - mark the current position with mark 'a' +" GNB - on bottom line, create a command to search the NextChar table +" for the current state +" 0M0E@m^M - yank the command into the Macro register and execute it +" wX - we have now found the entry in the table, now yank the +" following word into the Macro register +" `a@m - go back to the current position and execute the macro, this will +" yank the NextChar in register n +" GT$B$R - on bottom line, create a command to search the state table +" for the current state and NextChar +" 0M0E@m^M - yank the command into the Macro register and execute it +" 2WS - we have now found the entry in the table, now yank the +" next state into the State macro +" bX - and yank the action corresponding to this state table entry +" into the Macro register +" GVJ - on bottom line, create a command to restore the current character +" 0H - and save the command into the second Macro register +" `a@r - go back to the current position and exectute the macro to restore +" the current character +" @m - execute the action associated with this state +" U - and repeat +map L QAmaGNB0M0E@m
wX`a@mGT$B$R0M0E@m
2WSbXGVJ0H`a@r@mU +" +"================================================================ +" U - no tail recursion allowed in vi macros so cheat and set U = L +map U L +" +"================================================================ +" S - yank the next two characters into the State register +map S "sy2l +" +"================================================================ +" Q - save the current character in the Char register +map Q "cyl +" +"================================================================ +" A - replace the current character with an 'O' +map A rO +" +"================================================================ +" N - replace this line with the string 'n' +map N C/n +" +"================================================================ +" B - put the current state +map B "sp +" +"================================================================ +" M - yank this line into the Macro register +map M "my$ +" +"================================================================ +" E - delete to the end of the line +map E d$ +" +"================================================================ +" X - yank this word into the Macro register +map X "myt +" +"================================================================ +" T - replace this line with the string 's' +map T C/s +" +"================================================================ +" R - put NextChar +map R "np +" +"================================================================ +" V - add the letter 'r' (the replace vi command) +map V ar +" +"================================================================ +" J - restore the current character +map J "cp +" +"================================================================ +" H - yank this line into the second Macro register +map H "ry$ +" +"================================================================ +" F - yank NextChar (this macro is called from the Macro register) +map F "nyl +" +"================================================================ +" ^ - replace the current character with an 'X' +map ^ rX +" +"================================================================ +" YKeDP - create the state table, NextChar table and initial state +" Note that you have to escape the bar character, since it is special to +" the map command (it indicates a new line). +map Y osE1 k N1 sE1_ mm E2 sE2| mm S1 sE2. ll E1 +map K osW1 j S1 sW1_ mm W2 sW2| mm N1 sW2. hh W1 +map e osN1. hh W1 sN1| mm N2 sN2 k N1 sN2_ mm E1 +map D osS1. ll E1 sS1| mm S2 sS2 j S1 sS2_ mm W1 +map P onE1 kF nE2 lF nW1 G$JF nW2 hF nN1 hF nN2 kF nS1 lF nS2 G$JF
E1 diff --git a/runtime/macros/maze/mazeansi.c b/runtime/macros/maze/mazeansi.c new file mode 100644 index 0000000..b8e5e79 --- /dev/null +++ b/runtime/macros/maze/mazeansi.c @@ -0,0 +1,7 @@ +char*M,A,Z,E=40,J[80],T[3];main(C){for(M=J+E,*J=A=scanf("%d",& +C) ;-- E;J [E ]=M +[E ]= E) printf("._"); for(;(A-=Z=!Z) || (printf("\n|" +) , A = 39 ,C -- +) ; Z || printf (T ))T[Z]=Z[A-(E =A[J-Z])&&!C +& A == M[ A] +|6<<27<rand()||!C&!Z?J[M[E]=M[A]]=E,J[M[A]=A-Z]=A,"_.":" |"];} diff --git a/runtime/macros/maze/mazeclean.c b/runtime/macros/maze/mazeclean.c new file mode 100644 index 0000000..04dcebd --- /dev/null +++ b/runtime/macros/maze/mazeclean.c @@ -0,0 +1,22 @@ +/* + * Cleaned-up version of the maze program. + * Doesn't look as nice, but should work with all C compilers. + * Sascha Wilde, October 2003 + */ +#include <stdio.h> +#include <stdlib.h> + +char *M, A, Z, E = 40, line[80], T[3]; +int +main (C) +{ + for (M = line + E, *line = A = scanf ("%d", &C); --E; line[E] = M[E] = E) + printf ("._"); + for (; (A -= Z = !Z) || (printf ("\n|"), A = 39, C--); Z || printf (T)) + T[Z] = Z[A - (E = A[line - Z]) && !C + & A == M[A] + | RAND_MAX/3 < rand () + || !C & !Z ? line[M[E] = M[A]] = E, line[M[A] = A - Z] = + A, "_." : " |"]; + return 0; +} diff --git a/runtime/macros/maze/poster b/runtime/macros/maze/poster new file mode 100644 index 0000000..9114f59 --- /dev/null +++ b/runtime/macros/maze/poster @@ -0,0 +1,37 @@ +Article 2846 of alt.sources: +Path: oce-rd1!hp4nl!mcsun!uunet!munnari.oz.au!metro!otc!gregm +From: gregm@otc.otca.oz.au (Greg McFarlane) +Newsgroups: alt.sources +Subject: VI SOLVES MAZE (commented macros) +Message-ID: <2289@otc.otca.oz> +Date: 10 Feb 91 23:31:02 GMT +Sender: news@otc.otca.oz +Reply-To: gregm@otc.otca.oz.au (Greg McFarlane) +Organization: OTC Development Unit, Australia +Lines: 464 + +Submitted-by: gregm@otc.otca.oz.au +Archive-name: maze_solving_vi_macros + +A real working model. See it walk the maze in front of your very own eyes. + +To prove that you can do anything in vi, I wrote a couple of macros that +allows vi to solve mazes. It will solve any maze produced by maze.c +that was posted to the alt.sources last month. (Maze.c is also included +in this posting as well as an example of its output.) + +The uncommented version of the macros was sent to alt.sources last month. +However, so many people mailed me requesting the commented version of the +macros that I decided to post it. I have made some modifications to the +original macros to make them easier to follow and also after I learnt +that you can escape the special meaning of '|' in macros by using '^V|'. + +Save this article and unshar it. Then read maze.README. + +After studying these macros, anyone who cannot write an emacs emulator +in vi macros should just curl up and :q!. + +Coming soon to a newsgroup near you: "Vi macros solve Tower of Hanoi", +and a repost of the original "Turing Machine implemented in Vi macros" + +Anyone who has a version of these macros for edlin or nroff, please post. diff --git a/runtime/macros/maze/poster.info b/runtime/macros/maze/poster.info Binary files differnew file mode 100644 index 0000000..9a478d6 --- /dev/null +++ b/runtime/macros/maze/poster.info |