编写交互式Deadfish解释器


30

Deadfish是一个带有四个命令的玩笑“编程语言”。由于Esolang页面有点矛盾,并且该页面上的解释器工作原理并不完全相同,因此您应该实现以下变体:


规格

  1. 有一个累加器,其大小至少为 16位,允许更多但不允许更少。不需要支持负数。0程序启动时就是累加器。
  2. 以下是两个包含四个命令的集合,您的程序必须同时支持两个命令。
      标准死鱼│XKCD变体│含义
      ────────────────┼────┼────────┼ ──────────────────────────
            i│x│累加器
            d│d│减量累加器
            s│k│平方(acc = acc * acc)
            o│c│输出累加器,以数字表示
    
  3. 在执行命令后,如果累加器为-1256,则必须将累加器重置为零。请注意,这不是正常的环绕。例如,如果累加器为20,并且s运行命令,则应在400其后。同样,如果累加器为257d运行命令,则累加器应变为0
  4. 任何不是这些命令之一的输入都应被忽略。

测试程序

  • xiskso 应该输出 0
  • xiskisc 应该输出 289

输入输出

您的程序应显示提示:>>。提示必须在新行的开头。然后,它应该读取一行用户输入,并从左到右运行给定的命令。输出数字时,必须将数字分开。即12 34可以,12,34可以,

12
34 

可以,但1234不能。

您的程序应继续循环执行此操作,至少直到EOF达到为止。

会话示例:

>> xiskso
0
>> xiskisc
289
>> ddddo ddddo
285
281
>> ddddo ddddo
277
273
>> dddddddo
266
>> dddddddddo
257
>> do
0
>> do
0
>> io
1
>> 

由于提示输入,我无法使用GolfScript :-(
ProgramFOX

@ProgramFOX:您可以使用红宝石输入吗?
marinus 2013年

根据GolfScript教程,您无法在GolfScript中提示输入,所有输入均来自STDIN。
ProgramFOX 2013年

@ProgramFOX:我本以为这样的方法#{STDIN.gets}可以工作,但实际上不行。
marinus 2013年

我们可以使用大写字母代替输入吗?
lirtosiast 2015年

Answers:


6

K,77个字节

  {1">>";0{x*2=-1 256?x:y@x}/("xkcdiso"!7#(1+;{x*x};{-1@$x;x};-1+))@0:0;.z.s`}`
>>xiskso
0
>>xiskisc
289

注意,这是K4。一个K6解决方案稍长,因为IO动词是更长的时间,即使一切是更好的:

{""0:">>";0{x*^-1 256?x:y@x}/("xkcdiso"!7#(1+;{x*x};{""0:,$x;x};-1+))@0:"";o`}`
  • ""0:打印并返回其参数。注意,在K4中,我们仅适用于1
  • 0 f/ args 演示以初始值减少,即 f[f[0;first arg];second arg]…
  • {x*2=-1 256?x…将x分为0(对于-1),1(对于256)和2(对于所有其他值)。2=意味着我们获得1未分类的值,0否则,乘以x比有条件的要短。在K6中,我们可以做得更好,因为它{x*^-1 256?x:y@x}依赖于-1 256?x返回0N(空)并^检测空的事实。
  • “解析器”是地图,"xkcdiso"而不是建议的顺序,因为7#它将环绕四个参数,即7#"abcd"返回"abcdabc",这使我们的表更小
  • 该地图平移"x""i"投影到投影1+,该投影等效于该函数{1+x}但更短。
  • 地图转换为与功能等效"d"的投影-1+{-1+x}但更短。
  • 地图翻译"k""s"功能{x*x}
  • 映射转换"c""o"转换为输出函数{-1@$x;x},该输出函数在K6中再次稍长:{""0:,$x;x}但是都输出其输出,然后换行,然后返回参数。
  • .zs是自递归。在K6中,我们可以简单地说出o`哪个较短。

8

Perl 5,90个字节

do{print+(map{$?+=/i|x/-/d/;$?**=1+/s|k/;$?=~s/-1|^256$/0/;"$?
"x/o|c/}/./g),'>> '}while<>

在线尝试!

感谢@xfix之前在此方面的帮助!@Xcali节省了4个字节!


1
1当累加器溢出时,程序将打印。另外,您可以通过将更$a改为$?(将其初始化为0,并且直到从Perl运行某些外部程序之后才能更改),将程序缩短五个字符。
Konrad Borowski

啊,我正在寻找可以使用的变量,完美,谢谢!至于溢出,我没有注意到它,因为它仅在您issso作为一个命令运行时才发生,而不是在您分别执行每个命令时才发生……我稍后将对此进行讨论,并且肯定会使用$?。谢谢!
Dom Hastings 2013年

所以我想我在代码部分的顶部保留了一个较旧的版本,''而不是""在与perl -e '...'地图一起使用时以的结果结尾s///。再次感谢!
Dom Hastings 2013年

好,你是最矮的。
marinus 2014年

1
不再是最短的答案。
地质车

6

的powershell,131 126 121 114 113

for($x=0){[char[]](read-host ">>")|%{switch -r($_){"i|x"{$x++}"d"{$x-=!!$x}"s|k"{$x*=$x}"o|c"{$x}}
$x*=$x-ne256}}
  • for($x=0){...} -将累加器设置为0并永远循环
  • read-host '>>' -提示用户输入 >>
  • [char[]](...) -将用户输入转换为字符数组
  • |%{...} -表演里面的东西 {}每个角色
  • switch -r($_) -每个字符的正则表达式开关
  • "i|x"{$x++} -匹配ix-增加累加器
  • "d"{$x-=!!$x} -比赛d-减少$x通过!!$x,这将是0,如果$x0,和1其他。这样可以确保累加器永远不会达到-1
  • "s|k"{$x*=$x} -匹配sk-平方
  • "o|c"{$x} -匹配oc-输出累加器
  • $x*=$x-ne256-将累加器乘以02561

输出示例

>>: xiskso
0
>>: xiskisc
289
>>: ddddo ddddo
285
281
>>: ddddo ddddo
277
273
>>: dddddddo
266
>>: dddddddddo
257
>>: do
0
>>: do
0
>>: io
1
>>:

我猜想的实现read-host是特定于主机的,因此此Powershell主机(ConsoleHost)追加:到指定的提示。


真好!爱递减!!$x,可惜我不能利用...
Dom Hastings 2013年

嘿,Danko,您能发表一些测试结果吗?我认为我无法在非Windows上测试电源外壳...(如果我错了,请纠正我!)
Dom Hastings

我已经在答案中添加了一些测试输出。
DankoDurbić13年

6

REBOL 3,178 169 161 159

f: does [if a = -1 or (a = 256)[a: 0]]d: [any[["i"|"x"](++ a f)|["d"](-- a f)|["s"|"k"](a: a * a f)|["o"|"c"](print a)| skip]]a: 0 forever [parse (ask ">>") d]

更漂亮的版本:

f: does [if a = -1 or (a = 256) [a: 0]]
d: [
    any [
        ["i"|"x"] (++ a f) |
        ["d"] (-- a f) |
        ["s"|"k"] (a: a * a f) |
        ["o"|"c"] (print a) |
        skip
    ]
]
a: 0 
forever [parse (ask ">>") d]

6

哈斯克尔(202)

r=pure;-1%c=0%c;256%c=0%c;s%'o'=s<$print s;s%'c'=s%'o';s%'i'=r$s+1;s%'x'=s%'i'
s%'d'=r$s-1;s%'s'=r$s^2;s%'k'=s%'s';s%_=r s;n s(c:[])=s%c;n s(c:f)=s%c>>=(`n`f)
main=p 0;p s=putStr">> ">>getLine>>=n s>>=p

您可以通过更改ev运算符来节省一些字符。我还尝试重写vg以便该参数x保留在IO中,print等等。我没有设法使其正常运行,但我认为对于知道其haskell的人来说,这可能是一个不错的选择。
shiona 2013年

@shiona:是的,保留这些内容IO是因为它们打印得太频繁了(这就是我使用r n而不是的原因x)或打印得不够多,因为从未要求过该值……。那么,我将如何转变ev成为运营商?
Ry-

我在打印时遇到了同样的问题。您可以做的事情涉及运算符(以e为例)'i'%x=x+1;'d'%x=x-1...只需在v中调用即可do n<-x;r$w$o%n。运算符之所以会节省空间,是因为它们不需要空格。
shiona 2013年

@shiona:哦!好电话,谢谢!
Ry-

没问题。我首先想到了自己做一个答案,但是由于我无法实现自己的大想法,所以我认为发布完全相同的代码,使用相同的符号表示相同的功能只是粗鲁的做法。
shiona 2013年

4

红宝石,140 138

a=0
loop{$><<'>> '
eval gets.gsub(/./){|c|({i:i='a+=1',x:i,d:'a-=1',s:s='a**=2',k:s,o:o='p a',c:o}[:"#{c}"]||'')+';a=a==-1||a==256?0:a;'}}

示例会话(与您的会话相同):

c:\a\ruby>deadfish
>> xiskso
0
>> xiskisc
289
>> ddddo ddddo
285
281
>> ddddo ddddo
277
273
>> dddddddo
266
>> dddddddddo
257
>> do
0
>> do
0
>> io
1
>>

4

K,121

i:0;while[1;1">> ";{i{(r;0)(-1~r)|256~r:y x}/d{x@&x in y}[x;!d:"ixdskoc"!,/(2#(1+);-1+;2#{x*x};2#{-1@$i::x;})]}'" "\:0:0]

C:\q>q deadfish.k -q
>> xiskso
0
>> xiskisc
289
>> ddddo ddddo
285
281
>> ddddo ddddo
277
273
>> dddddddo
266
>> dddddddddo
257
>> do
0
>> do
0
>> io
1
>>

我的版本较短。我压缩了地图,依靠吗?要为“包装”值分类,请使用递归而不是while,并使用功能解释器而不是amend。
地质车

4

艾达

这是对这种语言感兴趣的少数人的Ada实现。我花了一些时间才能使用Ada的一些最佳做法(例如使用Indefinite_Holders代替访问权限)以及完全理解Deadfish必须如何工作。

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Containers.Indefinite_Holders;
with Ada.Integer_Text_IO;

procedure Deadfish is
   package String_Holder is new Ada.Containers.Indefinite_Holders(String);
   use String_Holder;

   value_output : Natural := 0;
   str_input : String_Holder.Holder := To_Holder("");
begin
   Prompt :
   loop
      Put(">> ");
      String_Holder.Replace_Element(str_input, Get_Line);
      for rg in str_input.Element'Range loop
         case str_input.Element(rg) is
            when 'i' | 'x' => 
               case value_output is
                  when 255 => value_output := 0;
                  when others => value_output := Natural'Succ(value_output);
               end case;

            when 'd'       =>                   
               case value_output is
                  when 257 => value_output := 0;
                  when 0 => null;
                  when others => value_output := Natural'Pred(value_output);
               end case;
            when 's' | 'k' => 
               case value_output is
                  when 16 => value_output := 0;
                  when others =>value_output := value_output * value_output;
               end case;
            when 'o' | 'c' => Ada.Integer_Text_IO.Put(value_output, Width => 0); Put_Line("");
            when others => null;
         end case;
      end loop;
   end loop Prompt;
end Deadfish;

并输出:

>> xiskso
0
>> xiskisc
289
>> ddddo ddddo
285
281
>> ddddo ddddo
277
273
>> dddddddo
266
>> dddddddddo
257
>> do
0
>> do
0
>> io
1
>>

如果有人在Ada中进行了实验,可以给我一些优化提示,我将不胜感激。


1
欢迎来到PPCG!代码高尔夫的目标是创建尽可能最短的代码,并且应在头文件中包含程序的大小(此处为1396字节)
TuxCrafting '16

4

C,159个字符

A; main(c) {
  printf(">> ");
  while (c = getchar(), ~c)
    A = c - 'i' & c - 'x'?
        c - 'd'?
        c - 's' & c - 'k'?
        c - 'o' & c - 'c'?
        c - '\n'?
        A :
        printf(">> "), A :
        printf("%d\n", A), A :
        A * A :
        A - 1 :
        A + 1,
    A *= ~A && A - 256;
}

我尝试了另一种基于建立用于指令解码的查询表的方法,但不幸的是,最终结果花费了更长的时间(169)。我将其包括在内,因为有人可能会想出一个巧妙的调整来减小尺寸。(必须在没有任何参数的情况下运行)

#define X !--c?A

A,M[256];
main(c) {
  for(; !M['x']; c++) M["@osid\nckx"[c]]-=c%5+1;
  for (printf(">> "); c = ~M[getchar()]; A *= ~A && A - 256)
  A= X,printf("%d\n", A),A:X*A:X+1:X-1:A;
  main();
}

3

C,163

#define i(u,v);if(c==u+89|c==v+89)
a;main(c){printf(">>");while(c=getchar()-10){i(6,21)a++i(1,1)a--i(8,16)a*=a;i(0,12)printf("%d\n",a);a=a==-1|a==256?0:a;}main();}

3

Python 3中,181 175 171 162

a=0
s=lambda x:"a=%d"%(x!=-1and x!=256and x)
while 1:
 for i in input(">>"):u,b,o=s(a+1),s(a*a),"print(a)";exec(dict(i=u,x=u,d=s(a-1),s=b,k=b,o=o,c=o).get(i,""))

这会在之后输出换行符>>,但OP并未表示不允许这样做。 不再!

感谢GlitchMrminitechgolfer9338


1
您可以将lambda而不是def用于立即返回的函数。
Konrad Borowski

x in(-1,256)保存两个字符。或者,s=lambda x:"a=%d"%(x!=-1and x!=256and x)可以节省一些。
Ry-

1
您可以删除print(">>")for i in input(">>")改为使用;input()允许指定提示。然后,在之后将不会有换行符>>,并且您可以保存字符。
golfer9338 2013年

我认为您的分数现在应该 1个字符。请仔细检查,但我得到的数字是161,而不是发布的162:3 + 40 + 8 + 107的行,外加3个换行符。实话实说,我很嫉妒,因为无论哪种方式,您都比我的C答案短几个字符。干杯!
达伦·斯通

3

R,161148,138

a=0;repeat{x=readline(">> ");for(i in utf8ToInt(x)-99){a=a^((i==8|i==16)+1)+(i==6|i==21)-(i==1&a);a=a*(a!=256);if(i==0|i==12)cat(a,"\n")}}

非高尔夫版本:

a = 0
repeat{
  x = readline(">> ")
  for(i in utf8ToInt(x) - 99) {
    a = a ^ ((i == 8 | i == 16) + 1) + (i == 6 | i == 21) - (i == 1 & a)
    a = a * (a != 256)
    if(i == 0 | i == 12) cat (a, "\n")
  }
}

会话示例(以交互方式):

>> xiskso
0
>> xiskisc
289
>> ddddo ddddo
285
281
>> ddddo ddddo
277
273
>> dddddddo
266
>> dddddddddo
257
>> do
0
>> do
0
>> io
1
>> 

3

的Python 3,141

我知道我来晚了,但是我想借此机会发布一个较短的Python版本(以及我的第一个CodeGolf尝试)。:)

v=0
m=lambda y:(0,y)[-1!=y!=256]
i=x='+1'
d='-1'
s=k='*v'
c=o=');print(v'
while 1:
 for n in input('>>'):exec('v=m(v'+locals().get(n,'')+')')

打印声明对此有些棘手。如果提示必须以空格结尾,则将一个字符添加到计数中。:)

说明

v 是累加器。

m检查给定的值是-1还是256。如果是这样,0将返回,否则返回该值。

在以下各行中,将操作分配给相应的变量(因为某些变量具有相同的含义(如i和,x这比实例化新词典要短)。然后将这些用于exec下面。

while 1: 是主循环

现在,乐趣开始了。就像@jazzpi的解决方案一样,它迭代输入的每个字符。locals()是所有当前(可见)变量的字典。带有.get(n,'')相应密钥的密钥将被放入exec字符串(如果未找到密钥(=其他输入),则为空字符串)。然后在执行时将其与串联v并传递给m。返回值将v再次存储在其中。

简短示例:

n = 'i'n= input-char),我们'+1'离开locals-block,这i是value的变量'+1'
的字符串exec如下所示:'v=m(v+1)'
也许现在更容易看到,在执行时,它将m使用的值进行调用v+1并将其输出v再次存储在其中。

重复此操作,直到无聊为止。:)


我知道我晚会很晚,但是m的lambda可以是y*(-1!=y!=256)-3个字节
恢复Monica

短短5年:)谢谢您的投入。我很懒,无法解决问题,但我会牢记在心
Dave J

3

蟒蛇2,139

a=0
while 1:
 for c in raw_input(">> "):
  if c in'ix':a+=1
  if c=='d':a-=1
  if c in'sk':a*=a
  if c in'oc':print a
  if a in(-1,256):a=0

这很整洁,但也很简单。这是一个更长,更酷的版本:

def i(a):
 while 1:
  c=yield
  if c in'ix':a+=1
  if c=='d':a-=1
  if c in'sk':a*=a
  if c in'oc':print a
  if a in(-1,256):a=0
 j=i(0);next(j)
while 1: 
 for c in raw_input(">> "):j.send(c)

重达190个字符,这可能不是这里竞争最激烈的答案。另一方面,协程很不错,我一直在寻找借口使用(分享)它们


3

TI-BASIC,104 107 102 100 98

适用于TI-83 + / 84 +系列计算器。

命名这个prgmD; 它最终会通过调用自身而使堆栈溢出。While 1要修复此问题,请以两个字节为代价将递归替换为。

Input ">>",Str1
For(I,1,length(Str1
int(.5inString("?ixskd?oc",sub(Str1,I,1
If Ans=4
Disp Y
imag(i^Ans)+Y^int(e^(Ans=2     //decrements when Ans=3; increments when Ans=1
min(0,Ans(Ans≠256→Y
End
prgmD

Y默认情况下为0,因此请使用全新的内存清除计算器来运行它,或者在运行此之前手动将0存储到Y。

不幸的是,小写字母(在字符串文字中)每个都是两个字节。否则,这将比Dom Hastings的回答短。

编辑:修复了以三个字节为代价的零除(0 ^ 0)错误。

107-> 102:使用了虚构的幂运算技巧来保存四个字节(包括括号中的1个字节和加长查找字符串的-1个字节),并使用Y而不是X进行初始化,而该过程只需要少一个字节。


2

附言272

/cmd<</i{1 add}/x 1 index/d{1 sub}/s{dup mul}/k 1 index/o{dup =}/c 1 index>>def
0{(>> )print flush{/f(%lineedit)(r)file def}stopped{exit}if{f
1 string readstring not{exit}if cmd exch 2 copy known{get exec}{pop pop}ifelse
dup -1 eq 1 index 256 eq or{pop 0}if}loop pop}loop

取消高尔夫:

/cmd <<  % define commands
/i { 1 add }
/x 1 index
/d { 1 sub }
/s { dup mul }
/k 1 index
/o { dup = }
/c 1 index
>> def
0        % accumulator on stack
{
    (>> )print flush   % print prompt
    { /f (%lineedit) (r) file def } stopped {exit} if  % read input line or quit
    {
        f 1 string readstring not {exit} if   % read 1-char string from line
        cmd exch 2 copy known { get exec }{ pop pop } ifelse   % execute command or don't
        dup -1 eq 1 index 256 eq or { pop 0 } if   % adjust accumulator if needed
    } loop
    pop
}loop

2

C (224 212个字符)

这可能是一个错误的语言选择,但是哦。不是像C这样的语言可以比某些动态编程语言做得更好。在Clang上,您需要为指定一个值return(gcc不需要此值)。

#define s(x,y)case x:y;break;
main(){int c=10,a=0;for(;;){switch(c){s(-1,return)s('i':case'x',++a)s('d',--a)s('s':case'k',a*=a)s('c':case'o',printf("%d\n",a))s(10,printf(">> "))}a!=-1&a!=256||(a=0);c=getchar();}}

删除define q并使用会不会更短printf
门把手

@DoorknobofSnow其实没有。q已使用3次,因此可define q节省〜2个字符。
贾斯汀

2

Lua中,230 228

a=0repeat io.write(">> ")x=io.read()for i=1,#x do c=x:sub(i,i)if c=="i"or c=="x"then a=a+1 elseif c=="d"then a=a-1 elseif c=="s"or c=="k"then a=a*a elseif c=="o"or c=="c"then print(a)end if a==256or a==-1then a=0 end end until _

不是最坏的,不是最好的。

注意:@mniip 报告的内容256or可能无法在您的解释器中使用。评论中的更多信息。

(或多或少)可读版本:

a=0
repeat
  io.write(">> ")
  x=io.read()
  for i=1,#x do
    c=x:sub(i,i)
    if c=="i"or c=="x"then
      a=a+1
    elseif c=="d"then
      a=a-1
    elseif c=="s"or c=="k"then
      a=a*a
    elseif c=="o"or c=="c"then
      print(a)
    end
    if a==256or a==-1then
      a=0
    end
  end  
until _

输出:

>> xiskso
0
>> xiskisc
289
>> ddddo ddddo
285
281
>> ddddo ddddo
277
273
>> dddddddo
266
>> dddddddddo
257
>> do
0
>> do
0
>> io
1
>>

编辑:感谢@mniip进行2个字符优化:until nil->until _


repeat until x(x是未定义的nil)短2个字符,并且while 1 do end长度完全相同,除了那是什么lua版本?256or在我的解释器中是无效的语法
mniip 2013年

@mniip感谢您的提示repeat until x。我正在从这里使用最新的Windows二进制文件。如您所见,a=a+1 elseif有空间。那是因为e是十六进制数字,而oin 256or不是,所以我的解释器将其or作为另一个语句/块/ howYouCallIt。
Egor305 2013年

是的256or,而且0repeat还有1then; 我使用的是lua.org提供的官方lua,您的代码无法在5.1、5.2或5.3中编译
mniip 2013年

2

哈斯克尔186178字节

这需要与runhaskell(或内部ghci)一起运行,因为它们都设置了BufferModeNoBuffering默认为,这可以节省很多字节:

infix 4#
-1#x=0#x
256#x=0#x
r#x:y=case x of 'i'->r+1#y;'x'->r+1#y;'d'->r-1#y;'s'->r^2#y;'k'->r^2#y;'o'->print r>>r#y;'c'->r#'o':y;_->r#y
r#_=putStr">> ">>getLine>>=(r#)
main=0#""

在线尝试!

说明

这定义了一个新的运算符 state # source(固定性声明可以让我们在与其他运营商一起使用时下降括号(+)(-)(^)(:)(>>)):

  • 前两行“修复”状态-1256
  • 然后匹配第一个字符并对其进行操作
  • 一旦字符(r#_)用完,它将读取新的字符并重新开始以保持旧状态

首先,我们使用初始化状态0并读取新的源代码行。从一个空的源开始:

main=0#""

1

Windows批处理,204 256

@echo off
set a=0
:a
set /p i=^>^> 
if %i%==i set /a a=%a%+1
if %i%==x set /a a=%a%+1
if %i%==d set /a a=%a%-1
if %i%==s set /a a=%a%*%a%
if %i%==k set /a a=%a%*%a%
if %i%==o echo %a%
if %i%==c echo %a%
if %a%==256 set a=0
if %a%==-1 set a=0
set i=n
goto a

成功忽略其他命令。真的没有without肿or与...合作

编辑:

固定:

  • 不再回显所有命令
  • 使用/ a使其实际执行数学运算
  • 重置-1
  • 每个周期后重置输入

这需要52个字符。

尚未解决:

  • 平方0在a中写入“ 0 * 0”。
  • 输入空格(或在刚打开时不输入任何内容)会使脚本崩溃。
  • 您需要一次输入一个字符。

2
这只是一个简单的根本不起作用(Windows 7)。我不是故意要混蛋,但是您测试了吗?
marinus 2013年

@marinus已修复。
Timtech

1

Windows命令脚本-154

最大程度地利用Abusin的未知功能。

@echo off
set i=1
set x=1
set d=-1
set/as=[*[-[
set/ak=[*[-[
set.=0
set/p.=^>^> 
set/a[=[+%.%
e%.:o=c%h%.:c=o% %[% 2>nul
set[=%[:-1=%
if;%[%==256 set[=
%0

1

> <>,258个字节

我做了另一个> <>回答,因为我无法测试阶段,并且它使用了预先堆叠的命令,而不是始终模仿外壳。

0v
"<vooo">> 
!~>i:0)?v~ >
 ^?=a:  /  ^!?="c"v?="o":v?="s":v?="k":v?="d":v?="x":v?="i":
   voan:<        ~<  v*:~<      <  v-1~<  v+1~<      <
   <                 <             <      <vv?=-10:v?=*:+1f:
  v                                        <>      >~0

当然可以打高尔夫球,但是我不确定我会不会需要疯狂勇气!

我使用Windows 7下cygwin下在python 3.5下运行的官方解释器对其进行了测试,并且可以再现测试运行:

$ python fish.py deadfish.fish
>> xiskso
0
>> xiskisc
289
>> ddddo ddddo
285
281
>> ddddo ddddo
277
273
>> dddddddo
266
>> dddddddddo
257
>> do
0
>> do
0
>> io
1
>> (pressed ctrl-Z)Stopped

如果您无法在计算机上运行它(输入似乎很棘手),或者您只想在没有任何其他软件的情况下尝试使用它,则可以在在线解释器上使用以下版本。

0v
 <vooo">> "<
  >i:0)?v~
      o:/  ^!?="c"v?="o":v?="s":v?="k":v?="d":v?="x":v?="i":
 ^oanoa:<        ~<  v*:~<      <  v-1~<  v+1~<      <
   <                 <             <      <vv?=-10:v?=*:+1f:
  v                                        <>      >~0

由于您无法在在线解释器中输入\ n和EOF,因此它显然会忽略\ n和EOF,但是它们的行为就像在每个输出命令之后都按回车一样。


1

C(gcc),139字节

编译-Dk="_nZZiaeY"(包含在字节数中)。-2个字节(如果>>\n允许提示符)。

x;f(c){for(printf(">>");c=getchar()-10;x+=c--?c--?c--?c||printf("%i\n",x),0:x*x-x:-1:1,x*=~x&&x^256)c=strchr(k,c)-k>>1;f();}

在线尝试!

德戈尔夫

/** Preprocessor **/
-Dk="_nZZiaeY" // This is a lookup string; it corresponds to "ixddskoc",
               // with 10 deducted from each character. Upon compilation, 
               // all occurences of the string literal are replaced with a 
               // pointer to its location in memory.

/** Source **/
x;f(c){ // x: 32-bit accumulator, c: local variable for read character
    for(printf(">>"); // Start for-loop and print prompt.
            c=getchar()-10; // Read a character from STDIN.
                            // Loop breaks if it is '\n'.

            // The below happens at the end of each iteration.
            x+=c--?c--?c--? 
               // Find the correct operation by testing c and post-
               // decrementing with multiple ternary-ifs. If c is 0, 
               // operation was found, add the else-value to the 
               // accumulator x.
               //     If the character is invalid, the value of c is
               // very large, and will not reach 0 with 3 decrements.

               c||printf("%i\n",x),0 
               // If c-3 is 0, print accumulator, else do nothing.
               // Returns 0 regardless of what happens. (No change to x)
               :x*x-x 
               // Square. Results in x=x+x*x-x, and is shorter than (x*=x)
               :-1:1, 
               // Decrement, Increment.
               x*=~x&&x^256 
               // Because -1==0xffffffff, ~x==0 when x==-1. Likewise,
               // x^256==0 only when x==256. The logical-AND coerces the result
               // to boolean 1 (no match) or 0 (match). Multiplication resets
               // the accumulator as appropriate.
           )
        // This is the actual body of the for-loop
        c=strchr(k,c)-k>>1; 
           // Finds the index of the read character in the lookup string,
           // then "divides" it by two.
           // Because strchr() returns NULL (0) when character is not found,
           // deducting k from it results in a very negative number.
           // The right-shift results in division by 2 for positive numbers, 
           // while the negative numbers become very large positive numbers
           // (c >= 0x70000000) because of the 2's complement representation.
    // Finally, recurse until forceful termination.
    f();
}

1

68B

0{'::"ÿ1+=$0<+['_0"] \>\>\
,,,,?:o=[':."]:i=['1+"]:d=['1-"]:s=[':*"

0

哈斯克尔(230)

import System.IO
i""n=[]
i(a:b)n 
 |a=='o'||a=='c'=[n]++i b n
 |True=i b$v a n
v a n=w(case a of 'i'->n+1;'x'->n+1;'d'->n-1;'s'->n^2;'k'->n^2)
w(-1)=0
w 256=0
w n=n
main=do;putStr ">> ";hFlush stdout;s <- getLine;print$i s 0;main

如果我能摆脱那个讨厌的hFlush stdout电话!没有它,直到执行o操作,提示才会显示。有什么建议吗?


您可以hFlush通过使用runhaskell而不是编译来摆脱它(请参阅我的回答),但是对于此解决方案,它是无效的并且会出错。
ბიმო

0

PHP + HTML 345

<form><?php $i=0;$o='';if(isset($_GET[i])){$i=$_GET[a];foreach(@str_split($_GET[i]) as $j=>$v){$v==i||$v==x?$i++:($v==d?$i--:($v==k||$v==s?$i*=$i:($v==o||$v==c?$o.=$i."\n":'')));($i==256||$i==-1)&&$i=0;}$_GET[p].='>> '.$_GET[i]."\n".$o;echo"<textarea locked name=p>$_GET[p]</textarea><input type=hidden name=a value=$i><br>";}?>>> <input name=i>

输出有点粗略(历史记录/会话显示在文本区域上,并且启用了错误报告功能后,会打印很多警告),但是一切正常


0

> <>,​​239

v
\r0&
v                  <
\&::&01-=$f1+:*=+?v
v             &0~&<
\:"i"=?v
       >~&1+&      ^
\:"d"=?v
       >~&1-&      ^
\:"s"=?v
       >~&:*&      ^
\:"o"=?v
       >~&:o&      ^
\:"h"=?v
       >~;        (^)
>~                 ^

初始堆栈是输入。您可以在这里在线尝试。


0

高尔夫基础84,88个字符

:0_A:0_O:1_I:2_D:3_S:O_C:I_X:S_Kl`1i`N@A=256:0_A@N=0d`A@N=1:A+1_A@N=2:A-1_A@N=3:A^2_Ag`1

与至少其他3个解决方案一样,一次提示一个命令。这是针对的测试运行xiskisc

?X
?I
?S
?K
?I
?S
?C
             289

同样,应xiskso输出0。


还有哪些其他解决方案一次提示一个命令?
Ry-

1
我写了一部Haskell,不,不是。Perl也没有,所以我真的不确定您在说什么。
Ry-

1
这不遵循I / O规则。
marinus 2013年

1
仍然不遵循规则,而是使用大写字母而不是小写字母。
lirtosiast 2015年

1
如果您了解TI-BASIC,则它仅支持大写输入。
Timtech

0

JavaScript(Node.js),204字节

process.openStdin(f=a=>process.stdout.write((i=0,""+a).split` `.map(x=>([...x.slice(0,-1)].map(d=>({i:x=e=>i++,d:e=>i--,s:k=e=>i*=i,o:c=e=>e,x,k,c})[d](i=-1||i==256?i=0:0)),i))+"\n>> "),f``).on("data",f)

这可能是打高尔夫球的。Node.js再次证明它是奇怪的变相冗长。代码说明:

process.openStdin( // This function has to be called to take input, but doesn't have arguments
  f=a=> // Define a function f. This is the deadfish interpreter. It takes an argument `a` which is a Buffer
  process.stdout.write( // Same as console.log, but doesn't output trailing newline
    (i = 0, "" + a) // Take advantage of comma operator to (A) define the accumulator i, and casts a (which is a Buffer) to a String
      .split` ` // Split the string a at spaces, making it an array
      .map(     // Map through each element of the array
        x=>     // Map function, takes argument x, the value in the array (string)
          ([...x.slice(0,-1)] // Remove the last character (newline) and than use the spread operator to divide the string into an array of it's chars
            .map(d=> // Map function, you know how this works
              ({ // Here I define the various deadfish commands
                i: x = e => i++,
                d: e => i--,
                s: k = e => i*=i,
                o: c = e => e,
                // Take advantage of ES6 object notation. Equivilent to {"x": x, "k": k, "c", c}
                x,
                k,
                c
              })
              [d] // Get the command to execute. If this is passed something which isn't valid, a giant error will appear
              (
                i==-1 || i==256 ? i = 0 : 0 // Take advantage of the fact that none of the command functions take arguments to handle the strange "overflow"
              )
            ),
          i)
      ) +
  "\n>> "), // Display the prompt again, as well as a newline
  f`` // Initalize the prompt by passing an empty script
)
.on("data",f) // Bind the f function to newline on STDIN

0

C#,311字节

using System;class p{static void Main(){int a=0;int s(int b)=>b==-1||b==256?0:b;while(true){Console.Write(">>");var c=Console.ReadLine();for(int i=0;i<c.Length;i++){switch(c[i]){case'i':case'x':a=s(a+1);break;case'd':a=s(a-1);break;case's':case'k':a=s(a*a);break;case'o':case'c':Console.WriteLine(a);break;}}}}}

如果只通过提供一个函数定义就可以省略uses和class声明等,则为283字节

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.