nieh@moose.steinmetz (nico nieh) (12/08/87)
The following problems occurred to me yesterday while I was editing a file which contains matrices. 1. Is there an easy way to transpose a matrix in GNU-Emacs ? 1 2 3 4 5 1 6 2 1 9 6 7 8 9 2 2 7 4 3 8 2 4 6 8 0 ====> 3 8 6 5 7 1 3 5 7 9 4 9 8 7 6 9 8 7 6 5 5 2 0 9 5 2. Is there an easy way to rotate a rectangular of text +90/-90 degrees ? 1 2 3 4 5 9 1 2 6 1 6 7 8 9 2 8 3 4 7 2 2 4 6 8 0 =====> 7 5 6 8 3 1 3 5 7 9 6 7 8 9 4 9 8 7 6 5 5 9 0 2 5 3. Is there an easy way to mirror a rectangular of text (vertical/horizontal) ? 4. How about reverse a line or reverse a region ? Above questions should be applied to both character and word boundary. Can anyone out there give me some advices ? Ko-Haw Nieh General Electric Company Corporate Research and Development nieh@ge-crd.arpa 518-387-7431
evan@cunixc.columbia.edu (Evan Bigall) (12/10/87)
| The following problems occurred to me yesterday while I was editing | a file which contains matrices. | | 1. Is there an easy way to transpose a matrix in GNU-Emacs ? | | 1 2 3 4 5 1 6 2 1 9 | 6 7 8 9 2 2 7 4 3 8 | 2 4 6 8 0 ====> 3 8 6 5 7 | 1 3 5 7 9 4 9 8 7 6 | 9 8 7 6 5 5 2 0 9 5 I know this is not exactly what you wanted, but if you just want to get it done what I would do is: run apl in a subshell under emacs cut the text from the file into the shell and assign it to an apl variable. use the apl transpose primitive function to transpose it (or rotate it, or whatever you want, apl can do it all) cut the result back into the file This is how I would do it, but then I like apl. Send me mail if you want the details of how to do the apl stuff. evan -- evan@cunixc.columbia.edu or EJB@yktvmh.bitnet (914)789-7027 APL is a mistake, carried through to perfection. It is the language of the future for the programming techniques of the past. - Edsger Dijkstra
karl@haddock.ISC.COM (Karl Heuer) (12/11/87)
In article <8129@steinmetz.steinmetz.UUCP> nieh@moose.steinmetz (nico nieh) writes: >The following problems occurred to me yesterday while I was editing >a file which contains matrices. > >1. Is there an easy way to transpose a matrix in GNU-Emacs ? >2. Is there an easy way to rotate a rectangular of text +90/-90 degrees ? >3. Is there an easy way to mirror a rectangular of text (vertical/horizontal) ? >4. How about reverse a line or reverse a region ? > >Above questions should be applied to both character and word boundary. I have a program called "flip" that transposes an input stream by character. I find this very useful for doing column-oriented operations in an editor where line-oriented operations are the norm. The program also has an option to use fixed-size rectangles of characters as the quantum (someday I should add an option for tab-separated quanta). Request by e-mail if you want the source code. It probably wouldn't be too difficult to do with an awk script, either. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
weltyc@nysernic (Christopher A. Welty) (12/11/87)
In article <8129@steinmetz.steinmetz.UUCP> nieh@moose.steinmetz (nico nieh) writes: > >The following problems occurred to me yesterday while I was editing >a file which contains matrices. > >1. Is there an easy way to transpose a matrix in GNU-Emacs ? > > 1 2 3 4 5 1 6 2 1 9 > 6 7 8 9 2 2 7 4 3 8 > 2 4 6 8 0 ====> 3 8 6 5 7 > 1 3 5 7 9 4 9 8 7 6 > 9 8 7 6 5 5 2 0 9 5 > Since emacs supports its own LISP, you can certainly write such fuinctions quite easily. In fact, I wrote this opne up quickly as an example. IT IS BY NMO MEANS EFFICIENT, there are a lot better ways to do it, I just wrote it real quick. If you position point at the beginning of a matrix which consists of elements separated by whitespace, and the last line of the matrix is followed by an empty line, this will put the transposed matrix after the original one. ie start with 1 2 3 3 2 1 1 2 3 and end up with 1 2 3 3 2 1 1 2 3 1 3 1 2 2 2 3 1 3 Here it is: (defun transpose () ; from point to the first blank line is current matrix (interactive) (let ((bol) (matrix nil) (i 0) (len) (tmatrix nil)) (while (not (eolp)) (setq bol (point)) (end-of-line) (setq matrix (append matrix (list (car (read-from-string (concat "(" (buffer-substring bol (point)) ")" )))))) (forward-line 1)) ; Now matrix is a list of lists, each sublist is a row (setq len (length (car matrix))) (while (< i len) (setq tmatrix (append tmatrix (list (mapcar '(lambda (x) (nth i x)) matrix)))) (setq i (1+ i))) ; tmatrix is now the transformed matrix, with each sublist a row ; Now we print it out after the current matrix (mapcar '(lambda (x) (newline 1) (mapcar '(lambda (x) (insert (format "%s " x))) x)) tmatrix))) Christopher Welty --- Asst. Director, RPI CS Labs weltyc@cs.rpi.edu ...!rutgers!nysernic!weltyc
rupley@arizona.edu (John Rupley) (12/12/87)
In article <1932@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes: >In article <8129@steinmetz.steinmetz.UUCP> nieh@moose.steinmetz (nico nieh) writes: >>The following problems occurred to me yesterday while I was editing >>a file which contains matrices. >> >>1. Is there an easy way to transpose a matrix in GNU-Emacs ? >>2. Is there an easy way to rotate a rectangular of text +90/-90 degrees ? >>3. Is there an easy way to mirror a rectangular of text (vertical/horizontal) ? >>4. How about reverse a line or reverse a region ? >> >>Above questions should be applied to both character and word boundary. > >I have a program called "flip" that transposes an input stream by character. <stuff deleted> >It probably wouldn't be too difficult to do with an awk script, either. ^^^^^^^^^^ True, awk makes it easy to do all that the original poster wanted. The example below is for text, ie for (2), (3), and (4); (1), for numbers, is even easier. Following is a quickie awk script to load an array, which you can read out however you want. I run new awk, but I think all is compatible with the old awk. The script is for text lines of variable length. Manipulating numerical arrays is simpler (that's how I prototyped, if one can speak of prototyping an awk script). Change in the gsub /re/ allows change from character to word boundary or to number, and this can be done dynamically, at least in the new awk, and through command line settings. Things could be prettied up and function calls would simplify, but its late and I'm doing this for fun. Some test output is given at the end of the script. *******NB: about 140 lines follow, so hit return if you're bored.... John Rupley uucp: ..{ihnp4 | hao!noao}!arizona!rupley!local internet: rupley!local@megaron.arizona.edu telex: 9103508679(JARJAR) (H) 30 Calle Belleza, Tucson AZ 85716 - (602) 325-4533 (O) Dept. Biochemistry, Univ. Arizona, Tucson AZ 85721 - (602) 621-3929 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ awk ' BEGIN { FS=":" } { #put in dummy separator, here a : gsub(/./, "&:") #split line into fields in array scr split($0, scr, ":") i = i + 1 j = 1 + 0 imax = i + 0 jmax[i] = NF - 1 if (jmax[i] > jmaxmax) jmaxmax = jmax[i] #fill doubly dimensioned array from elements of scr #i index = input row #j index = input field (no more than 10000) #the dummy index k is to make readout easier for (j = 1 + 0; j <= jmax[i]; j = j + 1) { k = i*10000 + j array[k] = scr[j] } } #now that the input is stuffed into an array, #read it out any-which-way END { #add spaces to obtain rectangular matrix #you can get rid of trailing spaces later, if you want for (i = 1 + 0; i <= imax; i = i + 1) { for (j = 1 + jmax[i]; j <= jmaxmax; j = j + 1) { k = i*10000 + j array[k] = " " } } #output whatever (function calls would be nicer) print "" print "send out what came in" for (i = 1 + 0; i <= imax; i = i + 1) { outstr="" for (j = 1 + 0; j <= jmaxmax; j = j + 1) { k = i*10000 + j outstr = outstr array[k] } print outstr } print "" print "reverse left-right" for (i = 1 + 0; i <= imax; i = i + 1) { outstr="" for (j = jmaxmax; j > 0; j = j - 1) { k = i*10000 + j outstr = outstr array[k] } print outstr } print "" print "reverse top-bottom" for (i = imax + 0; i > 0; i = i - 1) { outstr="" for (j = 1 + 0; j <= jmaxmax; j = j + 1) { k = i*10000 + j outstr = outstr array[k] } print outstr } print "" print "rotate + 90 degrees" for (j = 1 + 0; j <= jmaxmax; j = j + 1) { outstr="" for (i = imax + 0; i > 0; i = i - 1) { k = i*10000 + j outstr = outstr array[k] } print outstr } }' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ output for the following test block: abcdefg hijkl mnopqrstu v wx yz 0 is............ send out what came in abcdefg hijkl mnopqrstu v wx yz 0 reverse left-right (mirror vertically) (reverse region) gfedcba lkjih utsrqponm zy xw v 0 reverse top-bottom (mirror horizonatally) 0 v wx yz mnopqrstu hijkl abcdefg rotate + 90 degrees vmha nib wojc xpkd qle r f ys g zt u 0 ......and whatever else one's heart desires +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++