Viết một trình thông dịch Deadfish tương tác


30

Deadfish là một "ngôn ngữ lập trình" đùa với bốn lệnh. Vì trang Esolang hơi mâu thuẫn và các thông dịch viên trên trang đó không hoạt động giống hệt nhau, nên bạn nên thực hiện biến thể sau:


Đặc điểm kỹ thuật

  1. Có một bộ tích lũy có kích thước tối thiểu 16 bit, được phép nhiều hơn nhưng ít hơn là không. Số âm không cần phải được hỗ trợ. Bộ tích lũy là 0khi chương trình bắt đầu.
  2. Có hai bộ bốn lệnh sau và chương trình của bạn phải hỗ trợ cả hai cùng một lúc.
      Cá chết tiêu chuẩn Biến thể XKCD │ Ý nghĩa
      ─ ─ ─ ─ Giới thiệu về giới tính của bạn
            i │ x accum Tích lũy tăng
            d │ d accum Bộ tích lũy giảm dần
            s │ k │ Hình vuông (acc = acc * acc)
            o │ c accum Bộ tích lũy đầu ra, dưới dạng số
    
  3. Nếu, sau khi thực hiện một lệnh, bộ tích lũy là -1hoặc 256, bộ tích lũy phải được đặt lại về 0. Lưu ý rằng đây không phải là bao quanh bình thường. Nếu, giả sử, bộ tích lũy là 20slệnh được chạy, bộ tích lũy sẽ là 400sau đó. Tương tự, nếu bộ tích lũy 257dlệnh được chạy, bộ tích lũy sẽ trở thành 0.
  4. Bất kỳ đầu vào nào không phải là một trong những lệnh này sẽ bị bỏ qua.

Chương trình kiểm tra

  • xiskso nên đầu ra 0
  • xiskisc nên đầu ra 289

Tôi / O

Chương trình của bạn sẽ hiển thị lời nhắc : >>. Lời nhắc phải ở đầu một dòng mới. Sau đó, nó sẽ đọc một dòng đầu vào của người dùng và chạy các lệnh đã cho từ trái sang phải. Khi xuất số, các số phải được tách. Tức 12 34là ổn, 12,34ổn

12
34 

Không sao, nhưng 1234không phải.

Chương trình của bạn nên tiếp tục làm điều này trong một vòng lặp, ít nhất là cho đến khi EOFđạt được.

Phiên ví dụ:

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

Do lời nhắc nhập liệu, tôi không thể sử dụng GolfScript :-(
Chương

@ProgramFOX: Bạn có thể sử dụng đầu vào ruby ​​phải không?
bến

Theo hướng dẫn của GolfScript, bạn không thể nhắc nhập liệu vào GolfScript, tất cả đầu vào đều đến từ STDIN.
Chương trìnhFOX

@ProgramFOX: Tôi đã có thể nghĩ một cái gì đó như #{STDIN.gets}sẽ hoạt động nhưng thực sự nó không.
bến

Thay vào đó, chúng ta có được phép nhập liệu bằng chữ in hoa không?
lirtosiast 04/07/2015

Câu trả lời:


6

K, 77 byte

  {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

Lưu ý đây là K4 . Một giải pháp K6 dài hơn một chút vì các động từ IO dài hơn, ngay cả khi mọi thứ khác tốt hơn:

{""0:">>";0{x*^-1 256?x:y@x}/("xkcdiso"!7#(1+;{x*x};{""0:,$x;x};-1+))@0:"";o`}`
  • ""0:in và trả về đối số của nó. Lưu ý trong K4, chúng tôi chỉ cần áp dụng cho 1 .
  • 0 f/ args chứng tỏ giảm với giá trị ban đầu, nghĩa là f[f[0;first arg];second arg]…
  • {x*2=-1 256?x…phân loại x thành 0 (cho -1), 1 (cho 256) và 2 cho tất cả các giá trị khác. 2=có nghĩa là chúng ta nhận 1được các giá trị không được phân loại và 0nếu không, nhân với xngắn hơn một điều kiện. Trong K6 chúng ta có thể làm tốt hơn một chút vì {x*^-1 256?x:y@x}dựa vào thực tế là -1 256?xtrả về 0N(null) và ^phát hiện null.
  • "Trình phân tích cú pháp" là bản đồ "xkcdiso"thay vì thứ tự được đề xuất vì 7#sẽ bao quanh bốn đối số tức là 7#"abcd"trả về "abcdabc"giữ cho bảng của chúng ta nhỏ hơn
  • Bản đồ dịch "x""i"chiếu 1+tương đương với chức năng {1+x}nhưng ngắn hơn.
  • Bản đồ chuyển "d"sang hình chiếu -1+tương đương với chức năng {-1+x}nhưng ngắn hơn.
  • Bản đồ dịch "k""s"chức năng{x*x}
  • Bản đồ dịch "c""o"chức năng đầu ra {-1@$x;x}một lần nữa trong K6 dài hơn một chút: {""0:,$x;x}nhưng cả hai đều in đầu ra của nó theo sau một dòng mới, và sau đó trả về đối số.
  • .zs là tự đệ quy. Trong K6 chúng ta có thể chỉ cần nói o`ngắn hơn.

8

Perl 5 , 90 byte

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

Hãy thử trực tuyến!

Cảm ơn @xfix vì sự giúp đỡ của anh ấy về điều này trước đây! Đã lưu 4 byte nhờ @Xcali !


1
Chương trình của bạn in 1khi tích lũy tràn. Ngoài ra, bạn có thể rút ngắn chương trình của mình bằng năm ký tự, bằng cách thay đổi $athành $?(được khởi tạo thành 0và sẽ không thay đổi cho đến khi bạn chạy một số chương trình bên ngoài từ Perl).
Konrad Borowski

Ahhhh, tôi đã săn lùng một biến tôi có thể sử dụng, hoàn hảo, cảm ơn bạn! Đối với tràn, tôi đã không nhận thấy điều đó vì nó chỉ xảy ra nếu bạn chạy isssonhư một lệnh chứ không phải nếu bạn thực hiện riêng lẻ ... Tôi sẽ xem xét điều này sau và chắc chắn sẽ sử dụng $?. Cảm ơn bạn!
Dom Hastings

Vì vậy, tôi nghĩ rằng tôi đã để lại một phiên bản cũ hơn trong phần mã ở đầu ''thay vì ""vậy khi được sử dụng với perl -e '...'bản đồ sẽ kết thúc với kết quả của s///. Cảm ơn một lần nữa!
Dom Hastings

OK, bạn là người thấp nhất.
bến tàu

1
Không còn là câu trả lời ngắn nhất.
geocar

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){...} - đặt bộ tích lũy thành 0 và lặp lại mãi mãi
  • read-host '>>' - nhận thông tin người dùng nhập nhanh chóng >>
  • [char[]](...) - chuyển đổi đầu vào của người dùng thành một mảng các ký tự
  • |%{...} - thực hiện những gì bên trong {}cho mỗi nhân vật
  • switch -r($_) - chuyển đổi regex cho mỗi nhân vật
  • "i|x"{$x++} - khớp ihoặc x- tăng bộ tích lũy
  • "d"{$x-=!!$x} - khớp d- giảm $xtheo !!$x, sẽ là 0nếu $x0, và 1nếu không. Điều này đảm bảo tích lũy không bao giờ đạt được -1.
  • "s|k"{$x*=$x} - khớp shoặc k- vuông
  • "o|c"{$x} - khớp ohoặc c- xuất bộ tích lũy
  • $x*=$x-ne256- nhân số tích lũy với 0nếu nó là 256hoặc bằng cách 1khác

Ví dụ đầu ra

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

Tôi đoán việc triển khai read-hostlà máy chủ lưu trữ cụ thể, vì vậy máy chủ Powershell (Consolehost) này sẽ thêm :vào dấu nhắc được chỉ định.


Tốt đẹp! Yêu sự suy giảm bởi !!$x, xấu hổ, tôi không thể sử dụng điều đó ...
Dom Hastings

Này Danko, bạn có thể gửi một số đầu ra thử nghiệm không? Tôi không nghĩ rằng tôi có thể kiểm tra vỏ điện trên các cửa sổ không ... (vui lòng sửa lại cho tôi nếu tôi sai!)
Dom Hastings

Tôi đã thêm một số đầu ra thử nghiệm cho câu trả lời.
Danko Durbić

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]

Phiên bản đẹp hơn:

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

Haskell, 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

Bạn có thể có thể lưu một vài ký tự bằng cách thay đổi evthành toán tử. Tôi cũng đã thử viết lại vgđể tham số xở lại IO, printv.v. Tôi đã không quản lý để làm cho nó hoạt động, nhưng tôi nghĩ rằng đó có thể là một nơi tốt để đi cho một người biết về sự tàn phá của họ.
shiona

@shiona: Vâng, điều cần lưu IOý là chúng thường được in quá thường xuyên (đó là lý do tại sao tôi sử dụng r nthay vì x) hoặc không đủ vì giá trị không bao giờ được yêu cầu đối với. Vì vậy, làm thế nào tôi sẽ thay đổi evthành nhà khai thác?
Ry-

Tôi đã có cùng một vấn đề với in ấn. Điều gì đến với các toán tử bạn có thể làm (sử dụng e làm ví dụ) 'i'%x=x+1;'d'%x=x-1... Và chỉ cần gọi nó trong v do n<-x;r$w$o%n. Các nhà khai thác lý do tiết kiệm không gian là họ không yêu cầu không gian xung quanh họ.
shiona

@shiona: Ồ! Cuộc gọi tốt, cảm ơn bạn!
Ry- 22/12/13

Không vấn đề gì. Đầu tiên tôi nghĩ về việc đưa ra câu trả lời cho riêng mình nhưng vì tôi không thể thực hiện được những ý tưởng lớn của mình, tôi nghĩ rằng đó chỉ là một bài viết thô lỗ chính xác cùng một mã với các ký hiệu khác nhau cho cùng các chức năng.
shiona

4

Hồng ngọc, 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;'}}

Phiên mẫu (giống như của bạn):

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
>>

Phiên bản của tôi ngắn hơn. Tôi nén bản đồ, dựa vào ? để phân loại các giá trị "gói", sử dụng đệ quy thay vì trong khi và một trình thông dịch chức năng thay vì sửa đổi.
geocar

4

Ada

Đây là một triển khai Ada cho một số ít người quan tâm đến ngôn ngữ này. Tôi đã mất khá nhiều thời gian để sử dụng một số thực tiễn tốt nhất của Ada (như sử dụng Indefinite_Holders thay vì truy cập) và cũng để hiểu đầy đủ cách thức Deadfish phải hoạt động.

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;

Và đầu ra:

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

Nếu một số người thử nghiệm ở Ada có thể cho tôi một số gợi ý tối ưu hóa, tôi sẽ rất biết ơn.


1
Chào mừng đến với PPCG! Mục tiêu của code-golf là tạo ra mã ngắn nhất có thể và bạn nên bao gồm kích thước của chương trình của bạn trong tiêu đề (1396 byte ở đây)
TuxCrafting

4

C, 159 ký tự

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;
}

Tôi đã thử một cách tiếp cận khác dựa trên việc thiết lập bảng tra cứu để giải mã hướng dẫn, nhưng không may là kết thúc lâu hơn ( 169 ). Tôi đã bao gồm nó vì ai đó có thể đưa ra một tinh chỉnh thông minh để cắt giảm kích thước. (Phải được chạy mà không có bất kỳ đối số)

#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

Trăn 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,""))

Điều này tạo ra một dòng mới sau >>, nhưng OP không nói rằng điều đó không được phép. Không còn nữa!

Cảm ơn GlitchMr, minitechgolfer9338!


1
Bạn có thể sử dụng lambdathay vì defcho một chức năng trả về ngay lập tức.
Konrad Borowski

x in(-1,256)lưu hai nhân vật. Ngoài ra, s=lambda x:"a=%d"%(x!=-1and x!=256and x)có thể tiết kiệm một số.
Ry-

1
Bạn có thể loại bỏ print(">>")và sử dụng for i in input(">>")thay thế; input()cho phép chỉ định một dấu nhắc. Sau đó, sẽ không có dòng mới sau >>và bạn lưu các ký tự.
golfer9338

Điểm số của bạn nên, tôi nghĩ rằng, một char ngắn hơn ngay bây giờ. Xin vui lòng nhân đôi, nhưng tôi nhận được số lượng 161 thay vì 162: dòng 3 + 40 + 8 + 107, cộng với 3 dòng mới. Sự thật mà nói, tôi ghen tị, bởi vì dù sao đi nữa, bạn là một vài ký tự ngắn hơn câu trả lời C của tôi. Chúc mừng!
Darren Stone

3

R, 161 , 148 , 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")}}

Phiên bản bị đánh cắp:

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")
  }
}

Phiên ví dụ (trong chế độ tương tác):

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

3

Trăn 3, 141

Tôi biết tôi đến muộn, nhưng tôi muốn nhân cơ hội đăng một phiên bản Python ngắn hơn (và lần thử CodeGolf đầu tiên của tôi). :)

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,'')+')')

Các tuyên bố in là hơi khó khăn cho việc này. Nếu dấu nhắc phải kết thúc bằng khoảng trắng, hãy thêm một char vào số đếm. :)

Giải trình

v là người tích lũy.

mkiểm tra xem giá trị đã cho là -1hay 256. Nếu vậy, 0sẽ được trả lại, giá trị khác.

Trong các dòng sau, các hoạt động được gán cho các biến tương ứng (vì một số có cùng ý nghĩa (như ix), điều này ngắn hơn so với khởi tạo một từ điển mới). Những người sau đó được sử dụng execdưới đây.

while 1: là vòng lặp chính

Bây giờ cuộc vui bắt đầu. Giống như giải pháp của @jazzpi , nó lặp đi lặp lại trên mỗi char của đầu vào. locals()là từ điển của tất cả các biến hiện tại (hiển thị). Với .get(n,'')khóa tương ứng sẽ được đưa vào chuỗi exec (một chuỗi trống, nếu không tìm thấy khóa (= đầu vào khác)). Điều này sau đó sẽ, khi được thực thi, được nối với vvà chuyển sang m. Giá trị trả lại sẽ được lưu trữ vlại.

Ví dụ ngắn:

Được n = 'i'( n= input-char), chúng ta thoát '+1'khỏi locals-block như ilà biến có giá trị '+1'.
Chuỗi cho exechơn trông như thế này : 'v=m(v+1)'.
Có lẽ bây giờ dễ thấy hơn, khi thực thi, nó sẽ gọi mvới giá trị v+1và lưu lại đầu ra của nó v.

Lặp lại điều này cho đến khi bạn chán. :)


Tôi nhận ra rằng tôi RẤT muộn đến bữa tiệc, nhưng lambda cho m có thể là y*(-1!=y!=256)-3 byte
Phục hồi lại

chỉ 5 năm :) cảm ơn cho đầu vào mặc dù. Tôi quá lười để không trả lời nhưng tôi sẽ ghi nhớ
Dave J

3

Con trăn 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

Điều này là gọn gàng, nhưng cũng khá đơn giản. Đây là phiên bản dài hơn, mát hơn:

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)

Với 190 ký tự, có lẽ đây không phải là câu trả lời có độ cạnh tranh cao nhất ở đây. Mặt khác, coroutines khá rad và tôi luôn tìm kiếm một cái cớ để sử dụng (và chia sẻ) chúng


3

TI-BASIC, 104 107 102 100 98

Đối với máy tính sê-ri TI-83 + / 84 +.

Đặt tên này prgmD; cuối cùng nó tràn qua ngăn xếp bằng cách gọi chính nó. Thay thế đệ quy bằng a While 1, với chi phí là hai byte, để sửa lỗi này.

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 là 0 theo mặc định, do đó, hãy chạy nó với một máy tính mới xóa bộ nhớ hoặc lưu 0 đến Y theo cách thủ công trước khi chạy nó.

Quá tệ là các chữ cái viết thường (trong chuỗi ký tự) là hai byte mỗi; nếu không thì điều này sẽ ngắn hơn câu trả lời của Dom Hastings.

EDIT: Đã sửa lỗi chia cho 0 (0 ^ 0) với chi phí là ba byte.

107 -> 102: Sử dụng thủ thuật lũy thừa tưởng tượng để lưu bốn byte (bao gồm 1 từ dấu ngoặc đơn và -1 từ việc kéo dài chuỗi tra cứu) và sử dụng Y thay vì X, mất một byte ít hơn để khởi tạo.


2

Bản thảo 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

Ung dung:

/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 ký tự)

Đây có lẽ là một lựa chọn ngôn ngữ xấu, nhưng oh tốt. Không phải ngôn ngữ như C có thể làm tốt hơn một số ngôn ngữ lập trình động. Trên Clang, bạn sẽ cần chỉ định một giá trị cho return(điều này không cần thiết cho 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();}}

Nó sẽ không ngắn hơn để chỉ loại bỏ define qvà chỉ sử dụng printf?
Doorknob

@DoorknobofSnow Thực tế không. qđược sử dụng 3 lần, vì vậy define qtiết kiệm ~ 2 ký tự.
Justin

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 _

Không phải là tồi tệ nhất, không phải là tốt nhất.

LƯU Ý: như báo cáo của @mniip 256or có thể không hoạt động trong trình thông dịch của bạn. Thêm thông tin trong ý kiến.

(nhiều hơn hoặc ít hơn) Phiên bản có thể đọc được:

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 _

Đầu ra:

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

Chỉnh sửa: cảm ơn @mniip để tối ưu hóa 2 char: until nil->until _


repeat until x(x là không được xác định) ngắn hơn 2 ký tự và while 1 do endcó độ dài chính xác như nhau, khác với phiên bản lua đó là gì? 256orlà cú pháp không hợp lệ trong trình thông dịch của tôi
mniip 26/12/13

@mniip Cảm ơn bạn đã gợi ý về repeat until x. Tôi đang sử dụng cửa sổ nhị phân mới nhất từ đây . Như bạn có thể thấy a=a+1 elseifcó không gian. Đó là bởi vì elà hệ thập lục phân số, trong khi otrong 256orkhông phải là, vì vậy thông dịch viên của tôi phải mất ornhư tuyên bố khác / block / howYouCallIt.
Egor305

vâng khá nhiều bên cạnh 256or, cũng 0repeat1then; Tôi đang sử dụng lua chính thức từ lua.org, mã của bạn không biên dịch trong 5.1, 5.2 hoặc 5.3
mniip 27/12/13

2

Haskell , 186 178 byte

Nhu cầu này phải được chạy với runhaskell(hoặc bên ghci) vì cả hai thiết lập BufferModeđể NoBufferingtheo mặc định mà két khá nhiều byte:

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#""

Hãy thử trực tuyến!

Giải trình

Điều này xác định một nhà điều hành mới state # source(tờ khai tính cố định cho phép chúng ta thả ngoặc khi sử dụng nó kết hợp với các nhà khai thác khác (+), (-), (^), (:)(>>)):

  • hai dòng đầu tiên "sửa chữa" các trạng thái -1256
  • sau đó nó khớp với ký tự đầu tiên và hành động theo nó
  • một khi nó hết ký tự ( r#_), nó sẽ đọc các ký tự mới và bắt đầu lại trạng thái cũ

Để bắt đầu quá trình, chúng tôi khởi tạo trạng thái với 0và đọc một dòng nguồn mới, nghĩa là. bắt đầu với một nguồn trống:

main=0#""

1

Batch 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

Bỏ qua thành công các lệnh khác. Thực sự trở nên cồng kềnh mà không cần phải orlàm việc với ...

Chỉnh sửa:

Đã sửa:

  • Không còn Echo tất cả các lệnh
  • Làm cho nó thực sự làm toán với / a
  • Đặt lại vào -1
  • Đặt lại đầu vào sau mỗi chu kỳ

Điều này có giá 52 ký tự.

Không sửa:

  • Bình phương 0 viết "0 * 0" trong a.
  • Nhập không gian (hoặc không nhập gì, khi bạn vừa mở) gặp sự cố.
  • Bạn CẦN phải nhập một char mỗi lần.

2
Cái này hoàn toàn không hoạt động (Windows 7). Tôi không có nghĩa là một lỗ đít nhưng bạn đã kiểm tra điều này?
bến 23/12/13

@marinus Nó đã được sửa.
TimTech

1

Tập lệnh lệnh Windows - 154

Abusin không biết tính năng đến mức tối đa.

@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 byte

Tôi đã thực hiện một câu trả lời khác> <> vì tôi không thể kiểm tra các pha và nó đã sử dụng các lệnh được xếp chồng sẵn thay vì mô phỏng trình bao.

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

Nó chắc chắn có thể bị đánh gôn, nhưng tôi không chắc mình sẽ có bản lĩnh điên rồ cần thiết !

Tôi đã thử nghiệm nó với trình thông dịch chính thức chạy dưới python 3.5 dưới cygwin dưới windows 7 và có thể sao chép quá trình chạy thử:

$ 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

Trong trường hợp bạn không thể chạy nó trên máy của mình (đầu vào có vẻ khó) hoặc bạn chỉ muốn dùng thử mà không cần bất kỳ phần mềm nào khác, bạn có thể sử dụng phiên bản sau trên trình thông dịch trực tuyến .

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ó rõ ràng bỏ qua \ n và EOF vì bạn không thể nhập chúng vào trình thông dịch trực tuyến, nhưng sẽ hoạt động như thể nhấn enter sau mỗi lệnh đầu ra.


1

C (gcc) , 139 byte

Biên dịch với -Dk="_nZZiaeY"(bao gồm trong số byte). -2 byte nếu dấu nhắc >>\nđược cho phép.

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();}

Hãy thử trực tuyến!

Thuốc khử trùng

/** 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

Keg , 68B

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

0

Haskell, 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

Giá như tôi có thể thoát khỏi hFlush stdoutcuộc gọi phiền phức đó ! Không có nó, lời nhắc sẽ không được hiển thị cho đến khi một othao tác được thực hiện. Có lời khuyên nào không?


Bạn có thể thoát khỏi hFlushbằng cách sử dụng runhaskellthay vì biên dịch (xem câu trả lời của tôi ), nhưng đối với giải pháp này, nó không hợp lệ và lỗi.
ბიმო

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>

đầu ra hơi sơ sài (lịch sử / phiên được hiển thị trên một vùng văn bản và với báo cáo lỗi được kích hoạt, rất nhiều cảnh báo được in) nhưng mọi thứ đều hoạt động


0

> <>, 239

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

Ngăn xếp ban đầu là đầu vào. Bạn có thể thử nó trực tuyến ở đây .


0

Golf-Basic 84, 88 ký tự

: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

Nhắc một lệnh tại một thời điểm, như trong ít nhất 3 giải pháp khác. Đây là bản chạy thử cho xiskisc:

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

Ngoài ra, xisksođầu ra 0, như nó cần.


Những giải pháp khác nhắc một lệnh tại một thời điểm?
Ry- 22/12/13

1
Tôi đã viết Haskell một, và không, nó không. Cũng không phải là Perl, vì vậy tôi thực sự không chắc bạn đang nói về cái gì.
Ry- 23/12/13

1
Điều này không tuân theo các quy tắc I / O.
bến

1
Vẫn không tuân theo các quy tắc và sử dụng chữ in hoa thay vì chữ thường.
lirtosiast 04/07/2015

1
Nếu bạn biết về TI-BASIC, nó chỉ hỗ trợ nhập chữ hoa.
TimTech

0

JavaScript (Node.js), 204 byte

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)

Điều này có thể được đánh golf. Node.js một lần nữa chứng minh tính dài dòng được ngụy trang kỳ lạ của nó một lần nữa. Mã giải thích:

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 byte

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;}}}}}

sẽ là 283 byte nếu việc sử dụng và khai báo lớp, v.v. có thể được thông báo bằng cách chỉ cung cấp một định nghĩa hàm

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.