揮発性を解釈する


11

揮発性を解釈する

Volatileは、A_ / a '_' / Aによって作成されたスタックベースのesolangであり、8つの命令しかなく、完全に処理しています。ただし、これは非決定的でもあります。つまり、プログラムが常に同じ出力を与えるわけではありません。あなたの仕事はこの言語を解釈することです。

言語仕様

esolangsページから取得:

~: Push a random integer in any range of integers. Minimum range of 0 through 32768

+: Pop 2 values and push the sum of the 2 values

-: Like +, but subtracts

*: Multiply

/: Divide. 0-division will result in an error.

:: Duplicate the top of the stack

.: Output the top of the stack without popping it


(...): Execute ... inside a while loop when the top of the stack is not 0

他はすべて無視されます

入力

これらのプログラムはランダムに失敗する可能性があることに注意してください

~:/::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.~:/:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.~:/::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.~:/::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.~:/:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.~:/::::::::::::::::::::::::::::::::::::::::::::++++++++++++++++++++++++++++++++++++++++++++.~:/::::::::::::::::::::::::::::::::++++++++++++++++++++++++++++++++.~:/:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.~:/:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.~:/::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.~:/::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.~:/::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.~:/:::::::::::::::::::::::::::::::::+++++++++++++++++++++++++++++++++.~:/::::::::::++++++++++.

~:-.~:/+.(~:/+.)

~:-:/

出力

73 102 109 109 112 45 33 120 112 115 109 101 34 11

0 1 2 3 4 5 6 7 8 9 ...

<Any Error Message>

その他の例と参照実装((もう1つの)python 3インタープリターの下にある2番目の例を使用)は、https://esolangs.org/wiki/Volatileにあります。

得点

これはコードゴルフなので、バイト単位の最短の答えが勝ちます

リーダーボード

これは、通常のリーダーボードと言語ごとの勝者の概要の両方を生成するスタックスニペットです。

回答が確実に表示されるようにするには、次のMarkdownテンプレートを使用して、見出しから回答を始めてください。

# Language Name, N bytes

N提出物のサイズはどこですか。スコアを向上させる場合、古いスコアを打ち消すことで見出しに残すことができます。例えば:

# Ruby, <s>104</s> <s>101</s> 96 bytes

ヘッダーに複数の数値を含める場合(たとえば、スコアが2つのファイルの合計である場合や、インタープリターフラグのペナルティを個別に一覧表示する場合)、実際のスコアがヘッダーの最後の数値になるようにしてください。

# Perl, 43 + 2 (-p flag) = 45 bytes

言語名をリンクにして、リーダーボードスニペットに表示することもできます。

# [><>](http://esolangs.org/wiki/Fish), 121 bytes


2
除算は0に丸めることになっていますか?
Grimmy

ない~整数、または任意の番号をプッシュしますか?
mbomb007

1
また、実装によっては、これが実際に非決定的であるとは限りません。確かに、esolangページはそうだと主張していますが、それは、1ゼロで除算される可能性があるpush にリストされている方法が原因です。~ゼロをプッシュできる必要があります。それ以外の場合は確定的です。また、RNGは、任意の数のゼロが連続した後に常にゼロを返すことができる必要があります。
mbomb007

2
その2番目の入力は~:-.~:/+.(~:/+.)0 1 2 ...代わりにから始めるべきではありません1 2 3 ...か?その~:-.結果、0が出力されます。Esolangページのそれらの通訳はこれを確認しているようです(ここでは2番目)。
Kevin Cruijssen、

2
テストケースを追加する提案:~:-.(~:/+.)
Night2

回答:


6

05AB1E、35バイト

"~:/.()"”žGÝΩ DŠéõq}÷ = [D_# }”#‡.V

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

揮発性コードを05AB1Eにトランスパイルし、評価します。*+および-ままにしておくことができます。:.、および)ダイレクト1バイトの同等を持っています。他のコマンドは、それぞれ数バイトかかります。残念ながら、05AB1Eは0による除算でクラッシュしないため、条件付きの「スタックの最上位== 0の場合に終了」によって代わりに実装されます。


1
これはループに対して正しく機能しますか?2番目のテストケースを入力する01、ループの前に正しく出力されているように見えますが、Volatileプログラム(暗黙の入力)自体の出力を開始します。私D Doingõqはif文の辞書文字列が好きです。:)
Kevin Cruijssen

1
@KevinCruijssenの例では、ループはであると想定しているようですwhile peekが、参照インタープリターではwhile popです。この例は、いくつかを追加することで修正できます:TIO)。または、をwhile peek追加して、コードをに変更できますD
Grimmy

1
0 1 2 3 ...ただし、Esolangからの両方のリファレンスインタープリターがまだ出力されます。私は彼らのソースコードを見ていませんが、両方を試してみました。
Kevin Cruijssen

1
@KevinCruijssenああ、関数はpopという名前ですが、実際はのぞき見です。非常に混乱します。Dコードにを追加しました。
Grimmy

Lol ..組み込み名の混乱は、Javaのreplacevsを思い出させますreplaceAll(どちらもすべての出現replaceAll箇所を置き換えますが、は正規表現を使用し、もう1つはそうではありません)。xD
Kevin Cruijssen

4

ジュリア 1.0、334バイト

a\b=push!(a,b)
a=pop!(a)
v(q,s=[],l=0)=(i=1;
for c in q
!r=c==r
i+=1
!')' ? (l<1 && break;l-=1) :
!'(' ? (while s[end]!=0 v(q[i:end],s) end;l+=1) :
l>0 ? continue :
!'~' ? s\rand(Int) : 
!'+' ? s\(s+√s) :
!'-' ? s\(s-√s) :
!'*' ? s\(s*√s) :
!'/' ? s\(s÷√s) :
!':' ? s\s[end] :
!'.' ? print(s[end]," ") : 0
end)

あらゆるタイプの私の最初の「通訳」は、予想よりも簡単でした。基本的なゴルフをしましたが、まだまだ余裕があります。の出力後にスペースを印刷するようにしました。出力例にマッハします。ゴルフされていないバージョンは、TIOリンクのヘッダーにあります。使用例v("~:-:/")

ループカウンターを追加することで指摘されたバグNight2を修正するための+41バイト。今、トランスパイルが良い選択肢である理由がわかります。良いテストケースは~:-.(~:/+.)(~:/+.())~:-.期待される出力です0 0

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


3

ルーン文字エンチャント266の 264バイト

DS͗{r;'ui[0[0y̤<<<<<?+f2,;$"!0/"?*7≠0:S͗\
RS͗}:'~=?!\:':=?!\:'+=?!\:'-=?!\:'/=?!/:'.=?!\:'*=?!\:';=?!;:')≠3*?04B͍:'(=?!S͗
U/lA`R耀`S͗/?7  :S͗/?+f1+S͗/?3  -S͗/?3     $ '$:S͗/?7  *S͗/
U\m(d*?"SO!"$;
{:'(=?!\:')=?!\R
~/?)0l{͗/?8 {͗l}͗/U
 \}͗21B͍

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

ルーン文字に組み込まれた制限のためには、それだけ〜50のプログラムの長さ(およびスタックサイズ)をサポートすることができます1。大きすぎるプログラムは単純に失敗します。スタックが大きくなりすぎると、エラーになりますSO!(必須ではありませんが、サイレント終了よりも優れていました。コストは24バイトです)。プログラムが0で除算しようとすると、が出力されます/0!

RunicはSTDERRに書き込む方法がないため、エラーは標準出力の最後に追加されます。

このバージョンは、任意の長いプログラムをサポートしますが、それでもスタックの最大数は90に制限され(したがって、最初のテストプログラムの2番目の結果でエラーが発生します)、うまく機能していません(S͗}:との間のコマンド長の増加)。S͗}͍:0%:、いくつかの必要なセクションを整列させるための追加の間隔ですが、その余分なスペースにより、<最大スタックサイズが大きくなります。

あるいは、このプログラム~ゼロの生成を回避し、プログラムは100万実行ステップ(Runicインタープリターに組み込まれた無限ループに対する保護)の後で終了します。余分なNOPスペースをスキップして少し長く実行するための数バイトも含まれています。

  1. (IP mana + 10)で特大のちらつきが発生し、Volatileのスタックに入れたチェックは sizeof(stack) < manaは、マナ(50頭文字)をマージして組み合わせる5つのIPです。その値を真の制限(+10)に増やすと、さらに2バイトのコストがかかり、ロジックが正確ではなくゴルフのようになりました。

説明

揮発性の流れ

  1. プログラムは、上部中央の青いエリアから始まります。 <<<<<、5つのIPはy
  2. IPは左に移動し、スタックをセットアップして入力を読み取り、シアンのセクションに移動します
  3. IPはこの行の右下に移動し、スタックの先頭の文字をチェックして、コマンドを確認します。この線は、表示されているよりもさらに右に続きます。正しい命令が見つかると、左下の行のコードが実行されます(他のセクションをスキップして、青でシアンに戻ります)。
  4. マゼンタセクションは実行中に実行されます ~:スタックオーバーフローか、エラーのコマンドを実行します。スタックがいっぱいでない場合、黄色のセクションはスキップされ、ラップアラウンドでダークブルーに戻ります。
  5. 右に遠いとき )赤い部分と右に移動するプログラム分岐を発見されました。
  6. このセクションは、コマンドスタックを右に回転させて、 (が見つかる(緑に進む)。
  7. 追加)が見つかるたびに(オレンジ色に進む)、スタック深度スタックがバンプされ、(が見つかると、スタック深度スタックが1回ポップされます(ダークグリーンとオレンジ色の再入力に進みます)
  8. 深度スタックが空の場合は、緑に続いて B、シアンからメインの解析ループに戻ります。それ以外の場合は、オレンジ->黄色->赤(ループリセットループに再び入る)でラップします。
  9. 右上の紫は除算を処理し、除算する値が0の場合、茶色のセクションがエラーと終了を処理します。シアンのセクションをスキップして、メインの解析ループに再び入ります。

2

PHP、196バイト

eval(strtr($argn,[':'=>($v='$a[]=').$e='end($a);','~'=>$v.'rand();','+'=>($q=$v.$p='array_pop($a)')."+$p;",'-'=>"$q-$p;",'*'=>"$q*$p;",'/'=>"$q/$p;",'.'=>"echo' ',$e",'('=>"for(;$e){",')'=>'}']));

入力1:オンラインでお試しください!

入力2(0、1、2、...):オンラインでお試しください!

入力3(ゼロによる除算エラー):オンラインで試してください!

コードをPHPに変換して評価するだけです!


2

JavaScriptの(V8)  178の172  171バイト

JSへのトランスパイル。Z is not definedまたはx is not definedコードが何か悪いことを行おうとすると、いずれかがスローされる可能性があります。

s=>eval(s.replace(/./g,c=>`S.push(${c>'}'?'x=Math.random()*1e5|0':c>'9'?'x':c=='.'?');print(x':c<')'?');while(x){(0':c<'*'?')}(0':`1/(x${c}=S.pop(S.pop()))?x:Z`});`,S=[]))

最初のプログラムをオンラインでお試しください!

2番目のプログラムをオンラインでお試しください!

3番目のプログラムをオンラインでお試しください!

どうやって?

各命令はに変換さS.push(れ、特定のパターンが続き、さらにが続き);ます。

JSはそのような無害な操作について少し気まずいため、ゼロによる除算を明示的にテストする必要があります。:-p

チャー。| JSコード
------- + --------------------------------------
   〜| S.push(x = Math.random()* 1e5 | 0);
   + | S.push(1 /(x + = S.pop(S.pop()))?x:Z);
   -| S.push(1 /(x- = S.pop(S.pop()))?x:Z);
   * | S.push(1 /(x * = S.pop(S.pop()))?x:Z);
   / | S.push(1 /(x / = S.pop(S.pop()))?x:Z);
   :| S.push(x);
   。| S.push(); print(x);
   (| S.push(); while(x){(0);
   )| S.push()}(0);

2

Java 8、420 418 402 373 359 357 341バイト

import java.util.*;s->f(s,new Stack());void f(String s,Stack<Integer>S){for(int i=0,c,t,u;i++<s.length();){if((c=s.charAt(i-1))<42&&S.peek()!=0)f(s.substring(40/c*i),S);if(c==46)System.out.println(S.peek());if(c>57)S.add(c>99?new Random().nextInt():S.peek());if(c<44|c==45|c==47){t=S.pop();u=S.pop();S.add(c<43?u*t:c<45?u+t:c<46?u-t:u/t);}}}

@Grimyのおかげで-2バイト。@ceilingcatの
おかげで-16バイト。

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

説明:

import java.util.*;       // Required import for 2x Stack and Random

s->                       // Method with String parameter and no return-type
  f(s,new Stack())        //  Call the recursive function, with a new Stack

// Separated recursive method with String and Stack parameters
void f(String s,Stack<Integer>S){
  int i=0,                //  Index integer
      c,                  //  Temp integer used for the current character
      t,u;                //  Temp integers used for the peeked/popped top of the stack
  for(;i++<s.length();){  //  Loop `i` in the range [0, String-length):
    if((c=s.charAt(i-1))  //   Set `c` to the current character
        <42               //   If the character is either '(' or ')',
        &&S.peek()!=0)    //   and the top of the stack is not 0:
         f(s.substring(   //    Take the substring, either removing everything before and
            40/c*i),      //    including the "(", or keeping the string as is for ")"
           S);            //    And do a recursive call with this String
    if(c==46)             //    If the character is '.'
      System.out.println( //     Print with trailing newline:
       S.peek());         //      The peeked top of the stack
    if(c>57)              //    If the character is ':' or '~':
      S.add(c>99?         //     If the character is '~':
        new Random().nextInt()
                          //      Add a random [0,2147483647) integer to the stack
       :                  //     Else (the character is ':')
        S.peek());        //      Add the peeked top to the stack
    if(c<44|c==45|c==47)  //    If the character is '*', '+', '-', or '/':
      t=S.pop();u=S.pop();//    Pop and set the top two values to `t` and `u`
      S.add(c<43?         //     If the character is '*':
        u*t               //      Add the product of the two values to the stack
       :c<44?             //     Else-if the character is '+':
        u+t               //      Add the sum of the two values to the stack
       :c<46?             //     Else-if the character is '-':
        u-t               //      Subtract the top two values, and add it to the stack
       :                  //     Else (the character is '/'):
        u/t;}}}           //      Divide the top two values, and add it to the stack

1
new Random().nextInt()は2より短い(int)(Math.random()*1e5)
Grimmy

@Grimyああ、私がそのjava.util.*インポートを忘れていましたStack。ありがとう!:)
Kevin Cruijssen

@ceilingcat -16ありがとうございます!
Kevin Cruijssen

これはおそらく1つ以上の装飾のルールに反しますがnew Random().nextInt()5すべてのテストケースに置き換えると、依然として合格します。
シーリングキャット

@ceilingcatええ、でも5正確にはランダムではありません;)関連するxkcd
Kevin Cruijssen

2

Linux x86_64のC(gcc)675 643 621 613 597 432 404 399バイト

printf();*z;*mmap();(*p)();*j(char*a){char*t=a,*n,c;for(p=0;read(0,&c,!p);t=!~c?n=j(t+9),z=mempcpy(t,L"\xf00f883Ƅ",5),*z=n-t-9,n:!c?p=*t++=233,z=t,*z=a-13-t,z+1:stpcpy(t,c-85?c-2?c-4?c-1?c-6?c-17?"PAPTYh%ld T_P^1\xc0QH\x83\xcc\bQA\xff\xd0\\AXX":"P":L"\xfef7995e":"[\xf7\xeb":"[)\xd8":"[\1\xd8":L"\xf0c70f50"))c-=41;return t;}main(){p=mmap(0,1<<20,6,34,0,0);p(strcpy(j(p),"j<X\xf\5"),0,0,0,printf);}

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

これは、Volatile命令をx86_64マシン言語に直接変換してコードを実行するJITです。あなたのマシンが持っていない場合はrdrand、命令を、あなたは置き換えることができL"\xf0c70f50""Pj*X"「のための少ない均一なPRNG」。Linux以外に移植するには、printf()およびexit()blobのsyscallsを置き換え、パラメーターをに調整しますmmap()

編集:このバージョンではprintf()、サブセットを最初から実装する代わりに呼び出します。

EDIT2:サポートされる整数は64ビットではなく32ビットになりました。

やや少ないゴルフ...

printf();*z;*mmap();(*p)();
// recursive function translates Volatile commands to x86_64 instructions
*j(char*a){
  char*t=a,*n,c;
  for(p=0;read(0,&c,!p);)
    c-=41,
    t=c=='('+41?
      // cmp eax,0
      // je n-t-9
      n=j(t+9),
      z=mempcpy(t,"\x83\xf8\x00\x0f\x84",5),
      *z=n-t-9,
      n
    :
      c==')'+41?
        // jmp a-13-t
        p=*t++=233,
        z=t,
        *z=a-13-t,
        z+1
      :
        stpcpy(t,c-'~'+41?
                   c-'+'+41?
                     c-'-'+41?
                       c-'*'+41?
                         c-'/'+41?
                           c-':'+41?
                             // ; This calls printf("%ld ",%rax)
                             // push rax
                             // push r8
                             // push rsp
                             // pop  rcx
                             // push 0x20646c25
                             // push rsp
                             // pop  rdi
                             // push rax
                             // pop  rsi
                             // xor  eax, eax
                             // push rcx
                             // or   rsp, 8
                             // push rcx
                             // call r8
                             // pop  rsp
                             // pop  r8
                             // pop  rax
                             "\x50\x41\x50\x54\x59\x68\x25\x6c\x64\x20\x54\x5f\x50\x5e\x31\xc0\x51\x48\x83\xcc\x08\x51\x41\xff\xd0\x5c\x41\x58\x58"
                           :
                             // push rax
                             "\x50"
                         :
                           // pop rsi
                           // cdq  
                           // idiv esi
                           "\x5e\x99\xf7\xfe"
                       :
                         // pop rbx
                         // imul ebx
                         "\x5b\xf7\xeb"
                     :
                       // pop rbx
                       // sub eax, ebx
                       "\x5b\x29\xd8"
                   :
                     // pop rbx
                     // add eax, ebx
                     "\x5b\x01\xd8"
                 :
                   // push rax
                   // rdrand eax
                   "\x50\x0f\xc7\xf0");
  return t;
}
main(){
  p=mmap(0,1<<20,6,34,0,0);
  p(strcpy(j(p),"\x6a\x3c\x58\x0f\x05"),0,0,0,printf);
}

1

Kotlin、412バイト

残念ながら私はJavaに負けましたが、望んでいませんでしたimport java.util.Stack(とにかくそれがギャップを埋めるかどうかはわかりません)。

{p->var i=0
var s=List(0){0}
var c=List(0){0}
while(i<p.length){when(val o=p[i]){'~'->s+=(0..32768).random()
in "+-*/"->{val(a,b)=s.takeLast(2)
s=s.dropLast(2)+when(o){'+'->a+b
'-'->a-b
'*'->a*b
'/'->a/b
else->0}}
':'->s+=s.last()
'.'->println(s.last())
'('->{if(s.last()!=0)c+=i else{var z=0
do{if(p[i]=='(')z++else if(p[i]==')')z--
i++}while(z>0)
i--}}
')'->if(s.last()!=0)i=c.last()else c=c.dropLast(1)}
i++}}

未ゴルフ

{ p ->                  // open lambda: p is the code string
    var i = 0           // program counter
    var s = List(0){0}  // data stack
    var c = List(0){0}  // jump stack

    // main loop
    while(i<p.length) {
        // match on the current character
        when(val o = p[i]) {
            // add random number to end of stack
            '~' -> s += (0..32768).random()
            // if a math op...
            in "+-*/" -> {
                // pick top stack items
                val (a, b) = s.takeLast(2)
                // pop two items and then push based on op
                s = s.dropLast(2) + when(o) {
                    '+' -> a+b
                    '-' -> a-b
                    '*' -> a*b
                    '/' -> a/b
                    else -> 0  // else is required here
                }
            }
            // duplicate top stack item
            ':' -> s += s.last()
            // print top stack item
            '.' -> println(s.last())
            // open loop
            '(' -> {
                if(s.last()!=0)
                    // push to jump stack if top of data stack is nonzero
                    c+=i
                else {
                    // skip ahead
                    var z=0
                    do {
                        // seek to matching brace
                        if(p[i]=='(') z++ else if(p[i]==')') z--
                        i++
                    } while(z>0)
                    // ensure program counter doesn't go too far
                    i--
                }
            }
            // close loop
            ')' -> if(s.last()!=0) i=c.last() else c=c.dropLast(1)
        }
        // next character
        i++
    }
}

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

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