Answers:
*
输出因为您可以通过在堆栈上保留一个字符串来输出,所以使用*
而不是使用S
。假设您的挑战是“采用字符串并添加空格”,那么使用输出的方式将是:
S( )S
*
另一方面,使用的方式要短一个字节:
( )*
问题是,如果您的输出有很多累积,则可能需要花费字节来处理堆栈上的输出元素。
如果您需要大量使用一段代码,则将代码存储在堆栈中并不时地进行复制和评估是很有意义的。到目前为止,这只是正常的Underload编程。不幸的是,将值长时间保留在堆栈上很困难,并且容易使您的代码变得冗长,即使值是函数而不是数据,也是如此。如果您有多个功能需要重复使用,则情况会更糟。
在可能会从多个重用函数中受益的大型程序中,您可以使用的解决方案是根据调用的方式(使其基于栈中的底层内容,或通过使用更长的呼吁不仅仅是序列^
;浓墨重彩的功能,可以区分^^
从^:^
从^*^
从^~^
,为您提供四个不同的,相当短序列)。您还可以在此“字典”中存储其他有用的东西,例如您多次使用的字符串。请注意,如果您大量使用字典,可以将其做成一种木盒,将其自身的副本推回堆栈中,这样就无需手动复制字典了。:
以便能够使用它而不会失去将来使用它的能力。
^!!!!^
样式查找来做字典(在页面上的其他一些示例中,尤其是在最小化部分中,我也使用了该示例。)尽管这可能无法提供最短的查找。
举一个简单的例子,布尔的最常见实现是!()
针对false(即整数0),而对于null字符串则为true(即整数1),但是如果您遇到的一个严重依赖于逻辑XOR的问题,它可能会将null字符串用于false和~
true的意义(可以使用将该数据格式转换为任何其他布尔格式(false)~(true)~^!
,并且允许*
XOR 非常简洁的实现。
可以进一步推广这一通用原理,并使用程序稍后将需要的功能作为数据值的一部分。这样就不必将函数和数据分别存储在堆栈中。这可能会使控制流程变得更加混乱,但是在打高尔夫球时,可维护性通常必须放在后座,这并不是说欠载仍然可以使用。
(!)
和(~!)
用于布尔值,但是您的方法似乎更好。
减少教堂数字的功能纯净的方法是使用Lambda微积分的前任功能:
\n.n(\p.\z.z($(pT))(pT))(\z.z0[whatever you define the predecessor of 0 to be])
其中0 = \ x。\ yy,T = \ x。\ yx,而$是后继。
用欠载重写,这是28个字节:
(!())~(!())~(!:(:)~*(*)*~)~^!
没关系,但是我们可以利用Underload的一些有用属性,即that :!
and ()*
do是no-ops。这意味着,对于一个数n
,:ⁿ!!()()*ⁿ
(其中cⁿ
被c
重复n
次)产生n-1个。例如,对教会数字3执行此操作将得出以下结果:
:::!!()()***
删除无操作对,我们得到:
:*
是2
因此,这是新的且更短的先前操作:
:(:)~^(!!()())*~(*)~^*
这短了7个字节。
(()~(:))~:(^!!())*~(*)~^**
仍然要短3个字节。
Underload实际上有两个堆栈-字符串堆栈和构成源代码的命令堆栈。Underload的^
指令使我们可以将字符串从前一个堆栈移动到后者。通过这样做,我们可以节省很多不必要的堆栈操作。
例如,假设我们(a)(b)(c)
在主堆栈上,并且我们想将最下面的两个元素(ignore)串联起来(c)
,以获得get (ab)(c)
。最简单的方法是旋转堆栈以获取(c)(a)(b)
,然后conconantate和交换回去:
a~a~*~a*^*~
这是不好的。使用a~a~*~a*^
旋转栈这样是极其昂贵的,应该尽量避免。通过放入(c)
程序空间,它可以缩短四个字节:
a(*)~*^
想法是接受您要执行的指令,然后添加一条指令以最后推(c)
回去,然后评估结果。这意味着我们不必担心,(c)
直到完成后再将其推回去。
(*)~a*^
,我认为它更具可组合性。本质上~a*^
是dip
Joy发出的命令。
eval
命令,我以前从未见过像这样的语言。