Malbolgeの「クレイジー」オペレーターを実装する


41

Malbolgeプログラミング言語の多くのユニークな機能の1つは、非常に直感的ではないOP演算子です。ドキュメントとソースコードでは「op」と呼ばれますが、一般的に「crazy」演算子として知られています。言語の作成者であるベン・オルムステッドがその文書で説明しているように、パターンを探してはいけない、そこにはない」。

opは「tritwise」演算子です。2つの引数の対応する3進数で動作します。各トリット(3進ビット)について、opの結果は次のルックアップテーブルによって与えられます。

           a
op(a,b)  0 1 2
       +-------
     0 | 1 0 0
   b 1 | 1 0 2
     2 | 2 2 1

たとえば、を計算するにはop(12345, 54321)、最初に両方の数値を3進数で書き出してから、テーブル内の各トリットのペアを検索します。

   0121221020   (12345_3)
op 2202111220   (54321_3)
--------------
   2202220211   (54616_3)

最後に重要な点は、入力値が10の幅にゼロで埋めなければならないのでMalbolgeのすべての値が10個のトリットが広いということである(例えば、op(0, 0)ある1111111111三元に)。

あなたの仕事は、2つの整数0≤ ab<59049を入力として受け取り、の整数値を出力することですop(a,b)

テストケース(形式a b op(a,b)):

0 0 29524
1 2 29525
59048 5 7
36905 2214 0
11355 1131 20650
12345 54321 54616

これがリファレンス実装です(Malbolgeのソースコードから直接コピーされます)。


28
これはマルボージで答えられますか?;)
表示名

3
マルボルジは今では良いゴルフ言語だと思います!
イーサン

7
価値があるのは、54616_3「この他のものは10進数の54616ですが、基数3として表される」という意味ではありません。「54616ベース3として読む」という意味です。もちろん、これはできません(Valveがそこに数えられない数字があります)。あなたが_3完全に取り除き、より正確になれば、おそらく同じくらい明確でしょう。
ニックハートリー

@Orangesandlemons Malbolgeで演算子を使用するだけで、標準の抜け穴に陥ると思います。別のコードを使用して再実装しても問題ありません。
パエロエベルマン

7
@PaŭloEbermannいいえ、それは抜け穴ではありません。
user202729

回答:



28

JavaScript(ES7)、56バイト

f=(a,b,k=9)=>~k&&(a%3|b%3<<9|8)**2%82%3+3*f(a/3,b/3,k-1)

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

どうやって?

とが与えられ場合、以下を計算します。b [ 0..2 ]ab[0..2]

f(a,b)=((a+512b+8)2mod82)mod3

につながる:

 a | b | 512b | a + 512b |  + 8 | squared | MOD 82 | MOD 3
---+---+------+----------+------+---------+--------+-------
 0 | 0 |    0 |      0   |    8 |      64 |   64   |   1                  a
 1 | 0 |    0 |      1   |    9 |      81 |   81   |   0                0 1 2
 2 | 0 |    0 |      2   |   10 |     100 |   18   |   0              +-------
 0 | 1 |  512 |    512   |  520 |  270400 |   46   |   1            0 | 1 0 0
 1 | 1 |  512 |    513   |  521 |  271441 |   21   |   0    -->   b 1 | 1 0 2
 2 | 1 |  512 |    514   |  522 |  272484 |   80   |   2            2 | 2 2 1
 0 | 2 | 1024 |   1024   | 1032 | 1065024 |    8   |   2
 1 | 2 | 1024 |   1025   | 1033 | 1067089 |   23   |   2
 2 | 2 | 1024 |   1026   | 1034 | 1069156 |   40   |   1

機能選択

フォームには、他にもいくつかの候補関数があります。

fk,c,p,m(a,b)=((a+kb+c)pmodm)mod3

最も短いものの1つ:

f(a,b)=((a+5b+2)4mod25)mod3

しかし、良いところ、それはこのように暗黙的の小数部分破棄、ビット演算子で実行することができるということであると。これが、各反復間で丸めることなく、単純にそれらを除算できる理由です。a b 3(a+512b+8)ab3

コメント済み

f = (a, b,            // given the input integers a and b
           k = 9) =>  // and starting with k = 9
  ~k &&               // if k is not equal to -1:
    ( a % 3           //   compute (a mod 3)
      | b % 3 << 9    //   add 512 * (b mod 3)
      | 8             //   add 8
    ) ** 2            //   square the result
    % 82              //   apply modulo 82
    % 3               //   apply modulo 3, leading to crazy(a % 3, b % 3)
    + 3 * f(          //   add 3 times the result of a recursive call with:
      a / 3,          //     a / 3  \__ no rounding required
      b / 3,          //     b / 3  /   (see 'Function choice')
      k - 1           //     k - 1
    )                 //   end of recursive call

(1581093>>b%3*2+a%3*8&3)全体のバイトを節約できると思います!
ニール

@Neil残念ながら、私は合格しa/3b/3丸めることはありません。そのため失敗します。
アーナウルド

9
存在しないパターンをどのように見つけたか興味深い。
エリックアウトゴルファー

好むどんな理由があるk = 9 ... => ~k && ...にはk = 10 ... => k && ...
ファルコ

1
@Falcoいいえ、短くも効率的でもありません。私は0から始まるものを好む傾向があるので、私はむしろ模倣するfor(k=9;k>=0;k--)よりもfor(k=10;k>=1;k--)
アーナルド

13

05AB1E、18バイト

コード:

3Tm+3Bø5+3m5(^3%3β

05AB1Eエンコードを使用します。オンラインでお試しください!


アルゴリズムの説明

数字をゼロで埋めるには、両方の数字に59049を追加する必要があります(3進数の59049は10000000000であるため)。先頭の1を必要はありません。数値を10進数から3進数に変換し、各ペアをそれぞれの数値として結合します。(1,1)0

たとえば、入力12345および54321の場合、これらは次のものにマッピングされます。

12345101212210205432112202111220

これにより、結合された整数の次のリストが得られます。

11,2,12,20,12,21,21,11,2,22,0

これらの整数は、OP内の指定されたルックアップテーブルによってマップされる必要があります。これらの数値を対応するトリット( 1、10)にマッピングする現在使用している式は次のとおりです。01,100,

f(x)=((x+5)35) mod 3

一方、はビット単位のxor関数を示します。

最終的に、この関数を結合整数のリストにマッピングした後、この結果のリストを基数3で表される数値として扱い、基数3から10進数に変換します。


コードの説明

3Tm+                  # Add 59049 to pad the ternary number with zeroes.
    3B                # Convert to base 3.
      ø               # Zip the list to get each joined integer.
       5+             # Add 5 to each element.
         3m           # Raise each element to the power of 3.
           5(^        # XOR each element with -5.
              3%      # Modulo each element with 3.
                3β    # Convert from base 3 to decimal.

3Tm+3Bø19sm74%3%3βゴルフできますか?
ジョナサンアラン

@JonathanAllan素敵な発見!しかし、他の種類の黒魔術式を使用せずにそれ以上ゴルフをすることは不可能に思えます。
アドナン

11

R64 62バイト

function(a,b,x=3^(9:0))30801%/%x[a%/%x%%3*3+b%/%x%%3+1]%%3%*%x

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

黒魔法のゴルフトリックと-2バイトのJADに感謝します!

30801、10トリットの3進整数に変換すると1120020210、列を下に読み取ったときに末尾のゼロが操作テーブルに追加されるだけです。次に、aおよびb要素単位の3進数を整数に変換し、それをの3進数のインデックスとして使用し30801ます。


1
演算子の優先順位は62バイトです。
JAD

1
ええ、この方法では、最初にxを使用してインデックスを作成し[.*]ます。その後、すべての%any%操作が発生します。楽しい部分は、あなたが見るならばということである30801%/%x%%3としてf=function(x)30801%/%x%%3その、f(x[index]) == (f(x))[index]。中括弧の保存:)
JAD

@JAD魅惑的!上でコメントしたように、基本的には黒魔術です。
ジュゼッペ

1
これには多くの手間がかかったことを喜んで認めます:P
JAD

10

C(gcc)74 72 71バイト

f(a,b,i,r){for(r=0,i=59049;i/=3;)r+=(108609>>a/i%3*2+b/i%3*6&3)*i;i=r;}

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

壊す

真理値表

           a
op(a,b)  0 1 2
       +-------
     0 | 1 0 0
   b 1 | 1 0 2
     2 | 2 2 1

3x3の配列と考えることができます。aは列、bは行です。これを1次元のリストに変換すると、100102221が得られます。スペースを節約するために、リストと文字列を避けて、代わりに数値にします。そのために、順序を反転し、すべてのトリットを2ビット数に変換します。それらを一緒に接着すると、右にシフトして2 * (b * 3 + a)マスキングすることで「インデックス付け」できるバイナリ番号が得られます。

 1 0 0 1 0 2 2 2 1
 1 2 2 2 0 1 0 0 1
011010100001000001

次に、操作の優先順位の力を使用して式をマッサージし、上記の憎悪になります。

3 ^ 9 = 19683なので、これは適切なループ制限です。カウンターに毎回3を掛けるため、2e4代わりに制限を記述できます。また、わずらわしいものpow()や似たようなものを保存します。

考え直して、3 ^ 10から始めて、ループ前の分割とテストを下に向かっていきましょう。




6

ゼリー 23  18 バイト

-1エリックOutgolferのおかげで(再配置3*⁵¤します⁵3*

⁵3*+b3Zḅ3ị⁽½Ṡb3¤ḅ3

2つの整数のリストを受け入れる単項リンク。

オンラインでお試しください!または、テストスイートを参照してください。

⁹*%733%3ị⁽½Ṡb3¤:( より長いバイトです

どうやって?

⁵3*+b3Zḅ3ị⁽½Ṡb3¤ḅ3 - Link: [a, b]      e.g. [11355,1131]
⁵                  - literal ten            10
 3                 - literal three          3
  *                - exponentiation         59049
   +               - addition (vectorises)  [70404,60180]
     3             - literal three          3
    b              - to base (vectorises)   [[1,0,1,2,0,1,2,0,1,2,0],[1,0,0,0,1,1,1,2,2,2,0]]
      Z            - transpose              [[1,1],[0,0],[1,0],[2,0],[0,1],[1,1],[2,1],[0,2],[1,2],[2,2],[0,0]]
        3          - literal three          3
       ḅ           - from base (vectorises) [4,0,3,6,1,4,7,2,5,8,0]
               ¤   - nilad followed by link(s) as a nilad:
          ⁽½Ṡ      -   literal 3706         3706
              3    -   literal three        3
             b     -   to base              [1,2,0,0,2,0,2,1]
         ị         - index into             [0,1,0,0,1,0,2,2,2,1,1]
                 3 - literal three          3
                ḅ  - from base              20650

また18:⁵3*+b3ZḌ19*%74%3ḅ3(10を基数から19の累乗に変換するペアワイズトリットを取得し、74を法として3を法として出力の必要なトリットを取得する-Pythonでの検索を使用して見つけた後、魔法の式を使用します)


18バイト(注:実際には "prepend y 0s"ビルトインが必要)
エリックアウトゴルファー

うーん、私はそれが厄介に見えると思った。ありがとう!
ジョナサンアラン

多くのことは厄介に見えますが、時々慣れなければなりません。:P
エリック・ザ・アウトゴルファー


4

J、37バイト

((3 3$d 30801){~{@,.)&.(d=.(10$3)&#:)

説明:

((3 3$d 30801){~{@,.)&.(d=.(10$3)&#:)   
                       (d=.(10$3)&#:)   convert to 10 trits, and name this function as d
                     &.                 ... which is done on both args and inverted on the result
                {@,.                    make boxed indices: 1 2 3 4 {@,. 5 6 7 8  ->  1 5 ; 2 6 ; 3 7 ; 4 8
              {~                        index out of a lookup table
 (3 3$d 30801)                          reusing the trits conversion function to make the table

比較的読みやすいものになりました、TBH。


PPCGへようこそ!ここにテストスイートがあります-Galen Ivanovの答えからラッピングコードを盗みました。
ジョナサンアラン

PPCGへようこそ!いい解決策!ここに TIOリンクがあります。
ガレンイワノフ



@FrownyFrogいいね!
ヨナ


3

、31バイト

I↨³⮌⭆χ§200211⁺∨﹪÷θX³ι³¦⁴﹪÷ηX³ι³

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:

     χ                          Predefined variable 10
    ⭆                           Map over implicit range and join
                    ι        ι  Current index
                  X³       X³   Power of 3
                 θ              Input `a`
                          η     Input `b`
                ÷        ÷      Integer divide
               ﹪     ³  ﹪     ³ Modulo by 3
              ∨       ¦⁴        Replace zero ternary digit of `a` with 4
             ⁺                  Add
      §200211                   Index into literal string `200211`
   ⮌                            Reverse
 ↨³                             Convert from base 3
I                               Cast to string
                                Implicitly print

代替ソリューション、31バイト:

I↨³E↨⁺X³χθ³§200211⁺∨ι⁴§↨⁺X³χη³κ

オンラインでお試しください!リンクは、コードの詳細バージョンです。

        χ                  χ    Predefined variable 10
      X³                 X³     Power of 3 i.e. 59049
         θ                      Input `a`
                            η   Input `b`
     ⁺                  ⁺       Sum
    ↨     ³            ↨     ³  Convert to base 3
   E                            Map over elements
                    ι           Current ternary digit of `a`
                   ∨ ⁴          Replace zero with 4
                      §       κ Index into ternary digits of `b`
                  ⁺             Add
           §200211              Index into literal string `200211`
 ↨³                             Convert from base 3
I                               Cast to string
                                Implicitly print



2

J、43バイト

3#.((3 3$t 6883){~<@,~"0)&(_10{.t=.3&#.inv)

それは確かにさらにゴルフすることができます。

説明:

                         &(               ) - for both arguments
                                t=.3&#.inv  - convert to base 3 (and name the verb t)
                           _10{.            - pad left with zeroes
   (              <@,~"0)                   - box the zipped pairs (for indexing)
    (3 3$t 6883)                            - the lookup table
                {~                          - use the pairs as indeces in the table
3#.                                         - back to decimal  

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



2

Pyth 26 25 24バイト

@ErikTheOutgolferのおかげで1バイト節約

@JonathanAllanの回答に触発された別のバイトを保存する

im@j3422 3id3Cm.[0Tjd3Q3

入力は2要素のリスト[a,b]です。ここでオンライン試すか、ここですべてのテストケースを確認してください

im@j3422 3id3Cm.[0Tjd3Q3   Implicit: Q=eval(input())
              m       Q    Map each element d of the input using:
                   jd3       Convert to base 3
               .[0T          Pad to length 10 with 0's
             C             Transpose
 m                         Map each element d of the above using:
   j3422 3                   The lookup table [1,1,2,0,0,2,0,2]
  @                          Modular index into the above using
          id3                Convert d to base 10 from base 3
i                      3   Convert to base 10 from base 3, implicit print

.TすることができますC
エリックアウトゴルファー


1

Japt24 23バイト

今月の言語としてJaptの実行でボールを転がします。

整数配列(つまり、[b,a])として逆順で入力を受け取ります。

ms3 ùTA y_n3 g6883ì3Ãì3

それを試してみてください

ms3 ùTA y_n3 g6883ì3Ãì3      :Implicit input of array U=[b,a]
m                            :Map
 s3                          :  Convert to base-3 string
    ù                        :Left pad each
     T                       :  With zero
      A                      :  To length 10
        y                    :Transpose
         _                   :Map
          n3                 :  Convert from base-3 string to decimal
             g               :  Index into
              6883ì3         :    6883 converted to a base-3 digit array
                    Ã        :End map
                     ì3      :Convert from base-3 digit array to decimal


0

Wolfram言語(Mathematica)75 72 60バイト

(d=IntegerDigits)[6883,3][[{1,3}.d[#,3,10]+1]]~FromDigits~3&

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

ゴルフされていないバージョン:

M[{a_, b_}] := 
  FromDigits[{1, 0, 0, 1, 0, 2, 2, 2, 1}[[
    IntegerDigits[a, 3, 10] + 3*IntegerDigits[b, 3, 10] + 1
  ]], 3];

両方ab番号のルックアップテーブルに2次元のインデックスとして使用ペアワイズ次いで、10-トリットリストに変換されます{1, 0, 0, 1, 0, 2, 2, 2, 1}。結果は再び10トリットリストとして解釈され、整数形式に変換されます。

ルックアップテーブルはとしてコーディングされていますIntegerDigits[6883,3]。これは、IntegerDigitsシンボルをリサイクルしているため短いです。

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