你如何保持`roll`操作符直线?

lus*_*oog 11 postscript

在后记中,roll操作员非常通用且难以可视化.你如何确保你正朝着正确的方向前进?

我希望得到一个可靠的处理,roll因为我希望能够使用变量转换函数

/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
Run Code Online (Sandbox Code Playgroud)

使用堆栈操作进入函数,更像是

/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
Run Code Online (Sandbox Code Playgroud)

要么

/f { % x y z
    3 { 3 1 roll dup mul } repeat
    2 { add } repeat      % x^2+y^2+z^2
} bind def
Run Code Online (Sandbox Code Playgroud)

通过减少名称查找(哈希表搜索),这些都应该更快地执行.

随着roll我总是要测试一下; 我通常在第一次尝试时弄错了!不过,我对exch很好

lus*_*oog 11

很长一段时间我都遇到滚动困难.我现在记得使用这些方法,它们都是等价的:

押韵(-ish)

nj roll


堆栈(东西)

也许更好的方式来考虑它是一个物理堆栈(书籍,比如说),所以堆栈的顶部字面意思是"在顶部".

然后正面滚动:

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

负面滚动下降:

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

侧身

但我通常会将堆栈横向描绘,即对象在文件中看起来像一系列文字的方式.因此,我认为积极的滚动会隐藏在第n件事背后的最重要的东西; 从第n件事开始,负面卷起了j事.给予和接受.

远.

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
Run Code Online (Sandbox Code Playgroud)

然后回来.

__ 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
Run Code Online (Sandbox Code Playgroud)

皮棉辊

另一种方法是侧面拍摄,并在顶部放置一个粘性轮(可能是一个棉绒辊)

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

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

然后正向滚动逆时针旋转,就像弧形旋转一样.

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


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


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


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

负滚动顺时针方向如弧线和负旋转.

    _______
   /       \
   |   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)

消除负面影响

不容易看出负滚动是完全不必要的,因为如果j <0,它可以被nj代替.例如.

3 -1 roll  % roll bottom 1 element from 3 to the top
3 2 roll   % roll top 2 elements behind the 3rd
Run Code Online (Sandbox Code Playgroud)

是相同的.

16 -4 roll  % roll bottom 4 elements from 16 to the top
16 12 roll  % roll top 12 elements behind the 16th
Run Code Online (Sandbox Code Playgroud)

是相同的.


这导致最终的,最终的简化视图(尽管上述每个都可以工作).

Roll只是一个很大的交换

你真的只是用下面的nj元素交换j个元素.

假设您在堆栈上有这个混乱(其中$ TOS $标记堆栈的顶部),并且想要正确地订购它:

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$
Run Code Online (Sandbox Code Playgroud)

向上计数(向下)nj.

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
Run Code Online (Sandbox Code Playgroud)

j的负值只是将相对于n个元素中最深元素的分界线定位(从下面开始计算).

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
Run Code Online (Sandbox Code Playgroud)

这是一个便利函数,它提供了一个与大交换视图更接近的滚动界面.

% 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
Run Code Online (Sandbox Code Playgroud)

输出:

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>
Run Code Online (Sandbox Code Playgroud)