生成Brainf *** NOP


26

有时,在编写脑力激荡的代码时,您会感到需要使其长度超过鼓励调试的时间。您可以通过><在其中放一个来做到这一点,但是那有什么乐趣呢?您将需要更长或更短的NOPey,以使任何人都无法阅读您的代码。

快速入门Brainfuck

BrainfuckUrbanMüller于1993年创建的一种深奥的编程语言,以其极简主义而著称。(维基百科)

Brainfuck是一种基于八种命令的语言:+-><,.[]。该代码在图灵机之类的东西上运行:可以在上面更改值的无限磁带。在此挑战中,我们将重点关注前四个:

+    increment the value at the pointer
-    decrement the value at the pointer
>    move the pointer right
<    move the pointer left

脑干NOP

脑干NOP是一系列脑干角色,当从任何状态执行时,脑筋都不会改变状态。它们由上述四个字符组成。

挑战

面临的挑战是编写一个程序或函数,当执行该程序或函数时,将生成给定长度的随机性NOP。

输入项

您将收到一个非负偶数整数作为输入n。(NOP不可能是奇数n。)

输出量

您将输出一个长度为的随机性NOP n

规则

  • NOP的定义:在将程序的输出插入到Brainfuck程序的任何位置时,该程序的行为不得以任何方式改变。换句话说,它不得更改解释器的状态。
    • 请注意,例如+>-<,这是不正确的,因为它更改了两个单元格的值而没有将它们改回来。发布前,请先测试您的解决方案。
    • 另请注意,这+>-<->+<是一个NOP,仅通过删除就不能将其减少为零>< <> +- -+。因此,您不能使用仅将它们彼此插入的算法。
  • 长度的每个有效NOP n必须有非零的机会出现在输出中。但是,分布不必一定是统一的。
  • 讨论中的“脑干”解释器具有无限精确的任意精确细胞带。也就是说,您可以无限地向两个方向移动,并无限地增加/减少每个单元格。
  • 该程序必须在1分钟内在n我的计算机上完成= 100,因此不能生成所有可能的NOP并选择一个。
  • 如果输入的内容无效(非整数,负数,奇数等),则可以执行任何您想做的事情,包括崩溃。

计分

这是,因此最短的答案以字节为单位。

例子

这是n= 4的所有有效输出:

++--    +-+-    +--+    --++    -+-+    -++-
>><<    ><><    ><<>    <<>>    <><>    <>><
><+-    ><-+    <>+-    <>-+
>+-<    >-+<    <+->    <-+>
+><-    -><+    +<>-    -<>+
+-><    -+><    +-<>    -+<>

以下是n= 20 的一些可能的输出:

+>>->+<->-<<<->>++<<
>+>-<+<->+-<>->+<-<+
+--+-++--++-+--+-++-
>>>>>>>>>+-<<<<<<<<<

18
这是一个不按照+-<>您的要求使用的操脑NOP :a
Undergroundmonorail

1
我不认为存在非简单的NOP,因此您可以删除该限定条件。.具有副作用,,覆盖不使用不能恢复的值[]。但是[]最终将值设置为零。[]除非我们可以确定受影响的单元格从零开始,否则这也会覆盖一个值(因此我们需要另一个值来恢复它)。但是,我们必须使用来搜索类似的单元格[>],并且不可能可靠地返回到我们所在的位置。
马丁·恩德

4
@Eumel“有问题的大脑解释器具有无限精确的任意精确细胞带。”
马丁·恩德

2
请注意,系统级别的问题标题中不再允许使用“ Brainfuck”。看来您可以使用非ASCII字符来规避该限制。将来,请遵守此限制。
Alex A.

2
@undergroundmonorail好吧,它已经完成了图灵处理,因此从技术上讲,它可以像其他任何语言一样用PRNG编写PRNG。(尽管播种可能很困难。)
PurkkaKoodari 2015年

Answers:


13

CJam,62 59字节

感谢nhahtdh节省了3个字节。

因为不需要任何特定的分布,只要每个无操作以有限的概率出现,我们就可以通过简单地生成分别包含平衡数量的-+和的字符串<>,测试它是否为NOP并对其进行排序将其简化很多不是。

当然,对于更长的输入,这几乎总是会导致排序输出,但是您可以使用一些输入来测试代码,就像8看到它原则上可以产生给定长度的任何NOP一样。

ri_0a*\2/{;"-+<>":L2/mR}%smr:SL["Xa.Xm"3/2e*L]z:sers~0-S$S?

在线尝试。


1
是的...任意限制应在10秒内为n = 1000。如今,计算机只是快速发展的一种方式^^因为即使n = 1000,算法答案也能在一秒钟之内解决问题
Falco 2015年

对于更大的n,我认为如果平衡字符串不是NOP,则可以仅对输出进行排序。分布严重扭曲,但问题允许。
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ 2015年

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳这是一个好主意。
马丁·恩德

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳谢谢,实际上,这里也保存了三个字节。
马丁·恩德

16

CJam,118个 116字节

这有点失控了……尤其是下半场似乎应该很容易打高尔夫球。

ri2/_)mr:R-"<>"R*mr_'=fm0\{1$+}%+__&e`]:\{mr1aa..+}*\@](\z:~\{~\("+-"*mr1$3$e=[{_,)mr_2$<@@>}*+]@@f{`1$`={(}@?\}W<}/

在这里测试。

N = 100几乎可以立即处理。我现在没有时间编写代码的完整分类,所以这里是算法:

  • 生成的随机平衡串<>用随机的(偶数)之间的长度0N包容性。
  • 将磁带头位置弄乱到该阵列中。例如"<>><"变为[0 '< -1 '> 0 '> 1 '< 0]
  • 获取此过程中到达的所有职位的列表。
  • 对于每个这样的位置,初始化一个空字符串。还要确定剩下多少对字符才能达到一个长度字符串N
  • 对于其余每个对,请附加+-到随机位置的字符串。
  • 随机播放所有这些字符串。
  • 对于每个位置,确定该位置在小格数组中出现的频率,然后将相应的字符串拆分为多个(随机长度)的块。
  • 在小数组中,将位置的出现替换为随机块。

做完了 基于以下观察:

  • 任何NOP的数量必须相等,<并且>要将磁带头返回到原始位置。
  • 该代码将是NOP,只要每个磁带单元的增加频率与减少的频率相同即可。

通过在磁带头位于给定单元上的所有位置之间分配随机且平衡的+s和-s 量,我们确保找到所有可能的NOP。


4

Mathematica,350个字节

Quiet@(For[a="+",If[{##4}=={},#3!=0||Union@#!={0},Switch[#4,"+",#0[ReplacePart[#,#2->#[[#2]]+1],#2,#3,##5],"-",#0[ReplacePart[#,#2->#[[#2]]-1],#2,#3,##5],">",#0[#~Append~0,#2+1,#3+1,##5],"<",If[#2<2,#0[#~Prepend~0,1,#3-1,##5],#0[#,#2-1,#3-1,##5]]]]&@@{{0},1,0}~Join~Characters@a,a=""<>RandomSample@Flatten@RandomChoice[{{"+","-"},{">","<"}},#/2]];a)&

太久了?是。我什至在乎吗?直到有人发布有效答案。


4
您介意添加一个解释,以便人们实际上可以说服自己这是有效的吗?:)
马丁·恩德

究竟如何这项工作?如果我用数字调用该函数,则仅返回+
马丁·恩德

@MartinBüttner修复...当前,它仅生成具有相等数量的+- -<- >对的随机程序,直到一个碰巧是NOP。它的一半由一个简单的BF解释器获取。
LegionMammal978

在一分钟之内实际上会产生有效的长度为100的无操作吗?
马丁·恩德

@MartinBüttner是的。平均来说,这大约需要5秒钟。起初,我试图完全随机的方案,但它永远不会终止,长100
LegionMammal978

2

Python 3,177字节

from random import*
n=int(input())
r=[0]*n*3
p=0
a=[43,45]
s=choices(a+[60,62],k=n)
for c in s:p+=~c%2*(c-61);r[p]+=c%2*(44-c)
if any(r+[p]):s=a*(n//2)
print(*map(chr,s),sep='')

在线尝试!

我将Bubbler答案中的代码用于BF模拟。


2

Python 3,163字节

from random import*
n=int(input())
p=0;d=[0]*n;a=choices(b'+-<>',k=n)
for c in a:d[p]+=c%2*(44-c);p+=~c%2*(c-61)
if p|any(d):a=n//2*b'+-'
print(*map(chr,a),sep='')

在线尝试!

将结果打印到STDOUT的完整程序。运行BF代码的行可能是可打高尔夫球的。

采用Tyilo的方法;如果生成的BF代码不是NOP,则将其完全丢弃,然后退回至'+-'重复。


n = 100
l4m2的

@ l4m2没有注意到该要求。固定。
Bubbler


1

Wolfram语言(Mathematica),224个字节

(s=RandomSample[##&@@@Table["<"">",(r=RandomInteger)[#/2]]];While[(g=Length@s)<#,s=Insert[s=Insert[s,"+",i=r@g+1],"-",RandomChoice@@Select[GatherBy[0~Range~++g,Count[#,"<"]-Count[#,">"]&@Take[s,#]&],!FreeQ[#,i]&]+1]];""<>s)&

在线尝试!

这是未高尔夫(或预高尔夫)的版本:

Function[{n},
 k = RandomInteger[n/2];
 s = RandomSample[## & @@@ Table["<" ">", k]];
 While[Length[s] < n,
   s = Insert[s, "+", i = RandomInteger[Length[s]] + 1];
   p = GatherBy[Range[0, Length[s]], 
     Count[#, "<"] - Count[#, ">"]& @ Take[s, #]&];
   j = RandomChoice @@ Select[p, ! FreeQ[#, i] &]];
   s = Insert[s, "-", j + 1];
   ];
 ""<>s]

我们首先挑选的随机数<的和>的使用,产生数目相等各随机列出。

要填充其余字符,我们选择要在其中添加+的位置,然后找到指针指向相同位置的位置并在其中添加一个位置-

重复进行操作,直到列表的长度为n,然后对结果进行字符串化。

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.