Простой переводчик гольфа


13

Вызов:

Ваша задача - создать простого переводчика для простого языка игры в гольф.


Входные данные:

Ввод будет в виде строки, разделенной пробелами.

Вы можете заменить пробел на то, что вы хотите


Выход:

Выведите результат (число или строку), полученный после выполнения всех операций. Если имеется более одного выхода, объедините их, чтобы получить один результат (без разделителей). Начальное значение переменной всегда равно нулю. то есть: это начинается в0


Синтаксис языка:

Язык имеет следующие операторы:

inc  ---> add one to variable
dec  ---> remove one from variable
mult ---> multiply variable by 2
half ---> divide the variable by 2
Pri  ---> print the variable to console (or whatever your language has)
exit ---> end the program (anything after this is ignored)

Примеры:

inc inc inc dec Pri exit                 ---> 2
dec inc mult inc inc Pri                 ---> 2
inc inc inc mult half Pri exit inc       ---> 3
inc Pri inc Pri inc Pri exit half mult   ---> 123
Pri exit                                 ---> 0
inc half Pri exit                        ---> 0.5 

Ограничение:

Это код-гольф, поэтому победит самый короткий код в байтах для каждого языка.


Замечания:

  • Ввод всегда будет действительным. (строка операторов, разделенных пробелом)
  • Вы можете округлить до ближайшего целого числа, если не хотите десятичных знаков.

3
Могу ли я взять список строк? Могу ли я использовать другую заглавную букву?
user202729

Добавить выходной регистр? выход должен иметь значение
l4m2

1
@Kaldo: Вы можете отделиться, используя новые строки
Мухаммед Салман,

3
Хм, я бы не назвал этот язык "языком игры в гольф".
Пало Эберманн

1
Это Deadfish с двойным и половинным вместо квадратных и длинных имен команд
Джо Кинг,

Ответы:


8

Баш , 61 байт

sed '1i0
s/.//2g;y"idmhe"+-*/q";/+\|-/i1
/*\|\//i2
/P/cdn'|dc

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

Преобразует программу в программу постоянного тока, а затем оценивает ее как код постоянного тока. Это берет ввод, разделенный новыми строками. Обратите внимание, что dc основан на стеке и использует обратную польскую запись.

Вход сначала передается в sed

1i0 в первой строке ввода вставьте (prepend) a 0, это будет аккумулятор

s/.//2g удалить все, кроме первого символа в каждой строке

y"idmhe"+-*/q"транслитерируйте idmheв +-*/qсоответственно, + - * / - арифметические команды и q выходит из программы

/+\|-/в каждой строке, содержащей + или -, i1вставьте 1

/*\|\//в каждой строке, содержащей * или /, i2вставьте 2

/P/в каждой строке, содержащей P, cdnизмените его на dnэквивалентный дубликат и выведите без перевода строки в dc

Теперь это оценивается как выражение постоянного тока.


2
Я полагаю, что не sedисключено, что синтаксис станет еще более чуждым, чем считалось ранее, когда в игру вступит гольф.
Матеин Улхак,

6

Желе , 21 байт

ḲḢ€O%11ị⁾’‘j“IȮḤH”¤VI

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


Обратите внимание, что значения ASCII первых символов ( idmhPe) по модулю 11 являются уникальными по модулю 6.


Использование по модулю 16:

Желе , 21 байт

ḲḢ€O%⁴ị“ḢwġḞkz’ṃØJ¤VI

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

В ḤH‘’IȮэтом случае используется строка для индексации . Они ‘’больше не на границах.


Использование 11 байтов для представления 6-байтовой строки ... очень плохо. Но ... “”занимает 2 байта, ¤занимает 1 байт, сами данные занимают 6 байтов, осталось 2 байта, чтобы что-то сделать. В настоящее время это и j, но ịØJили ṃØJнамного хуже, и не работает (потому что Unicode).
user202729

Концепция строки в jli («Строка - это список целых чисел со специальным флагом, влияющим на печать») великолепна.
user202729

5

R , 128 125 байт

Reduce(function(x,y)switch(y,i=x+1,d=x-1,m=x*2,h=x/2,P={cat(x);x}),substr(el(strsplit(gsub("e.*$","",scan(,""))," ")),1,1),0)

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

Должен вызываться с, source(echo=FALSE)чтобы предотвратить автоматическое распечатывание возвращаемого значения. Альтернативой может быть завернуть все,invisible но это гораздо меньше, чем игра в гольф (и разрушает мой [все еще] хороший счетчик байтов).


3

05AB1E , 25 байтов

΀¬"idmhPe"S"><·;=q"S‡J.V

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

Сопоставляет каждую языковую функцию с соответствующей функцией 05AB1E (используя первый символ каждой функции), а затем выполняет результирующую строку как код 05AB1E.



2

Python 2 , 131 125 122 121 118 117 115 байтов

v=0;o=""
for x in input().split("x")[0].split():
 if"Q">x:o+=`v`
 else:v+=(1,-1,v,-v/2.)['idmh'.find(x[0])]
print o

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

-6 и -3 благодаря @Rod

-3 и -2 благодаря @etene

-1 путем замены "Pri"==xна"P"in x


Вы можете splitвключить "exit"и получить 1-й блок, вместо breakэтого сохранив 4 байта
Rod

1
Вы можете убрать круглые скобки 'idmh'и использовать findвместо них index, что сэкономит несколько байтов
etene

@Rod - на самом деле может пойти дальше и разделить на части, exчтобы сохранить еще 2
ElPedro

Вы можете заменить v=(v+1,v-1,v*2,v/2.)на v+=(1,-1,v,-v/2.)него, должно работать, не проверял, хотя
Род

@Rod - думал об этом, но не мог понять, как это сделать half. Так просто! Благодарю.
ElPedro

2

Python 3 , 110 91 82 байта

exit приведет к выходу программы с ошибкой.

x=0
for c in input():c=='P'==print(x,end='');x+=(1,-1,x,-x/2,c,0)['ndmhx'.find(c)]

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


Сократите имена переменных, чтобы сохранить 9 байтов. i='x+=1';d='x-=1';...и затем в вашем execвызове измените его наexec(eval(c[0]))
mypetlion

@mypetlion Спасибо, но я нашел лучший способ.
mbomb007

Я думаю, что это действительно: 82 байта
Линн

@ Линн Это здорово! Я не мог придумать хороший способ замкнуть это printутверждение!
mbomb007

2

JavaScript (ES6), 83 79 байт

Сохранено 4 байта благодаря @ l4m2

Итеративно заменяет инструкции либо выходными, либо пустыми строками.

s=>s.replace(/\S+./g,w=>m<s?'':w<{}?m:(m+={d:-1,e:w,i:1,m}[w[0]]||-m/2,''),m=0)

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

комментарии

s =>                       // given the input string s
  s.replace(/\S+./g, w =>  // for each word w in s:
    m < s ?                //   if m is a string:
      ''                   //     ignore this instruction
    :                      //   else:
      w < {} ?             //     if w is 'Pri' ({} is coerced to '[object Object]'):
        m                  //       output the current value of m
      : (                  //     else:
          m +=             //       add to m:
            { d: -1,       //         -1 if w is 'dec'
              e: w,        //         w  if w is 'exit' (which turns m into a string)
              i: 1,        //         1  if w is 'inc'
              m            //         m  if w is 'mult'
            }[w[0]]        //       using the first character of w to decide
            || -m / 2,     //       or add -m/2 (for 'half') if the above result was falsy
        ''),               //       do not output anything
    m = 0                  //   m = unique register of our mighty CPU, initialized to 0
  )                        // end of replace()

s=>s.replace(/\S+./g,w=>k<s?'':w<{}?k:(k+={d:-1,e:w,i:1,m:k}[w[0]]||-k/2,''),k=0)
l4m2

@ l4m2 Это w<{}чистое зло: р
Арно

s=>s.replace(/\S+./g,e=>m<s?'':e<{}?m:(m+={d:-1,e,i:1,m}[e[0]]||-m/2,''),m=0)также работа
l4m2

2

Древесный уголь , 37 35 байт

≔⁰ηF⎇№θx…θ⌕θxθ≡ιn≦⊕ηd≦⊖ηm≦⊗ηh≦⊘ηrIη

Попробуйте онлайн! Ссылка на подробную версию кода. Вдохновленный ответом @ RickHitchcock. Объяснение:

≔⁰η

Очистить переменную.

F⎇№θx…θ⌕θxθ≡ι

Обрежьте вход в xслучае, если он есть, затем зациклите и включите каждый символ (остаток) от ввода.

n≦⊕η

nя п инкрементов переменную.

d≦⊖η

d d экранирует переменную.

m≦⊗η

m m умножает переменную на два (т.е. удваивает).

h≦⊘η

h h alves переменная.

rIη

rp r вставляет переменную, приведенную к строке.


1
@RickHitchcock Извините, недостаточно тщательно протестировал. Я нашел обходной путь, но это стоило мне байта.
Нил

2

JavaScript (ES6), 77 75 байт

(Заимствовано ( украдено ) @ Уловка Арно, использующая в mкачестве имени переменной, экономя 2 байта.)

f=([c,...s],m=0)=>c<'x'?(c=='P'?m:'')+f(s,m+({h:-m/2,d:-1,n:1,m}[c]||0)):''

Рекурсивно обходит строку, ища различные буквы в каждой инструкции и игнорируя остальные:

  • n: inc
  • д: декабрь
  • м: мульт
  • ч: половина
  • P: Pri
  • х: выход

Принимает преимущество в том , что не undefinedявляется ни больше , ни меньше , чем 'x', в результате чего рекурсии до остановки в конце строки или когда он встречает 'x'в выходе .


1
После вашего удаленного комментария, на который я, конечно, больше не могу отвечать, я забыл вставить ссылку на исправленный код (черт!), Но я нашел новый подход, который на 2 байта короче, чем моя первоначальная попытка.
Нил


1

JavaScript (Node.js) , 91 байт

_=>_.split` `.map(o=>o<{}>!_?S+=+i:o<"e"?i--:o<"f"?++_:o<"i"?i/=2:o<"j"?i++:i*=2,i=S="")&&S

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

JavaScript (Node.js) , 96 байт

_=>_.split` `.map(o=>F?0:o<"Q"?S+=i:o<"e"?i--:o<"f"?F=1:o<"i"?i/=2:o<"j"?i++:i*=2,F=i=0,S="")&&S

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

JavaScript (Node.js) , 99 байт

s=>s.split` `.map(_=>eval('++i7--i7++e7u+=+i7i*=27i/=2'.split(7)[Buffer(e+_)[0]%11%6]),e=i=u='')&&u

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


1

JavaScript, 107 байт

s=>eval('x=0;x'+(s.split` `.map(v=>({i:"++",d:"--",m:"*=2",h:"/=2",P:";alert(x)",e:"//"})[v[0]]).join`;x`))


1

Lua, 207 байт

s=0;n=0;for a in io.read():gmatch'.'do if s==0 then s=1;n=a=='i'and n+1 or a=='d'and n-1 or a=='m'and n*2 or a=='h'and n/2 or n;if a=='P'then print(n)elseif a=="e"then break end elseif a==' 'then s=0 end end

1

Python 3 , 114 110 109 116 байт

На самом деле в Python 2 потребовалось бы на два байта меньше, потому что execэто оператор и не нуждается в скобках ...

  • Сохранено 4 дополнительных байта благодаря @ElPedro

  • Сохраненный дополнительный байт, используя тот факт, что findпри ошибке возвращается -1, который затем можно использовать в качестве индекса

  • +7 байт, потому что я не заметил правила отсутствия перевода строки :(

i=0;exec(";".join("i+=1 i-=1 i*=2 i/=2 print(i,end='') exit()".split()["idmhP".find(h[0])]for h in input().split()))

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

Отображает первый символ каждого входного слова на фрагмент кода Python. Затем они объединяются и execредактируются.

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


112 Попробуйте онлайн! если у вас есть команды в виде разделенной пробелами строки и разделите ее.
ElPedro

1
110 на самом деле, как скобки могут пойти Попробуйте онлайн!
ElPedro

Это не дает правильный вывод. В вопросе говорится, что вы должны печатать без разделителей, так что вам нужно print(i,end=''). Смотрите 4-й контрольный пример.
mbomb007

Я не заметил, я это исправлю. Благодарность !
18:00 в Этене

@etene Комментарий, когда вы это исправите, и я уберу свое понижение.
mbomb007

1

Рубин + -na, 81 73 65 байт

x=0;$F.map{|w|eval %w{x+=1 x-=1 1/0 $><<x x*=2 x/=2}[w.ord%11%6]}

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

Довольно просто. Для первой буквы каждого слова найдите соответствующую командную строку и evalее. Использует целочисленное деление и exitsбросая ZeroDivisionError.

-5 байт: использовать .ord%11%6вместо поиска строки. Кредит идет в пользователю202729

-3 байта: .ordучитывает только первый символ строки, поэтому я могу пропустить[0] .

-8 байт: используйте -aфлаг для автоматического разделения ввода, благодаря Кириллу Л.


1
Вы можете сэкономить еще больше байтов, добавив -aопцию, чтобы сделать автоматическое разделение для вас, как это
Кирилл Л.

1

Эмоджикод , 270 байт

🐖🔥🍇🍮c 0🔂j🍡💣🐕🔟 🍇🍊😛j🔤inc🔤🍇🍮c➕c 1🍉🍋😛j🔤dec🔤🍇🍮c➖c 1🍉🍋😛j🔤mult🔤🍇🍮c✖️c 2🍉🍋😛j🔤half🔤🍇🍮c➗c 2🍉🍋😛j🔤Pri🔤🍇👄🔡c 10🍉🍓🍇🍎🍉🍉🍉

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

🐋🔡🍇
🐖🔥🍇
🍮c 0
🔂j🍡💣🐕🔟 🍇
🍊😛j🔤inc🔤🍇🍮c➕c 1🍉
🍋😛j🔤dec🔤🍇🍮c➖c 1🍉
🍋😛j🔤mult🔤🍇🍮c✖️c 2🍉
🍋😛j🔤half🔤🍇🍮c➗c 2🍉
🍋😛j🔤Pri🔤🍇👄🔡c 10🍉
🍓🍇🍎🍉🍉🍉🍉

🏁🍇
 🔥🔤inc inc inc dec Pri exit🔤
😀🔤🔤
 🔥🔤dec inc mult inc inc Pri🔤
😀🔤🔤
 🔥🔤inc inc inc mult half Pri exit inc🔤
😀🔤🔤
 🔥🔤inc Pri inc Pri inc Pri exit half mult🔤
😀🔤🔤
 🔥🔤Pri exit🔤
😀🔤🔤
 🔥🔤inc half Pri exit🔤
🍉

0

SNOBOL4 (CSNOBOL4) , 165 байт

	P =INPUT ' exit ' 
	x =0
S	P LEN(1) $ L ARB ' ' REM . P	:S($L)F(end)
i	X =X + 1	:(S)
d	X =X - 1	:(S)
P	O =O X		:(S)
m	X =X * 2	:(S)
h	X =X / 2.	:(S)
e	OUTPUT =O
END

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

Валовой.

	P =INPUT ' exit ' 				;* append ' exit ' to the input to guarantee that the program will stop
	x =0						;* initialize x to 0 else it won't print properly if the program is 'Pri'
S	P LEN(1) $ L ARB ' ' REM . P	:S($L)F(end)	;* set L to the first letter of the word and goto the appropriate label
i	X =X + 1	:(S)
d	X =X - 1	:(S)
P	O =O X		:(S)				;* append X to the output string
m	X =X * 2	:(S)
h	X =X / 2.	:(S)				;* divide by 2. to ensure floating point
e	OUTPUT =O					;* print whatever's in O, which starts off as ''
END

0

C # (.NET Core), 186 байт

class P{static void Main(string[]a){int v=0;foreach(var s in a){var i=s[0];if(i=='i')v++;if(i=='d')v--;if(i=='m')v*=2;if(i=='h')v/=2;if(i=='P')System.Console.Write(v);if(i=='e')break;}}}

Вы можете сократить это на 26 байт, выполнив несколько простых вещей, таких как объявление iс vпомощью таблицы ASCII, чтобы вы могли использовать небольшие числа, перегруппировать ifs, а затем использовать троичный: class Z{static void Main(string[]a){int v=0,i;foreach(var s in a){i=s[0]%'d';if(i==1)break;if(i>9)System.Console.Write(v);else v=i<1?v-1:i<5?v/2:i<6?v+1:v*2;}}}(PS объяснение того, как это работает и как использовать это (например, ожидает аргументы командной строки) всегда приветствуется!)
VisualMelon

(О, это стыдно ... Я должен был использовать %50вместо %'d')
VisualMelon

0

Perl 5 -a , 61 байт

eval'$,'.qw(++ -- ;exit ;print$,||0 *=2 /=2)[(ord)%11%6]for@F

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

Украл ord%11%6трюк пользователя user202729

Как?

-a            # split the input by whitespace, store in @F
eval          # Execute the string that results from:
'$,'          # $, (the accumulator)
.             # appending:
qw(           # create an array for the following whitespace separated values:
++ --            # operators for inc & dec
;exit            # exit
;print$,||0      # Pri  (||0 ensures that 0 is output if accumulator is null
*=2 /=2)         # mult div
[(ord)%11%6] # @user202729's trick selects one of the preceding operations
for@F        # for every term input

0

Pyth, 44 байта

Vmx"idmhPe"hdcwd=Z@[hZtZyZcZ2ZZ)NIqN4pZIqN6B

Тестирование

объяснение

Vmx"idmhPe"hdcwd=Z@[hZtZyZcZ2ZZ)NIqN4pZIqN6B   ## full program
             cwd                               ## split input on space
Vmx"idmhPe"hd                                  ## iterate through list of numbers corresponding to operators
                =Z@[hZtZyZcZ2ZZ)N              ## assign the variable Z (initialliy Zero) it's new value
                                 IqN4pZ        ## print Z if the current operator is "Pri" (4)
                                       IqN6B   ## break if the current operator is "exit" (5)

0

TI-BASIC, 112 байт

Это использует некоторые предположения, которые AFAIK совершенно приемлемы. Во-первых, все переменные инициализируются нулями до выполнения; номер два в том, что вход берется через Ans.

Ans+" E→Str1
While 1
I+4→I
sub(Str1,I-3,1→Str2
A+(Ans="I")-(Ans="D
If inString("MH",Str2
Then
I+1→I
2AAns+A/2(1-Ans
End
If Str2="P
Disp A
If Str2="E
Stop
Ans→A
End

0

Java (OpenJDK 8) , 164 байта

a->{int c=0;for(String g:a.split(" ")){char b=g.charAt(0);if(b==105)c++;if(b==100)c--;if(b==109)c*=2;if(b==104)c/=2;if(b==80)System.out.print(c);if(b==101)return;}}

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

Выше мое решение, которое округляется до целых чисел, но ниже мое решение, которое обрабатывает десятичные дроби. Ненавистный способ, которым двойные отпечатки java добавляют еще 55 байтов к счету. Я оставил новые строки, чтобы сделать код более читабельным во втором представлении только потому, что это по сути то же самое решение с одной дополнительной командой и оператором импорта.

Java (OpenJDK 8) , 219 байт

a->{
double c=0;
for(String g:a.split(" ")){
char b=g.charAt(0);
if(b==105)c++;
if(b==100)c--;
if(b==109)c*=2;
if(b==104)c/=2;
if(b==80)System.out.print(new DecimalFormat("0.#").format(c));
if(b==101)return;}}

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


0

C (gcc) , 120 114 111 байтов

-6 байт благодаря потолку.

x,d;f(char*s){for(x=0;s>1;s=index(d^1?s:"",32)+1)d=*s-100,x+=d?d==5:-1,x*=d^9?d^4?1:.5:2,d+20||printf("%d",x);}

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

124 байта

Версия с плавающей точкой:

d;f(char*s){for(float f=0;s>1;s=strchr(s,32)+1)d=*s-80,f+=d==25,f-=d==20,f*=d^29?d^24?1:.5:2,s=d^21?s:"",d?:printf("%f",f);}

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

Я не беспокоился о версии, которая округляется, но делает исключение для 0, что будет разрешено, если я правильно понимаю цепочку комментариев.


0

33 , 62 байта

s'i'{1a}'d'{1m}'m'{2x}'h'{2d}'P'{o}'e'{@}It[mzsjk""ltqztItn1a]

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

Эта программа принимает инструкции, разделенные символами новой строки

Объяснение:

It[mzsjk""ltqztItn1a]
  [mz            n1a] | Forever
It    jk       It     | - Get the first character of the next instruction
            qz        | - Call the function declared previously
     s  ""lt  t       | - Make sure we don't lose track of the variable

Код перед этим сегментом определяет все функции.

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