Написать интерактивный переводчик Deadfish


30

Deadfish - это шутка «языка программирования» с четырьмя командами. Поскольку страница Esolang немного противоречива и интерпретаторы на этой странице не все работают одинаково, вам следует реализовать следующий вариант:


Спецификация

  1. Имеется аккумулятор размером не менее 16 бит, больше разрешено, но меньше нет. Отрицательные числа не должны поддерживаться. Аккумулятор - это 0когда программа запускается.
  2. Существуют следующие два набора из четырех команд, и ваша программа должна поддерживать обе команды одновременно.
      Стандартный Deadfish │ XKCD Вариант │ Значение
      ─────────────────────┼──────────────────┼───────── ───────────────────────────
            i │ x │ Аккумулятор увеличения
            d │ d │ Аккумулятор декремента
            S │ K │ Площадь (акк = акк * акк)
            o │ c │ Выходной аккумулятор, как число
    
  3. Если после выполнения команды аккумулятор равен -1или 256, аккумулятор должен быть сброшен на ноль. Обратите внимание, что это не нормальный переход. Если, скажем, аккумулятор есть 20, а sкоманда запущена, аккумулятор должен быть 400позже. Аналогично, если аккумулятор есть 257и dкоманда запущена, аккумулятор должен стать 0.
  4. Любой ввод, который не является одной из этих команд, должен игнорироваться.

Тестовые программы

  • xiskso должен выводить 0
  • xiskisc должен выводить 289

I / O

Ваша программа должна отображать подсказку: >>. Подсказка должна быть в начале новой строки. Затем он должен прочитать строку ввода пользователя и выполнить указанные команды слева направо. При выводе чисел числа должны быть разделены. То есть, 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: Вы можете использовать рубиновый ввод, верно?
Маринус

Согласно руководству по GolfScript, вы не можете запрашивать ввод в GolfScript, все данные поступают из STDIN.
ProgramFOX

@ProgramFOX: я бы подумал, что что-то вроде #{STDIN.gets}бы сработает, но на самом деле это не так.
Маринус

Можно ли вместо этого принимать ввод заглавными буквами?
lirtosiast

Ответы:


6

К, 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 немного длиннее, потому что глаголы ввода-вывода длиннее, даже если все остальное лучше:

{""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 - это саморекурсия . В К6 мы можем просто сказать, o`что короче.

8

Perl 5 , 90 байт

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

Попробуйте онлайн!

Спасибо @xfix за его помощь в этом ранее! Сохранено 4 байта благодаря @Xcali !


1
Ваша программа печатает 1при переполнении аккумулятора. Кроме того, вы можете сократить свою программу на пять символов, изменив ее $aна $?(которая инициализируется 0и не изменится, пока вы не запустите внешнюю программу из Perl).
Конрад Боровски

Аааа, я искал переменную, которую мог бы использовать, отлично, спасибо! Что касается переполнения, я не заметил этого, так как это происходит только в том случае, если вы запускаете isssoодну команду, а не если вы выполняете каждую из них в отдельности ... Я рассмотрю это позже и, безусловно, буду использовать $?. Спасибо!
Дом Гастингс

Поэтому я думаю, что я оставил более старую версию в разделе кода вверху, ''вместо того, ""чтобы при использовании с perl -e '...'картой он заканчивался результатом s///. Еще раз спасибо!
Дом Гастингс

ОК, ты самый короткий.
марин

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++} - соответствует iили x- увеличивает аккумулятор
  • "d"{$x-=!!$x} - match d- уменьшить $xна !!$x, что будет, 0если $xесть 0, а в 1противном случае. Это гарантирует, что аккумулятор никогда не достигнет -1.
  • "s|k"{$x*=$x} - совпадать sили k- квадрат
  • "o|c"{$x} - соответствовать oили c- выводить аккумулятор
  • $x*=$x-ne256- умножить аккумулятор на, 0если он есть, 256или на 1иное

Пример вывода

>>: 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, позор, я не могу использовать это ...
Дом Гастингс

Эй, Данко, не могли бы вы опубликовать тестовый вывод, пожалуйста? Я не думаю, что смогу протестировать Power Shell на не-Windows ... (пожалуйста, поправьте меня, если я ошибаюсь!)
Дом Гастингс

Я добавил тестовый вывод в ответ.
Данко Дурбич

6

Ребол 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

Вы могли бы сэкономить несколько персонажей, изменяя eи vв операторы. Я также попытался переписать vи gчтобы параметр xоставался в IO и printт. Д. Был отменен. Мне не удалось заставить его работать, но я думаю, что это может быть хорошим местом для тех, кто знает их хаскель.
Шион

@shiona: Да, дело в IOтом, что они должны печатать слишком часто (именно поэтому я использовал r nвместо x) или недостаточно, потому что значение никогда не запрашивается…. Так как бы я изменился eи vна операторов?
Ry-

У меня были такие же проблемы с печатью. Что касается операторов, которые вы можете сделать (используя e в качестве примера) 'i'%x=x+1;'d'%x=x-1... И просто позвоните в v do n<-x;r$w$o%n. Причина, по которой операторы экономят пространство, заключается в том, что они не требуют пробелов вокруг них.
Шион

@shiona: Ой! Хороший звонок, спасибо!
Ry-

Нет проблем. Сначала я подумал о том, чтобы сделать собственный ответ, но так как я не смог воплотить в жизнь свои большие идеи, я подумал, что это будет просто грубая публикация абсолютно одного и того же кода с разными обозначениями для тех же функций.
Шиона

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

К, 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 и функциональный интерпретатор вместо поправки.
Геокар

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

Если бы некоторые люди, экспериментирующие в Аде, могли дать мне несколько советов по оптимизации, я был бы благодарен.


1
Добро пожаловать в PPCG! Целью code-golf является создание максимально короткого кода, и вы должны
указать

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

С 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

Питон 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,""))

Это выводит новую строку после >>, но ОП не сказал, что это не разрешено. Уже нет!

Спасибо GlitchMr, minitechи golfer9338!


1
Вы можете использовать lambdaвместо defфункции, которая немедленно возвращает.
Конрад Боровски

x in(-1,256)сохраняет два символа. В качестве альтернативы, s=lambda x:"a=%d"%(x!=-1and x!=256and x)можно сэкономить.
Ry-

1
Вы можете удалить print(">>")и использовать for i in input(">>")вместо этого; input()позволяет указать подсказку. После этого не будет новой строки >>, и вы сохраните символы.
golfer9338

Ваша оценка должна быть, по- моему, один символ короче прямо сейчас. Пожалуйста, перепроверьте, но я получил счет 161 вместо опубликованных 162: строки 3 + 40 + 8 + 107 плюс 3 новых строки. По правде говоря, я ревную, потому что в любом случае, вы на несколько символов короче моего C ответа. Ура!
Даррен Стоун

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

Безголовая версия:

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

Питон 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снова.

Краткий пример:

Be n = 'i'( n= input-char), мы получаем '+1'из locals-block как iпеременную со значением '+1'.
Строка для execчем выглядит следующим образом : 'v=m(v+1)'.
Может быть, теперь легче увидеть, что при выполненииm со значением v+1и vснова сохранять результаты .

Повторяйте это, пока не надоест. :)


Я понимаю, что я ОЧЕНЬ опаздываю на вечеринку, но лямбда для m может быть y*(-1!=y!=256)для -3 байта
Восстановить Монику

всего 5 лет :) спасибо за вклад, хотя. Я слишком ленив, чтобы не исправить ответ, но я буду помнить об этом
Дэйв Дж.

3

Python 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

Ungolfed:

/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

Луа, 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

@mniip Спасибо за подсказку repeat until x. Я использую последнюю версию бинарного Windows отсюда . Как видите, a=a+1 elseifесть место. Это потому, что eшестнадцатеричная цифра, в то время как oв 256orнет, поэтому мой интерпретатор принимает в orкачестве другого оператора / block / howYouCallIt.
Егор305

да в значительной степени, кроме того 256or, также 0repeatи 1then; Я использую официальный lua от lua.org, ваш код не компилируется ни в 5.1, 5.2, ни в 5.3
mniip

2

Haskell , 186 178 байт

Это должно быть выполнено с runhaskell(или внутри ghci), так как они оба устанавливают BufferModeзначение NoBufferingпо умолчанию, которое сохраняет довольно много байтов:

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(декларация неподвижности позволяет нам отказаться от круглых скобок при использовании его в сочетании с другими операторами (+), (-), (^), (:)и (>>)):

  • первые две строки "исправить" состояния -1и256
  • затем он соответствует первому символу и действует на него
  • как только у него заканчиваются символы ( 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

Успешно игнорирует другие команды. Действительно раздулся без необходимости orработать с ...

Редактировать:

Исправлена:

  • Больше не нужно повторять все команды
  • Сделано это на самом деле делать математику с / а
  • Сброс на -1
  • Сбрасывать ввод после каждого цикла

Это стоит 52 символа.

Не исправлено:

  • Квадрат 0 пишет "0 * 0" в.
  • Ввод пробела (или ничего не вводить, когда вы только что открыли его) завершает работу скрипта.
  • Вам нужно вводить один символ за раз.

2
Этот просто не работает вообще (Windows 7). Я не хочу быть мудаком, но ты проверял это?
Маринус

@marinus Это было исправлено.
Timtech

1

Командный скрипт Windows - 154

Абусин неизвестных функций на макс.

@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

Это , безусловно , может быть golfed вниз, но я не уверен , что я буду иметь необходимую невменяемость отвагу!

Я протестировал его с помощью официального интерпретатора, работающего под python 3.5 под cygwin под windows 7, и смог воспроизвести тестовый прогон:

$ 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, так как вы не можете вводить их в онлайн-интерпретаторе, но будет вести себя так, как если бы ввод вводился после каждой команды вывода.


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

Попробуйте онлайн!

Degolf

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


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

Golf-Basic 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
Это не соответствует правилам ввода / вывода.
Маринус

1
Все еще не следует правилам и использует прописные буквы, а не строчные.
lirtosiast

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

было бы 283 байта, если использование, объявление класса и т. д. можно было бы опустить, просто предоставив определение функции

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.