教会布尔


33

布尔布尔教堂

堂布尔是一个函数,返回x为真,y假其中x是第一个参数的功能,y是第二个参数的功能。这些功能可以构成其他功能,这些功能代表and not or xorimplies逻辑操作。

挑战

构建教堂和布尔and not or xorimplies教堂大门在你选择的语言。and or并且xor应接受两个函数(代表教堂布尔值)并返回一个函数(代表另一个教堂布尔值)。同样,not应该反转它需要的功能,并且implies门应该执行布尔值隐含逻辑,其中第一个参数implies第二个。

计分

制作教堂所需的所有代码的总长度,true以及false使用您的语言and not or xor以及implies教堂和教堂大门所需要的代码,不包括功能名称。(例如,false=lambda x,y:y在Python中为13个字节)。您可以稍后在代码中重用这些名称,使它们的计数占该门的总字节数为1个字节。

伪代码示例:

您创建的函数应该可以稍后在您的代码中这样调用。

true(x, y) -> x
false(x, y) -> y
and(true, true)(x, y) -> x
and(true, false)(x, y) -> y
# ... etc

2
我们是否必须将函数输入(或最接近的替代项)视为黑盒函数,还是可以检查其中的代码?逻辑运算的返回值是否必须与先前定义为Church布尔值的函数具有相同的函数,或者它们是否可以是做相同事情的其他函数?
不相关的字符串

1
@JonathanAllan我对其进行了编辑,因此它是正确的。提示是应该的。
瑞安·谢弗

2
我们可以把列表作为参数(例如true([x, y])and([true, true])([x, y]))?
ar4093

2
@RyanSchaefer我认为您应该重新考虑允许将参数放在有序列表中,因为可以将参数简单地包装在解决方案的开头。我不认为要求采取任何措施来改善这一挑战(事实上,我认为这限制了有趣的高尔夫潜力)。当然,这只是我的意见,如果您不同意,也可以。
FryAmTheEggman

1
得分相当混乱。那岂不是更好地让人们提交匿名函数,但如果他们在其他地方使用他们,他们必须给它们,就像往常一样
乔金

Answers:


14

二进制Lambda微积分13.875 12.875字节(103位)

John Tromp的Binary Lambda微积分语言(BLC)基本上是一种有效的lambda微积分序列化格式。这非常适合此任务,因为教堂符号甚至是BLC中使用布尔值的“惯用”方式。

我对组合器使用了以下lambda函数,其中一些是我从Haskell答案复制并打高尔夫球的:这些是通过详尽搜索而发现的,每种情况的证明极限均为20β约简。这些极有可能是最短的。

True:  (\a \b a)
False: (\a \b b)
Not:   (\a \b \c a c b)
And:   (\a \b b a b)
Or:    (\a a a)
Xor:   (\a \b b (a (\c \d d) b) a)
Impl:  (\a \b a b (\c \d c))

这些转换为以下(二进制)BLC代码序列:

 bits |  name | BLC
------+-------+---------
    7 | True  | 0000 110
    6 | False | 0000 10
   19 | Not   | 0000 0001 0111 1010 110
   15 | And   | 0000 0101 1011 010
    8 | Or    | 0001 1010
   28 | Xor   | 0000 0101 1001 0111 0000 0101 0110
   20 | Impl  | 0000 0101 1101 0000 0110

以上功能的总长度为111位(13.875字节),长度为103位(12.875字节)。它们不需要与字节边界对齐即可在程序内使用,因此计算小数字节是有意义的。

组合器之间没有代码可重复使用,因为BLC中没有变量/引用/名称-所有内容都必须复制。仍然,编码的效率使简洁的表示成为可能。


1
我不了解blc,但是可以And: (\a \b a b a)吗?
tsh

是的,它有效。我实际上将此公式用于代码序列。我只是忘了更新相应的lambda函数(现已更正)。等效功能适用于或者:\a \b a a b。它比我在BLC中使用的更长。
帕维尔·波托切克

25

Haskell50-6 = 44字节

-1个字节感谢Khuldraeseth na'Barya,-1个字节感谢Christian Sievers。

t=const
f=n t
n=flip
a=n n f
o=($t)
x=(n>>=)
i=o.n

在线尝试!


2
旁注:您可以Showconst和定义实例,然后const id直接打印教堂的布尔值。在线尝试!
nimi


4
为什么没人使用f=n t
Christian Sievers

3
您可以使用t=pure代替来保存一个字节t=const
约瑟夫·西布尔

4
@JosephSible我最初尝试过。不幸的是,t=pure当我尝试应用将导致一个错误aox,或i给它。声明t修复此问题的类型比使用花费更多的字节t=const
Nitrodon

9

Python 2,(-3?) 101  95字节

大卫·比兹利(David Beazley)伤了你的心!

-6感谢Chas Brown(将重复的内容:移到了连接文本>。<中)

exec'=lambda x,y=0:'.join('F y;T x;N x(F,T);A x(y,F);O x(T,y);X x(N(y),y);I O(y,N(x))'.split())

在线尝试!

我想可能是95 - 3因为我不重复使用的功能AX或者I,但我用一个单一=的分配(在前面lambda)。也许我无法删除任何内容;也许我什至可以删除3.5?


@Ryan Schaefer我可以删除三个exec吗,还是我不能用这个意思?我可以看到任一种方式-我不重用A,X或I,但是没有它们,代码将无法工作。(也许我什至可以删除3.5 ?!)
乔纳森·艾伦


谢谢@Chas!穿过网的冒号:)替换-1 BTW的好工作
乔纳森·艾伦

7

JavaScript(Node.js)92 86 83-7 = 76字节

t=p=>q=>p
f=t(q=>q)
n=p=>p(f)(t)
a=p=>n(p)(f)
o=p=>p(t)
x=p=>p(n)(f())
i=p=>n(p)(t)

在线尝试!链接包括基本测试用例。编辑:由于@tsh,节省了6 9个字节。


1
看来你不能说这是因为-7 tfn被使用。
tsh

1
@tsh这不是我对计分系统的理解;尽管使用中的名称花费1个字节,但它在定义中明确排除了该名称。
尼尔

@Neil你不能索赔由您的代码调用(函数名字节的折扣tfn你的情况)。
asgallant

2
@asgallant没有。名称没有字节,以后使用时只有1个字节。稍后使用时,“ T fnaox i”为1个字节,没有字节。我想提高可读性,但现在我意识到我应该把它完全打高尔夫球,现在进行更改为时已晚
Ryan Schaefer

@RyanSchaefer那条规则在哪里?我从未见过如此做。
asgallant

6

Python 2中133 - 6 = 127个 94字节

exec"t!u;f!v;n!u(f,t);a!u(v,f);o!u(t,v);x!u(n(v),v);i!o(v,n(u))".replace('!','=lambda u,v=0:')

在线尝试!

无耻地偷偷乔纳森·艾伦回答背后的偷偷摸摸的主意;虽然没有扣除字节。


我本来打算回答自己的问题,但不确定是否允许这样做,我认为这违背了它的精神。所以我想我会指导您。除了使用列表之外,您是否还可以使用自己正在输入的函数以及它们返回输入的特定方式来缩短代码?
瑞安·谢弗

我敢打赌,尽管答案是肯定的,但在Python中它会更长。
不相关的字符串

我的立场更正
不相关的字符串

@ Mr.Xcoder您是正确的,示例函数的字节数错误。尽管允许删除函数名称的6个字节。
Ryan Schaefer

@先生。Xcoder:根据您的观察进行修改。
查斯布朗

4

J,67个字节-7 = 60

t=.[
f=.]
n=.~
a=.2 :'u v]'
o=.2 :'[u v'
x=.2 :'u~v u'
i=.2 :'v u['

在线尝试!

值得注意:

在J语言中,高阶函数的工作方式不同于在功能语言中。要从1个或2个现有动词创建新动词,您需要使用副词(在1的情况下)或连词(在2的情况下)。

从句法上说,副词位于动词之后,而连词位于它们之间。因此,要“不” f做一个动词f n,而要“和”一个动词fand g,您f a g


4

Wolfram语言(Mathematica),61-7 = 54字节

t=#&
f=#2&
a=#2~#~f&
o=t~#~#2&
n=f~#~t&
x=n@#~#2~#&
i=#2~#~t&

在线尝试!

非高尔夫:受维基百科启发,

t[x_, y_] := x
f[x_, y_] := y
and[x_, y_] := x[y, f]
or[x_, y_] := x[t, y]
not[x_] := x[f, t]
xor[x_, y_] := y[not[x], x]
imply[x_, y_] := x[y, t]

可以肯定的是,换行符对于分隔函数定义是必需的。另外,您在其他函数定义中引用了tf和n,因此您无法扣除这些定义,因此61-4 = 57。
乔纳森·艾伦

@JonathanAllan我已经重新阅读了得分说明,并同意换行应该计算在内,谢谢。我不同意您的第二部分:当我重复使用名称时,的确将它们算作“朝向该门的字节总数的1个字节”,这在这里是隐含的,因为我使用的是1个字节的名称。在我阅读说明的过程中,没有提及将它们也计为原始定义总数的一个字节。所以我要使用N-7个字节。另外,OP的另一条评论阐明:“名称没有字节,以后使用时只有1个字节。”
罗马

我读了“稍后再发送1个字节”,这意味着在另一个函数中使用它需要花费一个字节。这也与其他人的评分方式保持一致。
乔纳森·艾伦

@JonathanAllan我在注释不太感兴趣,更在代码高尔夫😀
罗马

4

欠载56 52字节

(~!)(!)((~)~*):((!)~^)*(:^)(~(!)~^(~)~*)(()~(~)~^~*)

在线尝试!(包括测试套件和识别程序部分的文本)

对于非常低水平的雪兰莪,这得分令人惊讶地好。(出于这个原因,教堂数字,教堂布尔值等在欠负载中非常常用;该语言没有内置数字和布尔值,这是模拟它们的较简单方法之一。也就是说,将布尔值编码为教堂数字0和1。)

对于任何困惑的人:Underload允许您定义可重用的函数,但不允许您以常规方式命名它们,它们只是在参数堆栈上浮动(因此,如果您定义了五个函数,然后想调用第一个函数,您定义的代码需要编写一个新函数,该函数需要五个参数并调用其中的第五个参数,然后在参数不足的情况下调用它,以便查找要使用的备用参数。调用它们默认会销毁它们,但是您可以修改该调用以使其无损(在简单情况下,您只需在该调用中添加一个冒号,尽管在复杂情况下更常见,因为您需要确保副本不会妨碍您的操作),因此Underload的功能支持满足了我们从问题中获得的所有要求。

说明

真正

(~!)
(  )  Define function:
 ~      Swap arguments
  !     Delete new first argument (original second argument)

这很简单;我们摆脱了我们不想要的参数,而我们想要的参数仅停留在那里,作为返回值。

(!)
( )   Define function:
 !      Delete first argument

这甚至更简单。

((~)~*)
(     )  Define function:
    ~*     Modify first argument by pre-composing it with:
 (~)         Swap arguments

这很有趣:not根本不调用其参数,而只是使用函数组合。这是Underload中的一个常见技巧,其中您根本不检查数据,而只是通过对数据进行预组合和后组合来更改其功能。在这种情况下,我们修改函数以在运行前交换其参数,这显然会否定教堂数字。

:((!)~^)*
 (     )   Define function:
     ~^      Execute its first argument with:
  (!)          false
               {and implicitly, our second argument}
        *  Edit the newly defined function by pre-composing it with:
:            {the most recently defined function}, without destroying it

该问题允许根据其他功能来定义功能。接下来,我们定义“和”,因为最近定义的“非”越容易使用。(这不会从分数中减去,因为我们根本没有命名为“ not”,但是它节省了字节,无需再次写入定义。这是一个函数唯一引用另一个函数的唯一一次,因为引用任何函数但最近定义的字节数过多。)

这里的定义是and x y = (not x) false y。换句话说,如果not x,那么我们返回false;否则,我们返回y

要么

(:^)
(  )  Define function:
 :      Copy the first argument
  ^     Execute the copy, with arguments
          {implicitly, the original first argument}
          {and implicitly, our second argument}

@Nitrodon在注释中指出,该注释or x y = x x y通常短于or x y = x true y,并且在Underload中也正确。一个简单的实现是(:~^),但是我们可以注意到一个额外的字节,不管我们运行原始的第一个参数还是它的副本都没有关系,无论哪种方式,结果都是相同的。

欠载实际上并不支持通常意义上的curring,但是像这样的定义使其看起来像它!(诀窍是未使用的参数会停留在周围,因此您调用的函数会将它们解释为自己的参数。)

暗示

(~(!)~^(~)~*)
(           )  Define function:
 ~               Swap arguments
     ~^          Execute the new first (original second) argument, with argument:
  (!)              false
                   {and implicitly, our second argument}
       (~)~*     Run "not" on the result

这里使用的定义是implies x y = not (y false x)。如果y为true,则简化为not false,即true。如果y为假,则简化为not x,从而得到所需的真值表。

在这种情况下,我们将not通过重写代码而不是引用它来再次使用。它只是直接编写(~)~*而没有括号,因此它被调用而不是定义。

异或

(()~(~)~^~*)
(          )  Define function:
   ~   ~^       Execute the first argument, with arguments:
    (~)           "swap arguments"
 ()               identity function
         ~*     Precompose the second argument with {the result}

这次,我们仅评估两个参数之一,并使用它来确定第二个参数的构成。Underload使您可以快速而轻松地使用arity,因此我们使用第一个参数在两个两个参数的两次返回函数之间进行选择;参数swap以相反的顺序返回两者,而identity函数以相同的顺序返回它们。

因此,当第一个参数为true时,我们将生成第二个参数的编辑版本,该版本将在运行之前交换其参数,即,使用“交换参数”进行预组合,即not。因此,真正的第一个参数意味着我们返回not第二个参数。另一方面,错误的第一个参数意味着我们与身份函数组合在一起,即什么也不做。结果是的实现xor


or x y = x x y节省一些字节or x y = x true y
Nitrodon

当使用重用变量替换文字时,欠载通常是违反直觉的,但是在这种情况下,这种转换节省的字节多于预期,而不是更少。感谢您的改进!
ais523


3

爪哇8,得分:360 358 319 271 233(240-7)个字节

interface J<O>{O f(O x,O y,J...j);}J t=(x,y,j)->x;J f=(x,y,j)->y;J n=(x,y,j)->j[0].f(y,x);J a=(x,y,j)->j[0].f(j[1].f(x,y),y);J o=(x,y,j)->j[0].f(x,j[1].f(x,y));J x=(x,y,j)->j[0].f(j[1].f(y,x),j[1].f(x,y));J i=(x,y,j)->j[0].f(j[1].f(x,y),x);

这比我刚开始时想的要难得多implies。无论如何,它都能正常工作。编辑:好的,不重复使用函数,而只是复制相同的方法就Java的字节数而言便宜很多。而且由于不使用任何函数,我也获得了-7分的全额奖励。

在线尝试。

说明:

// Create an interface J to create lambdas with 2 Object and 0 or more amount of optional
// (varargs) J lambda-interfaces, which returns an Object:
interface J<O>{O f(O x,O y,J...j);}

// True: with parameters `x` and `y`, always return `x`
J t=(x,y,j)->x;
// False: with parameters `x` and `y`, always return `y`
J f=(x,y,j)->y;

// Not: with parameters `x`, `y`, and `j` (either `t` or `f`), return: j(y, x)
J n=(x,y,j)->j[0].f(y,x);

// And: with parameters `x`, `y`, and two times `j` (either `t` or `f`), return:
//      j1(j2(x,y), y);
J a=(x,y,j)->j[0].f(j[1].f(x,y),y);

// Or: with parameters `x`, `y`, and two times `j` (either `t` or `f`), return:
//     j1(x, j2(x,y))
J o=(x,y,j)->j[0].f(x,j[1].f(x,y));

// Xor: with parameters `x`, `y`, and two times `j` (either `t` or `f`), return:
//      j1(j2(y,x), j2(x,y))
J x=(x,y,j)->j[0].f(j[1].f(y,x),j[1].f(x,y));

// Implies: with parameters `x`, `y`, and two times `j` (either `t` or `f`), return:
//          j1(j2(x,y), x)
J i=(x,y,j)->j[0].f(j[1].f(x,y),x);

2

C ++ 17,207−49 = 158 195 − 58 = 137字节

换行符不是必需的(前两个除外)。

#define A auto
#define D(v,p)A v=[](A x,A y){return p;};
D(true_,x)
D(false_,y)
A not_=[](A f){return f(false_,true_);};
D(and_,x(y,false_))
D(or_,x(true_,y))
D(xor_,x(not_(y),y))
D(implies,x(y,true_))

在线尝试!

用断言进行单元测试,例如:

static_assert('L' == true_('L', 'R'));
static_assert('R' == not_(true_)('L', 'R'));
static_assert('L' == and_(true_, true_)('L', 'R'));
static_assert('L' == or_(true_, true_)('L', 'R'));
static_assert('R' == xor_(true_, true_)('L', 'R'));
static_assert('L' == implies(true_, true_)('L', 'R'));

更新:以前我有

A not_=[](A f){return[f](A x,A y){return f(y,x);};};

但是罗曼的回答为更短的版本指明了方向。请注意,现在not_(std::plus<>)格式不正确,以前它等同于std::plus<>;。但由于std::plus<>它并不“代表教会的布尔值”,因此我认为任何一种行为在规则上都可以。


不应将“除第一个以外的其他”更新为“除前两个以​​外的其他”吗?
LF

@LF:绝对正确。更新。:)
Quuxplusone

2

如(gforth) 133个字节- 7 = 126 122

: j execute ;
: t drop ;
: f nip ;
: n ['] f ['] t rot j ;
: a dup j ;
: o over j ;
: x 2dup a n -rot o a ;
: m over n -rot a o ;

在线尝试!

-4个字节,得益于Quuxplusone

最初,我考虑到宏和文字之类的东西时大大超乎想象,但是后来我意识到,如果我用对与错来定义事物(像我本来应该做的那样),就会变得更加简单。

代码说明

\ Helper function to save some bytes
: j        \ define a new word
  execute  \ execute the word at the provided address
;          \ end word definition

\ True
: t        \ define a new word
  drop     \ drop the second argument
;          \ end the word

\ False
: f        \ define a new word
  nip      \ drop the first argument
;          \ end the word

\ Not - The "hardest" one because we have to reference true and false directly
: n        \ define a new word
  ['] f    \ get address of false
  ['] t    \ get the address of true
  rot      \ stick the input boolean back on the top of the stack
  j        \ call the input boolean, which will select the boolean to return
;          \ end the word

\ And 
: a        \ define a new word
  dup      \ duplicate the 2nd input value
  j        \ call the 2nd input on the first and second input
;          \ end the word

\ Or
: o        \ define a new word
  over     \ duplicate the 1st input value
  j        \ call the 1st input on the first and second input
;          \ end the word

\ Xor
: x        \ define a new word
  2dup     \ duplicate both of the inputs
  a n      \ call and, then not the result (nand)
  -rot     \ move the result behind the copied inputs
  o a      \ call or on the original inputs, then call and on the two results
;          \ end the word

\ Implies
: m        \ define a new word
  over     \ duplicate the 1st input value
  n        \ call not on the 1st input value
  -rot     \ move results below inputs
  a o      \ call and on the two inputs, then call or on the two results
;          \ end the word

1
您重复长词execute三遍。定义速记: j execute ;将为您节省4个字节。
Quuxplusone

1

SKI微积分+ C组合器,36字节

true=K
false=SK
not=C
and=CC(SK)
or=CIK
xor=C(CIC)I
implies=CCK

我实际上不知道有哪个解释器可以让您根据先前的解释器定义其他组合器,因此我不得不使用http://ski.aditsu.net/进行测试,方法是粘贴所需的组合CCKK(SK)pqq,例如output ,表明K不暗示SK


1

朱莉娅1.0,36字节

(b::Bool)(x,y)=b ? x : y;i(x,y)=!x|y

我不知道这是否有意义,实际上我只是在重载Bool可调用的本机类型,因此我免费获得了大多数逻辑门。不幸的是,茱莉亚(Julia)没有implies门,所以我不得不编写自己的函数。

在线尝试!


我认为您仍然需要在提交中包括重载的运算符...但是由于它们只是名称,因此得分不会计入它们?因此,换行符将是+6个字节?我不是太肯定的得分这个挑战是如何工作
乔金

我也不是100%知道它是如何工作的,但是必须包含实际上不执行任何操作的代码对我来说没有任何意义。
user3263164

即使已经声明了代码,您仍然必须将其包括在内,否则所有其他高尔夫语言提交都将为零字节。你只是没有将其分配到任何东西
乔金


1

C ++ 17,202−49 = 153 193 − 58 = 135字节

受到评论讨论的启发,无论如何都应视为2元函数,这是我以前的C ++ 17解决方案的简化版本。它实际上更短,因为我们可以使用与not_定义所有其他功能相同的宏来定义!

#define D(v,p)auto v=[](auto x){return[=](auto y){return p;};};
D(true_,x)
D(false_,y)
D(not_,x(false_)(true_)(y))
D(and_,x(y)(false_))
D(or_,x(true_)(y))
D(xor_,x(not_(y))(y))
D(implies,x(y)(true_))

在线尝试!

这是通过断言测试的

static_assert('R' == and_(true_)(false_)('L')('R'));
static_assert('L' == or_(true_)(false_)('L')('R'));

注意,or_定义为有效

auto or_=[](auto x){return[=](auto y){return x(true_)(y);};};

我们可以or_更“简洁地” 定义为

auto or_=[](auto x){return x(true_);};

但这将使我们付出代价,因为我们D不再使用宏。


由于C ++区分大小写,如何使用TrueFalse代替true_and false_?与其他运营商相似。这样可以节省12个字节。
G. Sliepen

@ G.Sliepen:OP的评分算法已经考虑到标识符实际上是一个字符长。Quote:“在您的语言中使Church为真和假以及and和not或xor所需的所有代码的总长度,这意味着教堂大门不包括函数名称。(例如,Python中的false = lambda x,y:y将是13个字节)。您可以稍后在代码中重复使用这些名称,它们会将1个字节计为该门的总字节数。”
Quuxplusone

啊,我错过了。
G. Sliepen

0

APL(dzaima / APL),47 字节SBCS

基于Jonah的J解决方案

truefalse是缀函数,not是一个后缀操作者,和其余的是中缀运算符。

true←⊣
false←⊢
and←{⍺(⍶⍹false)⍵}
not←⍨
or←{⍺(true⍶⍹)⍵}
xor←{⍺(⍶not⍹⍶)⍵}
implies←{⍺(⍹⍶true)⍵}

根据OP,此操作会将每行(包括行)到行尾的所有内容计数在内,并将每个调用的前一个定义计为一个字节。

在线尝试!

true和false是左右标识函数。

not 只需交换其操作数函数的参数。

其余的执行决策树:

and如果为true,则使用右手函数选择左手函数的结果,否则选择函数的结果false

or使用lefthand函数选择truetrue,否则选择righthand函数的结果

xor如果为true,则使用右手函数选择左手函数的求反结果⍶not,否则使用左手函数的结果。

implies如果为true,则使用左手函数选择右手函数的结果,否则选择函数的结果true


0

Stax,34 个字节

¿S£↓♣└²≡é♫Jíg░EèΩRΦ♂°┤rà╝¶πï╡^O|Θà

在staxlang.xyz上运行和调试它!

将一堆积木推入堆栈。每个块都希望其最后一个参数位于堆栈顶部,然后以相反的顺序排列其余的参数。

未压缩(41个字节):

{sd}Y{d}{y{d}a!}X{ya!}{b!}{cx!sa!}{sx!b!}

每对{ }都是一个块。我使用两个寄存器X和Y来保存truenot因此以后可以轻松访问它们。不幸的是,false不能简单地成为一个无操作者,因为这会使堆栈混乱并弄乱一个XOR案例。

测试套件,已评论

false
{sd}    stack:   x y
 s      swap:    y x
  d     discard: y

true
{d}    stack:   x y
 d     discard: x

not
{y{d}a!}    stack:  p
 y{d}       push:   p f t
     a      rotate: f t p
      !     apply:  p(f,t)

and
{ya!}    stack:  p q
 y       push:   p q f
  a      rotate: q f p
   !     apply:  p(q,f)

or
{b!}    stack:  p q
 b      copies: p q p q
  !     apply:  p q(q,p)

xor
{cx!sa!}    stack:  p q
 c          copy:   p q q
  x!        not:    p q nq
    s       swap:   p nq q
     a      rotate: nq q p
      !     apply:  p(nq,q)

implies
{sx!b!}    stack:  p q
 s         swap:   q p
  x!       not:    q np
    b      copies: q np q np
     !     apply:  q np(np,q)

0

Befunge-98105个 77 65字节

在没有功能的语言中进一步发挥“功能”的概念……这是教堂布尔的Befunge-98版本!

在Befunge-98的这种受限方言中,程序由一系列“行”或“函数”组成,每个行或函数>均以x = 0列中的(向右)指令开头。每个“功能”都可以通过其行号(y坐标)来识别。函数可以照常通过Befunge的堆栈获取输入。

第0行是特殊的,因为(0,0)是起始IP。要制作执行L行的程序,只需将指令放在第0行,执行时将指令指针飞到(x = L,y = 0)。

魔术发生在第1行。执行时,第1行L从堆栈中弹出一个数字,然后跳到第number行L。(该行以前是> >>0{{2u2}2}$-073*-\x,可以“绝对跳转”到任何行;但是我刚刚意识到,由于我知道该行与第1行挂钩,因此我们可以L-1用更少的代码来“相对跳转” 行。)

第2行代表Church FALSE。执行时,它将弹出两个数字tf从堆栈中弹出,然后飞到第number行f

第3行代表Church TRUE。执行时,它将弹出两个数字tf从堆栈中弹出,然后飞到第number行t

代表教堂的6号线XOR是创新的。执行时,它将弹出两个数字ab从堆栈中弹出,然后a与堆栈input对齐NOT EXEC b。因此,如果a代表教会TRUE,结果a NOT EXEC b将是NOT b;如果a代表教会FALSE,的结果a NOT EXEC b将是EXEC b


这是带有测试装置的非高尔夫版本。在第0行,使用您的输入设置堆栈。例如,338装置IMPLIES TRUE TRUE。确保关闭x出现在正好(x,y)=(0,15)处,否则将无效!另外,请确保您的堆栈设置以开头ba,以便该程序实际上将以一些输出终止。

在线尝试!

>  ba 334  0f-1x
> >>1-0a-\x             Line 1: EXEC(x)(...) = goto x
> $^< <            <    Line 2: FALSE(t)(f)(...) = EXEC(f)(...)
> \$^                   Line 3: TRUE(t)(f)(...) = EXEC(t)(...)
> 3\^                   Line 4: OR(x)(y)(...) = EXEC(x)(TRUE)(y)(...)
> 3\2\^                 Line 5: NOT(x)(...) = EXEC(x)(FALSE)(TRUE)(...)
> 1\5\^                 Line 6: XOR(x)(y)(...) = EXEC(x)(NOT)(EXEC)(...)
> 2>24{\1u\1u\03-u}^    Line 7: AND(x)(y)(...) = EXEC(x)(y)(FALSE)(...)
> 3^                    Line 8: IMPLIES(x)(y)(...) = EXEC(x)(y)(TRUE)(...)

> "EURT",,,,@
> "ESLAF",,,,,@

这是我计算字节数的版本。

>>>1-0a-\x
>$^<< }u-30\<
>\$^
>3\^\
>3\2^
>1\5^
>2>24{\1u\1u^
>3^

请注意,要在该方言中定义一个函数,您根本不会提到它的名称。其“名称”由其源位置确定。要调用一个函数,您必须提到它的“名称”。例如,XOR6)是根据NOTEXEC51)定义的。但是我所有的“函数名”都只用一个字节表示。因此,此解决方案没有评分调整。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.