2013-04-14 4 views
9

In PostScript ist der Operator roll sehr allgemein und schwierig zu visualisieren. Wie stellen Sie sicher, dass Sie in die richtige Richtung rollen?Wie halten Sie den "Roll" -Operator in Ordnung?

Ich möchte auf roll einen festen Griff bekommen, weil ich Funktionen in der Lage sein wollen, zu transformieren Variablen

/f { % x y z 
    /z exch def 
    /y exch def 
    /x exch def 
    x dup mul 
    y dup mul 
    z dup mul add add % x^2+y^2+z^2 
} def 

in Funktionen Stapelmanipulationen verwendet wird, eher wie

/f { % x y z 
    3 1 roll dup mul % y z x^2 
    3 1 roll dup mul % z x^2 y^2 
    3 1 roll dup mul % x^2 y^2 z^2 
    add add % x^2+y^2+z^2 
} def 

oder

/f { % x y z 
    3 { 3 1 roll dup mul } repeat 
    2 { add } repeat  % x^2+y^2+z^2 
} bind def 

Diese sollten beide schneller ausführen, indem sie weniger haben Name-Lookups (Hash-Suche).

Mit roll muss ich es immer testen; und ich normalerweise bekommen es falsch beim ersten Versuch! Ich bin okay mit Austausch, obwohl

+0

Diese Frage ist erfunden, um die Antwort zu motivieren (Teilen Sie Ihr Wissen). Verbesserungsvorschläge werden gerne erbeten. –

Antwort

9

Ich hatte Schwierigkeiten mit Rollen für eine sehr lange Zeit. Ich erinnere mich, es nun, diese Möglichkeiten mit, die alle gleichwertig:

der Reim (ish)

nj Rolle

  • positive j, wegrollen

    7 8 9 3 1 roll 
    % 9 7 8

  • negativ, es zurück zu bekommen (oder "negateeve, um dann abrufen")

    % 9 7 8 
    3 -1 roll 
    % 7 8 9


Stapel (Dinge)

Vielleicht eine bessere Art und Weise ein zu denken, es ist physischer Stapel (von Büchern, sagen Sie) also ist die Oberseite des Stapels buchstäblich "oben".

Dann wird eine positive Rolle nach oben geht:

 for j number of times 
    pick up n books 
    put the top one on the bottom (shifting the substack "up") 
    put them back down

und eine negative Rolle geht:

 for j number of times 
    pick up n books 
    put the bottom one on top (shifting the substack "down") 
    put them back down

seitwärts

Aber ich Bild in der Regel den Stapel zur Seite, die Art und Weise Die Objekte würden in einer Datei als Folge von Literalen aussehen. Also denke ich an die positive Rolle als Versteckt die oberen j Dinge hinter der nth Sache; und die negative Rolle als snagging j Dinge beginnend mit mit der n-ten Sache. Geben und Nehmen.

Weg.

n j roll 

__ j > 0 __  move top j elements to the bottom of n 

n   TOS 
    -------------| 
|  j  | 
|  -----| 
|  |  | 
V  V  | 

a b c d e f g h 

^  |  | 
|  |-------| 
^   | 
-<-<-<-<-<- 
    move 

Und zurück.

__ j < 0 __ move j elements from the bottom of n to the top 

n   TOS 
    -------------| 
|  j  | 
|-----  | 
|  |  | 
V  V  | 

a b c d e f g h 

|  |  ^
|-------|  | 
    |   ^
    ->->->->->- 
     move 

Fussel-Rolle

Noch eine andere Art und Weise ist es seitwärts Bild und ein klebriges Rad mit an der Spitze (ein Fussel-Rolle, vielleicht)

(a) (b) (c) (d) (e) 5 3 roll 

      _______ 
     /  \ 
      | 3 | 
      |/| \ | 
      \_______/ 
(a) (b) (c) (d) (e)

Dann ein positive Rolle geht gegen den Uhrzeigersinn genau wie Bogen und drehen.

  _______ (e) 
    / /\ 
     | 3 --| (d) 
     |  \ | 
     \_______/ (c) 
(a) (b) 


    (e)__(d)__(c) 
    /\ | /\ 
    | 3 | 
    |  | 
    \_______/ 
    (a) (b) 


    (c)_______ 
    /\  \ 
(d) |-- 3 | 
    |/  | 
    \_______/ 
    (e) (a) (b) 


    _______ 
/  \ 
    | 3 | 
    |/| \ | 
    \_______/ 
(c) (d) (e) (a) (b)

und eine negative Rolle geht im Uhrzeigersinn wie ARCn und eine negative Drehung.

 _______ 
/  \ 
    | 3 | 
    |/| \ | 
    \_______/ 
(a) (b) (c) (d) (e) 


    (a)_______ 
    /\  \ 
(b) |-- 3 | 
    |/  | 
    \_______/ 
    (c)  (d) (e) 


    (c)__(b)__(a) 
    /\ | /\ 
    | 3 | 
    |  | 
    \_______/ 
    (d) (e) 

     _______ (c) 
    / /\ 
     | 3 --| (b) 
     |  \ | 
     \_______/ (a) 
(d) (e) 

      _______ 
     /  \ 
      | 3 | 
      |/| \ | 
      \_______/ 
(d) (e) (a) (b) (c)

eliminieren die negative

Es sollte nicht schwierig sein, dass negative Rollen unnötig sind vollständig zu sehen, denn wenn j < 0, kann es durch n-j ersetzt werden. z.B.

3 -1 roll % roll bottom 1 element from 3 to the top 
3 2 roll % roll top 2 elements behind the 3rd 

sind gleich.

16 -4 roll % roll bottom 4 elements from 16 to the top 
16 12 roll % roll top 12 elements behind the 16th 

sind gleich.


Dies führt zu der endgültigen, ultimativen vereinfachten Ansicht (obwohl jede der oben genannten auch funktioniert).

Roll ist nur ein großer Swap

Sie sind wirklich nur top j Elemente mit den unter dem n-j Elemente auszutauschen.

Angenommen, Sie haben dieses Chaos auf dem Stapel (wobei $ TOS $ die Spitze des Stapels markiert), und es bestellen möchten richtig:

g h i j k l m n o p q r s t u v w x y z a b c d e f $TOS$ 

Count oben (unten) für n und j.

g h i j k l m n o p q r s t u v w x y z a b c d e f 
26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 
|               | j = 6 . . . . 
| n = 26 . . . . . . . . . . . . . . . . . . . . . . . 

> 26 6 roll pstack 

a b c d e f g h i j k l m n o p q r s t u v w x y z 

Ein negativer Wert für j einfach diese Linie relativ zu dem tiefstenen Elemente Teilungspositionen aus den n Elementen (von unten zählt).

t u v w x y z a b c d e f g h i j k l m n o p q r s 
26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 
. . . . j = -7 |              | 
. . . . . . . . . . . . . . . . . . . . . . . n = 26 | 

> 26 -7 roll pstack 

a b c d e f g h i j k l m n o p q r s t u v w x y z 

Hier ist eine Komfortfunktion, die eine Schnittstelle, das ist näher analog die großer Swap Ansicht zu rollen gibt.

% r0..rN s0..sM N M swap s0..sM r0..rN 
% a gentler interface to the power of roll 
/swap { 
    exch 1 index add exch 
    roll 
} def 
0 1 2 3 /a /b /c 4 3 swap pstack 

Ausgang:

GPL Ghostscript 8.62 (2008-02-29) 
Copyright (C) 2008 Artifex Software, Inc. All rights reserved. 
This software comes with NO WARRANTY: see the file PUBLIC for details. 
3 
2 
1 
0 
/c 
/b 
/a 
GS<7>GS<7> 
+0

Dies wurde aus Material kompiliert, das ich zuvor in [comp.lang.postscript] (https://groups.google.com/d/msg/comp.lang.postscript/gCGb5UQAmac/TsQOBNVvFKQJ) –

+0

veröffentlicht hatte. Wenn Sie alle gelesen haben Weg zu hier, * teste dein Verständnis *, indem du versuchst, die/xpose-Funktion [hier] (http://stackoverflow.com/a/14600918/733077) zu lesen, die eine Transponierte einer * abgeflachten * 4x4-Matrix macht. Die Funktion könnte berücksichtigt werden, um alle Zahlen in einem 2D-Array und "{aload pop roll forall" zu haben, aber dann würde es keinen Ort geben, an dem der Kommentar geschrieben werden könnte. :) –

1

Einfach sagen: wenn Sie etwas rundes Objekt Rolle machen, von Ihnen seine Entfernung wird wahrscheinlich größer sein nach als zuvor, es sei denn, Sie etwas anderes, als Sie die Hand (zB: ein magischer Zauberstab, ...) um das Objekt zum Rollen zu bringen.

5 1 roll bedeutet, dass das 1 Objekt auf der Oberseite des Stapels später in einem größeren Abstand von der Oberseite des Stapels sein wird.

10 11 12 13 14 15 16 17 18 19 20 5 1 roll 

ist die gleiche als

10 11 12 13 14 15 20 16 17 18 19 

Sie sehen 20 hat tiefer gegangen, und die letzten fünf Element geändert Position.

5 in 5 1 roll bedeutet, dass nur die fünf ersten Objekte aus dem Stapel alle ihre Position ändern können.

-1 und 4 sind die gleichen Modulo 5, daher ist es leicht, sich daran zu erinnern, dass negative Zahlen modifiziert werden müssen positiv sein, bevor diese Lösung angewendet wird.