Вкажіть "божевільний" оператор Малболге


41

Однією з багатьох унікальних особливостей мови програмування Malbolge є її дуже неінтуїтивний OPоператор, який у документації та вихідному коді називається лише "op", але в народі відомий як "божевільний" оператор. Як описав у своїй документації Бен Олмстед, творець мови: " не шукайте шаблону, його там немає ".

op - оператор "tritwise" - він працює на відповідних потрійних цифрах двох його аргументів. Для кожного трита (потрійний біт) результат op задається наступною таблицею пошуку:

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

Наприклад, для обчислення op(12345, 54321)спочатку випишіть обидва числа у потрійному, а потім шукайте кожну пару тритів у таблиці:

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

Останній важливий момент є те, що всі значення в Malbolge 10 trits шириною, тому вхідні значення повинні бути доповнені нулями до ширини 10. (наприклад, op(0, 0)знаходиться 1111111111в трехкомпонентном.)

Ваше завдання - взяти за вхід два цілих числа 0 ≤ a, b<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не означає, що "інша річ є десятковим числом 54616, але представлена ​​як основна три". Це означає "Прочитати 54616як базу 3". Що, звичайно, ви не можете зробити (є цифри, на які Valve не може порахувати). Напевно, все одно було б так само зрозуміло, якби ви позбулися _3цілком і точніше.
Нік Хартлі

@Orangesandlemons Я думаю, що просто використання оператора в Malbolge потрапить під стандартну лазівку. Повторно виконувати його за допомогою іншого коду було б добре.
Paŭlo Ebermann

7
@ PaŭloEbermann Ні, це не лазівка .
користувач202729

Відповіді:



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

Одним з найкоротших є:

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

Але хороша річ полягає в тому, що вона може бути виконана з побітними операторами, таким чином неявно відкидаючи десяткові частини і . Ось чому ми можемо просто розділити їх на без округлення між кожною ітерацією.(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/3і b/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 до обох чисел (бо 59049 у потрійному - 10000000000 ). Нам не потрібно залишати провідні 1 як . Ми перетворюємо числа з десяткових в потрійні і приєднуємо кожну пару як кожне власне число.(1,1)0

Наприклад, для вхідних даних 12345 та 54321 вони відображаються на:

12345101212210205432112202111220

Що дає наступний список об'єднаних цілих чисел:

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

Ці цілі числа потрібно відобразити за допомогою заданої таблиці пошуку в ОП. Формула, яку ми використовуємо в даний час, яка відображає ці числа до відповідних тритів ( ):01,100,

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

Тоді як позначає побитову функцію xor .

Зрештою після відображення цієї функції у списку об'єднаних цілих чисел ми розглядаємо цей отриманий список як число, представлене в базі 3, і перетворюємо його з бази 3 в десятковий.


Пояснення коду

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

R , 64 62 байти

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

Спробуйте в Інтернеті!

Дякуємо JAD за кілька чорних магічних трюків з гольфу та -2 байти!

30801, при перетворенні на 10-тритрічне потрійне ціле число - це те, 1120020210що просто додає кінцевий нуль до операційної таблиці при зчитуванні стовпців. Потім ми перетворюємо потрійні цифри aта bелементами в ціле число і використовуємо це як індекс у потрійні цифри 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 - рядок. Перетворення цього в одновимірний список дає нам 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

Монадична посилання, що приймає список з двох цілих чисел.

Спробуйте в Інтернеті! Або подивіться тестовий набір .

⁹*%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(використовує магічну формулу після отримання парних тритів перетворення з базової десяти, а потім забирає 19 на цю потужність, модуль 74, модуль 3, щоб отримати необхідні трити виведення - знайдені за допомогою пошуку в Python)


18 байт (примітка: має бути дійсно «PREPEND y 0S» вбудований)
Ерік Outgolfer

Фу, я подумав, що це виглядає ніяково. Дякую!
Джонатан Аллан

Багато речей виглядають незграбно, іноді до них доводиться звикати. : 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

Закінчився відносно читабельним, тбг.


Ласкаво просимо до PPCG! Ось набір тестів - я вкрав обгортковий код з відповіді Галена Іванова.
Джонатан Аллан

Вітаємо до 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

Рубін , 70 байт

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

Спробуйте в Інтернеті!

Розкладається aі bрекурсивно, поки ми не отримаємо 10 цифр кожної. 6883дає сплющений потрійний стіл (перевернутий). Реконструює від потрійного до десяткового шляхом множення на 3**(10-l).



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 байти

Збережено 1 байт, завдяки @ErikTheOutgolfer

Зберегти інші байти, натхненного @ 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

Japt , 24 23 байти

Як м'яч котиться на перегоні Джапта як мови місяця - я повністю сподіваюся на це перевершити!

Приймає вхід у зворотному порядку як цілий масив (тобто [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

Мова Вольфрама (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];

Обидва aі bперетворюються в десятитриткові списки, потім використовуються попарно як 2D-індекс у таблицю пошуку чисел {1, 0, 0, 1, 0, 2, 2, 2, 1}. Результат знову інтерпретується як десятитритний список і перетворюється назад у цілу форму.

Таблиця пошуку кодується як IntegerDigits[6883,3], що є коротким, оскільки ми переробляємо IntegerDigitsсимвол.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.