Melaksanakan operator "gila" Malbolge

41

Salah satu fitur unik dari bahasa pemrograman Malbolge adalah OPoperatornya yang sangat tidak intuitif , hanya disebut sebagai "op" dalam dokumentasi dan kode sumber tetapi dikenal sebagai operator "gila". Seperti dijelaskan oleh Ben Olmstead, pencipta bahasa, dalam dokumentasinya: " jangan mencari pola, itu tidak ada di sana ."

op adalah operator "tritwise" - ini beroperasi pada digit ternary yang sesuai dari dua argumennya. Untuk setiap trit (bit ternary), hasil op diberikan oleh tabel pencarian berikut:

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

Misalnya, untuk menghitung op(12345, 54321), pertama-tama tuliskan kedua angka dalam ternary dan kemudian cari setiap pasangan trit dalam tabel:

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

Poin penting terakhir adalah bahwa semua nilai di Malbolge memiliki lebar 10 trit, sehingga nilai input harus diisi dengan nol hingga lebar 10. (Misalnya, op(0, 0)berada 1111111111di ternary.)

Tugas Anda adalah mengambil dua bilangan bulat 0 ≤ a, b<59049 sebagai input, dan menghasilkan nilai integer sebesar op(a,b).

Kasus uji (dalam format a b op(a,b)):

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

Berikut ini adalah implementasi referensi (disalin langsung dari kode sumber Malbolge).

Gagang pintu
sumber
28
dapatkah ini dijawab dalam Malboge? ;)
Nama tampilan
3
Saya kira Malbolge adalah bahasa golf yang bagus sekarang!
Ethan
7
Untuk apa nilainya, 54616_3tidak berarti "hal lain ini adalah angka desimal 54616, tetapi diwakili sebagai basis tiga". Ini berarti "Baca 54616sebagai basis 3". Yang tentu saja tidak bisa Anda lakukan (ada angka yang tidak bisa dihitung oleh Valve di sana). Mungkin masih akan sama jelasnya jika Anda menyingkirkan _3seluruhnya, dan lebih akurat.
Nic Hartley
@Orangesandlemons Saya kira hanya menggunakan operator di Malbolge akan jatuh di bawah celah standar. Mengimplementasikannya menggunakan kode yang berbeda akan baik-baik saja.
Paŭlo Ebermann
7
@ PaŭloEbermann Tidak, itu bukan celah .
user202729

Jawaban:

43

C (gcc) , 99 98 96 byte

  • Menyimpan satu byte berkat plafon ; bermain golf 19683untuk L'䳣'.
  • Disimpan dua byte; bermain golf 108609untuk L'𚡁'.
M,a,l,b,o;L(g,e){for(o=b=L'䳣',l=0;o/=2.4;b/=3)M=g/b,g%=b,a=e/b,e%=b,l+=b*(L'𚡁'>>M+6*a+M&3);g=l;}

Cobalah online!

Jonathan Frech
sumber
14
Saya suka skema penamaan!
Matthieu M.
28

JavaScript (ES7), 56 byte

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

Cobalah online!

Bagaimana?

Diberikan dan dalam , kami menghitung:b [ 0..2 ]ab[0..2]

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

Menuju ke:

 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

Pilihan fungsi

Ada beberapa kemungkinan fungsi kandidat lainnya dari formulir:

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

Salah satu yang terpendek adalah:

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

Tetapi hal baiknya tentang adalah dapat dilakukan dengan operator bitwise, sehingga secara implisit membuang bagian desimal dari dan . Inilah mengapa kita bisa membaginya dengan tanpa pembulatan di antara setiap iterasi.(a+512b+8)ab3

Berkomentar

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
Arnauld
sumber
Saya pikir (1581093>>b%3*2+a%3*8&3)menghemat seluruh byte!
Neil
@ Neil Sayangnya, saya lewat a/3dan b/3tanpa pembulatan. Itu akan gagal karena itu.
Arnauld
9
Menarik bagaimana Anda menemukan pola yang tidak ada.
Erik the Outgolfer
Apakah ada alasan untuk lebih memilih k = 9 ... => ~k && ...ke k = 10 ... => k && ...?
Falco
1
@ Falco Tidak, itu tidak lebih pendek atau lebih efisien dengan cara apa pun. Saya cenderung lebih suka hal-hal yang diindeks 0, jadi saya lebih suka meniru for(k=9;k>=0;k--)daripada for(k=10;k>=1;k--).
Arnauld
13

05AB1E , 18 byte

Kode:

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

Menggunakan penyandian 05AB1E . Cobalah online!


Penjelasan Algoritma

Untuk mendapatkan nomor yang diisi dengan angka nol, kita perlu menambahkan 59049 ke kedua angka (karena 59049 di ternary adalah 10000000000 ). Kita tidak harus meninggalkan yang pertama sebagai . Kami mengonversi angka dari desimal ke terner dan bergabung dengan setiap pasangan sebagai masing-masing nomor sendiri.(1,1)0

Misalnya, untuk input 12345 dan 54321 , ini dipetakan ke:

12345101212210205432112202111220

Yang memberikan daftar bilangan bulat gabungan berikut:

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

Bilangan bulat ini perlu dipetakan oleh tabel pencarian yang diberikan di OP. Rumus yang saat ini kami gunakan yang memetakan angka-angka ini ke catatan yang sesuai ( ) adalah:01,100,

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

Sedangkan menunjukkan fungsi xor bitwise .

Akhirnya setelah memetakan fungsi ini pada daftar bilangan bulat yang bergabung, kami memperlakukan daftar yang dihasilkan ini sebagai angka yang diwakili dalam basis 3 dan mengubahnya dari basis 3 ke desimal.


Penjelasan Kode

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.
Adnan
sumber
Bisakah 3Tm+3Bø19sm74%3%3βbermain golf?
Jonathan Allan
@ Jonathan Allan Nice find! Namun sepertinya tidak mungkin untuk bermain golf lebih jauh tanpa menggunakan beberapa jenis formula ilmu hitam lainnya.
Adnan
11

R , 64 62 byte

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

Cobalah online!

Terima kasih kepada JAD untuk beberapa trik golf sihir hitam dan -2 byte!

30801, ketika dikonversi ke bilangan bulat ternary 10-trit, adalah 1120020210yang hanya menambahkan nol tambahan ke tabel operasi, saat membaca kolom. Kemudian kita mengonversi digit terner adan belementwise menjadi integer dan menggunakannya sebagai indeks ke digit terner 30801.

Giuseppe
sumber
1
62 byte Yay untuk diutamakan operator!
JAD
1
Ya, dengan cara ini, Anda xmenggunakan indeks pertama kali [.*]. Lalu semua %any%operasi terjadi. Bagian yang menyenangkan adalah bahwa jika Anda melihat 30801%/%x%%3sebagai f=function(x)30801%/%x%%3, itu f(x[index]) == (f(x))[index]. Menyimpan kawat gigi :)
JAD
@ JAD menarik! Dan seperti yang saya komentari di atas, pada dasarnya ilmu hitam.
Giuseppe
1
Dengan senang hati saya akui bahwa ini membutuhkan banyak waktu: P
JAD
10

C (gcc) , 74 72 71 byte

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

Cobalah online!

Kerusakan

Tabel kebenaran

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

Dapat dianggap sebagai array 3x3, di mana a adalah kolom, dan b adalah baris. Mengubah itu menjadi daftar satu dimensi memberi kita 100102221. Untuk menghemat ruang, kita menghindari daftar dan string dan menjadikannya sebagai angka. Untuk melakukan itu, kami membalik urutan dan mengubah setiap trit menjadi angka 2-bit. Rekatkan keduanya dan kita memiliki angka biner yang dapat kita "indeks" dengan menggesernya ke kanan dengan 2 * (b * 3 + a)dan menutupi:

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

Selanjutnya, kita memijat ekspresi menggunakan kekuatan operasi yang diutamakan untuk menjadi kekejian di atas.

3 ^ 9 = 19683 sehingga itu adalah batas loop yang baik. Karena kita mengalikan penghitung dengan 3 setiap kali, kita dapat menulis batas sebagai 2e4gantinya. Kami juga menyelamatkan diri dari gangguan pow()atau serupa.

Setelah dipikir-pikir, mari kita mulai dari 3 ^ 10 dan bekerja ke bawah dengan pre-loop divide-and-test.

gastropner
sumber
8

Haskell , 108 byte

2%2=1
_%2=2
0%_=1
2%1=2
_%_=0
g=take 10.map(`mod`3).iterate(`div`3)
(foldr((.(3*)).(+))0.).(.g).zipWith(%).g

Cobalah online!

Wisaya Gandum
sumber
6

Jelly ,  23  18 byte

-1 berkat Erik the Outgolfer (mengatur ulang 3*⁵¤untuk ⁵3*)

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

Tautan monadik yang menerima daftar dua bilangan bulat.

Cobalah online! Atau lihat test-suite .

⁹*%733%3byte lebih panjang dari ị⁽½Ṡb3¤:(

Bagaimana?

⁵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

Juga 18: ⁵3*+b3ZḌ19*%74%3ḅ3(menggunakan formula ajaib setelah mendapatkan pasangan-bijaksana dari mengkonversi dari basis sepuluh kemudian mengambil 19 untuk kekuatan itu, modulo 74, modulo 3 untuk mendapatkan catatan yang diperlukan dari output - ditemukan menggunakan pencarian dengan Python)

Jonathan Allan
sumber
18 byte (catatan: harus ada y 0built-in "prepend s")
Erik the Outgolfer
Ugh, kupikir itu terlihat canggung. Terima kasih!
Jonathan Allan
Banyak hal yang terlihat aneh, terkadang Anda harus terbiasa dengannya. : P
Erik the Outgolfer
4

J , 37 byte

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

Penjelasan:

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

Akhirnya menjadi relatif mudah dibaca, tbh.

dram
sumber
Selamat datang di PPCG! Ini adalah test-suite - saya mencuri kode pembungkus dari jawaban Galen Ivanov.
Jonathan Allan
Welcom ke PPCG! Solusi bagus! Berikut ini adalah tautan TIO.
Galen Ivanov
30
FrownyFrog
2
28
FrownyFrog
@FrownyFrog bagus!
Jonah
3

Python 2 , 90 87 byte

f=lambda a,b,A='':f(a/3,b/3,'100102221'[a%3+b%3*3]+A)if a+b else int(A.rjust(10,'1'),3)

Cobalah online!

Chas Brown
sumber
3

Arang , 31 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

     χ                          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

Solusi alternatif, juga 31 byte:

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode.

        χ                  χ    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
Neil
sumber
2

Ruby , 70 byte

->a,b,l=10{l>0?6883.digits(3)[8-b%3*3-a%3]*3**(10-l)+f[a/3,b/3,l-1]:0}

Cobalah online!

Mengurai adan bsecara rekursif sampai kita mendapatkan masing-masing 10 digit. 6883memberikan tabel terner rata (terbalik). Merekonstruksi dari ternary ke desimal dengan mengalikan dengan 3**(10-l).

crashoz
sumber
2

Cjam, 31 byte

{{3bA0e[\}2*.{3*+"100102221"=}}

Cobalah online!

Chromium
sumber
2

J , 43 byte

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

Tentu saja bisa bermain golf lebih lanjut.

Penjelasan:

                         &(               ) - 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  

Cobalah online!

Galen Ivanov
sumber
2

Pyth 26 25 24 byte

Disimpan 1 byte, terima kasih kepada @ErikTheOutgolfer

Simpan byte lain, terinspirasi oleh jawaban @ JonathanAllan

im@j3422 3id3Cm.[0Tjd3Q3

Input adalah daftar elemen 2 [a,b]. Cobalah online di sini , atau verifikasi semua test case di sini .

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
Sok
sumber
.Tbisa C.
Erik the Outgolfer
1

Japt , 24 23 byte

Mendapatkan bola bergulir pada lari Japt sebagai bahasa bulan ini - Saya sepenuhnya berharap akan kalah dalam hal ini!

Mengambil input dalam urutan terbalik sebagai array integer (yaitu, [b,a]).

ms3 ùTA y_n3 g6883ì3Ãì3

Cobalah

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
Shaggy
sumber
0

Perl 5 -p , 102 byte

sub t{map{("@_"%3,$_[0]/=3)[0]}0..9}@a=t$_;@b=t<>}{$\=(1,1,2,0,0,2,0,2,1)[(3*pop@a)+pop@b]+$\*3while@a

Cobalah online!

Xcali
sumber
0

Bahasa Wolfram (Mathematica) , 75 72 60 byte

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

Cobalah online!

versi tidak golf:

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

Keduanya adan bdikonversi ke daftar sepuluh-trit, kemudian digunakan berpasangan sebagai indeks 2D ke dalam tabel pencarian angka {1, 0, 0, 1, 0, 2, 2, 2, 1}. Hasilnya ditafsirkan kembali sebagai daftar sepuluh-trit dan dikonversi kembali ke bentuk integer.

Tabel pencarian dikodekan sebagai IntegerDigits[6883,3], yang singkat karena kita mendaur ulang IntegerDigitssimbol.

Roma
sumber