Thực hiện toán tử điên khùng của Malbolge


41

Một trong nhiều tính năng độc đáo của ngôn ngữ lập trình MalbolgeOPtoán tử không trực quan cao của nó , chỉ được gọi là "op" trong tài liệu và mã nguồn nhưng thường được gọi là toán tử "crazy". Theo mô tả của Ben Olmstead, người tạo ra ngôn ngữ, trong tài liệu của mình: " đừng tìm mẫu, nó không có ở đó ."

op là một toán tử "tritwise" - nó hoạt động trên các chữ số thứ ba tương ứng của hai đối số của nó. Đối với mỗi trit (bit ternary), kết quả của op được đưa ra bởi bảng tra cứu sau:

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

Ví dụ, để tính toán op(12345, 54321), đầu tiên hãy viết ra cả hai số trong ternary và sau đó tra cứu từng cặp trits trong bảng:

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

Điểm quan trọng cuối cùng là tất cả các giá trị trong Malbolge đều rộng 10 trits, do đó, các giá trị đầu vào phải được đệm bằng các số 0 đến chiều rộng 10. (Ví dụ: op(0, 0)nằm 1111111111ở vị trí thứ ba.)

Nhiệm vụ của bạn là lấy hai số nguyên 0 a, b<59049 làm đầu vào và xuất giá trị nguyên của op(a,b).

Các trường hợp thử nghiệm (ở định dạng a b op(a,b)):

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

Đây là một triển khai tham chiếu (được sao chép trực tiếp từ mã nguồn Malbolge).


28
điều này có thể được trả lời trong Malboge? ;)
Tên hiển thị

3
Tôi đoán Malbolge là một ngôn ngữ chơi golf tốt bây giờ!
Ethan

7
Đối với những gì nó có giá trị, 54616_3không có nghĩa là "điều khác này là số thập phân 54616, nhưng được biểu thị dưới dạng số ba". Nó có nghĩa là "Đọc 54616như cơ sở 3". Điều đó, tất nhiên, bạn không thể làm (có những chữ số mà Valve không thể đếm được ở đó). Có lẽ vẫn còn rõ ràng nếu bạn loại bỏ _3hoàn toàn, và chính xác hơn.
Nic Hartley

@Orangesandlemons Tôi đoán chỉ cần sử dụng toán tử trong Malbolge sẽ rơi vào kẽ hở tiêu chuẩn. Thực hiện lại bằng cách sử dụng mã khác nhau sẽ ổn.
Paŭlo Ebermann

7
@ PaŭloEbermann Không, đó không phải là một lỗ hổng .
dùng202729

Câu trả lời:



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)

Hãy thử trực tuyến!

Làm sao?

Cho và trong , chúng tôi tính toán:b [ 0..2 ]ab[0..2]

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

Dẫn tới:

 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

Lựa chọn chức năng

Có một số chức năng ứng cử viên khác có thể có của mẫu:

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

Một trong những cái ngắn nhất là:

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

Nhưng điều tốt về là nó có thể được thực hiện với các toán tử bit, do đó, loại bỏ hoàn toàn các phần thập phân của và . Đây là lý do tại sao chúng ta có thể đơn giản chia chúng cho mà không làm tròn giữa mỗi lần lặp.(a+512b+8)ab3

Đã bình luận

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

Tôi nghĩ (1581093>>b%3*2+a%3*8&3)tiết kiệm cả một byte!
Neil

@Neil Thật không may, tôi đi qua a/3b/3không làm tròn số. Điều đó sẽ thất bại vì điều đó.
Arnauld

9
Thật thú vị khi bạn tìm thấy một mô hình không tồn tại.
Erik the Outgolfer

Có lý do nào để thích k = 9 ... => ~k && ...đến k = 10 ... => k && ...?
Falco

1
@Falco Không, nó không ngắn hơn hay hiệu quả hơn bằng mọi cách. Tôi chỉ có xu hướng thích những thứ có chỉ số 0, vì vậy tôi thích bắt chước for(k=9;k>=0;k--)hơn for(k=10;k>=1;k--).
Arnauld

13

05AB1E , 18 byte

Mã số:

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

Sử dụng mã hóa 05AB1E . Hãy thử trực tuyến!


Giải thích thuật toán

Để có được số được đệm bằng số 0, chúng ta cần thêm 59049 vào cả hai số (bởi vì 59049 trong ternary là 10000000000 ). Chúng ta không phải rời khỏi vị trí dẫn đầu 1 là . Chúng tôi chuyển đổi các số từ thập phân sang ternary và tham gia mỗi cặp như mỗi số riêng.(1,1)0

Ví dụ: đối với đầu vào 1234554321 , các mục này được ánh xạ tới:

12345101212210205432112202111220

Cung cấp danh sách các số nguyên đã tham gia sau đây:

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

Các số nguyên này cần được ánh xạ bởi bảng tra cứu đã cho trong OP. Công thức chúng tôi hiện đang sử dụng để ánh xạ các số này tới các đặc điểm tương ứng của chúng ( ) là:01,100,

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

Trong khi đó biểu thị hàm xor bitwise .

Cuối cùng, sau khi ánh xạ hàm này vào danh sách các số nguyên đã tham gia, chúng tôi coi danh sách kết quả này là một số được biểu thị trong cơ sở 3 và chuyển đổi nó từ cơ sở 3 sang số thập phân.


Giải thích mã

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βthể chơi golf?
Jonathan Allan

@Jonathan ALLan Đẹp tìm thấy! Tuy nhiên, dường như không thể đánh gôn thêm nữa mà không sử dụng một số loại công thức ma thuật đen khác.
Ad Nam

11

R , 64 62 byte

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

Hãy thử trực tuyến!

Cảm ơn JAD về một số thủ thuật đánh gôn ma thuật đen và -2 byte!

30801, khi được chuyển đổi thành số nguyên ternary 10 trit, 1120020210chỉ cần thêm một số 0 vào bảng thao tác, khi đọc các cột. Sau đó, chúng tôi chuyển đổi các chữ số ternary của abtheo nguyên tố thành một số nguyên và sử dụng nó như là một chỉ số thành các chữ số ternary của 30801.


1
62 byte Yay cho quyền ưu tiên của nhà điều hành!
JAD

1
Vâng, theo cách này, bạn chỉ mục đầu tiên xsử dụng [.*]. Sau đó tất cả các %any%hoạt động xảy ra. Các phần thú vị là nếu bạn nhìn thấy 30801%/%x%%3f=function(x)30801%/%x%%3, rằng f(x[index]) == (f(x))[index]. Cứu niềng răng :)
JAD

@JAD hấp dẫn! Và như tôi nhận xét ở trên, về cơ bản là ma thuật đen.
Giuseppe

1
Tôi sẽ vui vẻ thú nhận rằng điều này đã gây ra rất nhiều khó khăn: 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;}

Hãy thử trực tuyến!

Phá vỡ

Bảng chân lý

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

Có thể được coi là một mảng 3x3, trong đó a là cột và b là hàng. Chuyển đổi nó thành một danh sách một chiều mang lại cho chúng ta 100102221. Để tiết kiệm không gian, chúng ta tránh các danh sách và chuỗi và thay vào đó thành một số. Để làm điều đó, chúng ta lật thứ tự và biến mọi trit thành số 2 bit. Dán chúng lại với nhau và chúng ta có một số nhị phân, chúng ta có thể "lập chỉ mục" bằng cách dịch sang phải bằng cách 2 * (b * 3 + a)và che dấu:

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

Tiếp theo, chúng tôi xoa bóp biểu thức bằng cách sử dụng sức mạnh của ưu tiên hoạt động để trở thành gớm ghiếc ở trên.

3 ^ 9 = 19683 vì vậy đó là giới hạn vòng lặp tốt. Vì chúng ta nhân số đếm với 3 lần mỗi lần, chúng ta có thể viết giới hạn 2e4thay thế. Ngoài ra chúng tôi tiết kiệm cho mình những phiền phức pow()hoặc tương tự.

Về ý nghĩ thứ hai, chúng ta hãy bắt đầu từ 3 ^ 10 và làm việc xuống dưới với phép thử và phân chia vòng lặp trước.




6

Thạch ,  23  18 byte

-1 nhờ Erik các Outgolfer (sắp xếp lại 3*⁵¤để ⁵3*)

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

Một liên kết đơn âm chấp nhận danh sách hai số nguyên.

Hãy thử trực tuyến! Hoặc xem một bộ thử nghiệm .

⁹*%733%3là một byte dài hơn ị⁽½Ṡb3¤:(

Làm sao?

⁵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

Ngoài ra 18: ⁵3*+b3ZḌ19*%74%3ḅ3(sử dụng công thức ma thuật sau khi nhận được các cặp chuyển đổi khôn ngoan từ cơ sở mười sau đó lấy 19 thành sức mạnh đó, modulo 74, modulo 3 để có được các yêu cầu đầu ra - được tìm thấy bằng cách tìm kiếm trong Python)


18 byte (lưu ý: thực sự cần phải có "tiền tố y 0s" tích hợp)
Erik the Outgolfer

Ugh tôi nghĩ rằng trông vụng về. Cảm ơn!
Jonathan Allan

Nhiều thứ có vẻ lúng túng, đôi khi bạn phải làm quen với chúng. : P
Erik the Outgolfer


4

J , 37 byte

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

Giải trình:

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

Đã kết thúc tương đối dễ đọc, tbh.


Chào mừng đến với PPCG! Đây là một bộ thử nghiệm - Tôi đã đánh cắp mã gói từ câu trả lời của Galen Ivanov.
Jonathan Allan

Chào mừng bạn đến với PPCG! Giải pháp tốt đẹp! Đây là một liên kết TIO với nó.
Galen Ivanov



@FrownyFrog tốt đẹp!
Giô-na


3

Than , 31 byte

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

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Giải trình:

     χ                          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

Giải pháp thay thế, cũng 31 byte:

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

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã.

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

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}

Hãy thử trực tuyến!

Phân tách abđệ quy cho đến khi chúng tôi nhận được 10 chữ số của mỗi. 6883đưa ra bảng ternary dẹt (đảo ngược). Tái thiết từ ternary đến thập phân bằng cách nhân với 3**(10-l).



2

J , 43 byte

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

Nó chắc chắn có thể được chơi golf hơn nữa.

Giải trình:

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

Hãy thử trực tuyến!



2

Pyth 26 25 24 byte

Đã lưu 1 byte, nhờ @ErikTheOutgolfer

Lưu một byte khác, lấy cảm hứng từ câu trả lời của @ Jonathan ALLan

im@j3422 3id3Cm.[0Tjd3Q3

Đầu vào là danh sách 2 yếu tố [a,b]. Dùng thử trực tuyến tại đây , hoặc xác minh tất cả các trường hợp thử nghiệm ở đây .

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

.Tcó thể C.
Erik the Outgolfer


1

Japt , 24 23 byte

Bắt quả bóng lăn trên đường chạy của Japt như ngôn ngữ của tháng - tôi hoàn toàn mong đợi sẽ vượt qua điều này!

Đưa đầu vào theo thứ tự ngược lại như một mảng số nguyên (nghĩa là [b,a]).

ms3 ùTA y_n3 g6883ì3Ãì3

Thử nó

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

Ngôn ngữ Wolfram (Mathicala) , 75 72 60 byte

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

Hãy thử trực tuyến!

phiên bản không chơi gôn:

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

Cả hai abđược chuyển đổi thành danh sách mười trit, sau đó được sử dụng theo cặp như một chỉ mục 2D thành bảng tra cứu số {1, 0, 0, 1, 0, 2, 2, 2, 1}. Kết quả một lần nữa được hiểu là danh sách mười trit và được chuyển đổi trở lại dạng số nguyên.

Bảng tra cứu được mã hóa IntegerDigits[6883,3]là ngắn, vì chúng tôi đang tái chế IntegerDigitsbiểu tượng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.