シンプルなゴルフ通訳


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
うーん、私はその言語を「ゴルフ言語」とは呼びません。
パウロEbermann

1
これは、正方形ではなく、2つ半のデッドフィッシュで、より長いコマンド名
ジョーキング

回答:


8

バッシュ、61バイト

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

オンラインでお試しください!

プログラムをDCプログラムに変換してから、DCコードとして評価します。これは、改行で区切られた入力を取ります。dcはスタックベースであり、逆ポーランド記法を使用することに注意してください。

入力は最初にsedにパイプされます

1i0 入力の最初の行に、0を挿入(追加)します。これがアキュムレーターになります

s/.//2g 各行の最初の文字以外をすべて削除します

y"idmhe"+-*/q"それぞれに文字idmhe変換+-*/q、+-* /は算術コマンドで、qはプログラムを終了します

/+\|-/+または-を含むすべての行にi11を挿入します

/*\|\//*または/を含むすべての行にi2、2を挿入します

/P/Pを含むすべての行で、cdnそれをdn、DCの改行なしで複製および出力に相当します

現在、これはDC式として評価されます。


2
sedゴルフが始まると、以前考えられていたよりもさらに異質になる構文を期待するのは不合理ではないと思います。
Mateen Ulhaq

6

ゼリー、21バイト

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

オンラインでお試しください!


idmhPe11を法とする最初の文字()のASCII値は、6を法とする一意であることに注意してください。


モジュロ16の使用:

ゼリー、21バイト

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

オンラインでお試しください!

ḤH‘’IȮこの場合、インデックスの作成に使用される文字列です。‘’境界にされなくなりました。


6バイトの文字列を表すために11バイトを使用するのは...残念です。しかし... “”2バイト¤かかり、1バイトかかり、データ自体は6バイトかかります。何かをするために残っているのは2バイトです。現在はand jですがịØJṃØJさらに悪いことには機能しません(Unicodeのため)。
user202729

jliの文字列の概念(「文字列は、印刷に影響を与える特別なフラグを持つ整数のリストです」)は素晴らしいです。
user202729

5

R128125バイト

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ラップすることもできますが、それははるかに少ないゴルフです(そして私の[まだ]素敵なバイト数を台無しにします)。



2

、121バイト

func[s][v: 0 parse s[any[["i"(v: v + 1)|"d"(v: v - 1)|"m"(v: v * 2)|"h"(v: v / 2.0)|"P"(prin v)|"e"(exit)]thru" "| end]]]

オンラインでお試しください!

読みやすい:

f: func [s] [
    v: 0
    parse s [
        any [
            [ "i" (v: v + 1)
            | "d" (v: v - 1)
            | "m" (v: v * 2)
            | "h" (v: v / 2.0)
            | "P" (prin v)
            | "e" (exit)]
            thru [" " | end]
        ]
    ]
] 

2

パイソン2131の 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のおかげで

@eteneのおかげで-3および-2

-1と置き換えること"Pri"==xにより"P"in x


次のことが可能split"exit"し、代わりに、第一のブロックを取得breakする 4バイトの節約
ロッド

1
括弧を削除しての代わりに'idmh'使用findするとindex、数バイト節約できます
etene

@Rod-それを実際にもう少し進めて、さらにex2を節約するために分割できます
ElPedro

動作するはずですが、テストv=(v+1,v-1,v*2,v/2.)するv+=(1,-1,v,-v/2.)ことはできませんで置き換えてください
Rod

@Rod-それについて考えましたが、どうやってやるのか解りませんでしたhalf。とても簡単!ありがとう。
エルペドロ

2

Pythonの3110の 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バイト
リン・

@Lynnそれは素晴らしい!私はprint声明に短絡する良い方法を考えることができませんでした!
mbomb007

2

JavaScript(ES6)、83 79バイト

@ l4m2のおかげで4バイト節約

命令を出力または空の文字列で繰り返し置換します。

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<{}純粋な悪である:P
アルノー

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≦⊕η

ni nは変数をインクリメントします。

d≦⊖η

d d変数をインクリメントします。

m≦⊗η

m mは、変数を2倍(つまり、倍数)にします。

h≦⊘η

h hは変数をalvesします。

rIη

rp rは、文字列にキャストされる変数を初期化します。


1
@RickHitchcock申し訳ありませんが、十分にテストしていませんでした。回避策を見つけましたが、1バイトかかりました。
ニール

2

JavaScript(ES6)、77 75バイト

(借りた(盗んだ)@Arnauldの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:株式会社
  • d:12月
  • m:マルチ
  • h:半分
  • P:プリ
  • x:終了

undefined大きくも小さくもないという事実を利用して'x'、文字列の最後で、または'x' in exitに遭遇したときに再帰を停止します


1
もちろん返信できなくなったあなたの削除されたコメントに続いて、修正したコード(d'oh!)へのリンクを貼り付けるのを忘れましたが、とにかく元の試みよりも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の3114 110 109 116バイト

Python 2 execでは、ステートメントであり、括弧を必要としないため、実際には2バイト少なくなります...

  • @ElPedroのおかげで4バイト追加

  • 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 オンラインで試してみてください!コマンドをスペース区切りの文字列として使用し、分割する場合。
エルペドロ

1
実際には、ブラケットが使用できるように、オンラインで試してみてください!
エルペドロ

これは正しい出力を提供しません。質問では、セパレータなしで印刷する必要があるため、必要print(i,end='')です。4番目のテストケースを参照してください。
mbomb007

私は気づかなかった、私はそれを修正します。ありがとう!
エテン

@eteneあなたがそれを修正したらコメントし、私は私の下票を削除します。
mbomb007

1

Ruby + -na81 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文字列検索の代わりに使用します。クレジットは user202729になります

-3バイト: .ord文字列の最初の文字のみを考慮するため、をスキップでき[0]ます。

-8バイト:使用 -aフラグをして、キリルLのおかげで入力を自動的に分割します


1
あなたは追加することによって、さらに多くのバイトを保存することができます-aように、あなたのための自動splitを行うためのオプションを、この
キリルL.を

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

あなたは宣言のように、いくつかの簡単な事をすることによって、このオフ26bytesを剃ることができますiv、あなたが小さな番号を使用することができるようにASCIIテーブルを参照、並べ替えるif:Sをして、三元使用して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、61 -aバイト

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

オンラインでお試しください!

@ user202729のord%11%6トリックを盗んだ

どうやって?

-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バイト

これは、完全に受け入れられるいくつかの仮定を利用しています。1つ目は、すべての変数が実行前にゼロに初期化されることです。番号2は、入力が経由で取得されること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バイトが追加されます。2番目のサブミットでコードを読みやすくするために新しい行を残しました。これは、1つの追加コマンドとimportステートメントを備えた基本的に同じソリューションであるためです。

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バイト

ceilingcatのおかげで-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

そのセグメントの前のコードは、すべての機能を定義しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.