Реализуйте «сумасшедший» оператор Малболжа


41

Одной из многих уникальных особенностей языка программирования Malbolge является его крайне неинтуитивный OPоператор, упоминаемый в документации и исходном коде только как «op», но широко известный как оператор «сумасшедший». Как описывает Бен Олмстед, создатель языка, в его документации: « не ищите шаблон, его там нет ».

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

           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
можно ли ответить на этот вопрос в Malboge? ;)
Отображаемое имя

3
Полагаю, Мальболге сейчас хороший язык для игры в гольф!
Итан

7
Что бы это ни стоило, 54616_3это не значит, что «эта другая вещь - десятичное число 54616, но представлена ​​как основа три». Это означает «Читать 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 ] , мы вычисляем:aб[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

Выбор функции

Есть несколько других возможных функций-кандидатов вида:

еК,с,п,м(a,б)знак равно((a+Кб+с)пмодификациям)модификация3

Одним из самых коротких является:

е(a,б)знак равно((a+5б+2)4модификация25)модификация3

Но хорошая вещь в состоит в том, что это может быть выполнено с побитовыми операторами, таким образом неявно отбрасывая десятичные части a и b . Вот почему мы можем просто разделить их на 3 без округления между каждой итерацией.(a+512б+8)aб3

комментарии

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
Интересно, как вы нашли шаблон, которого не существует.
Эрик Outgolfer

Есть ли основание предпочесть , k = 9 ... => ~k && ...чтобы k = 10 ... => k && ...?
Falco

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

Эти целые числа должны отображаться с помощью данной таблицы поиска в OP. В настоящее время мы используем формулу, которая отображает эти числа в соответствующие им триты ( ):01,100,...

е(Икс)знак равно((Икс+5)3-5) модификация 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при преобразовании в трехзначное трехзначное целое число, 1120020210которое просто добавляет конечный ноль в операционную таблицу при чтении столбцов. Затем мы конвертируем троичные цифры aи bпоэлементно в целое число и используем его в качестве индекса в троичных цифрах 30801.


1
62 байта Yay за приоритет оператора!
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 и продолжим работу с предварительным циклом «разделяй и тестируй».



7

APL (Дьялог) , 41 25 байт

9 байтов сохранено благодаря @ Adám

3⊥(b6883)[3⊥⍉⎕⊤⍨3,b93]

Попробуйте онлайн!


Принимает входные данные в обратном порядке, 25 байтов:3⊥(b⊤6883)[3⊥⍉⎕⊤⍨3,b←9⍴3]
Adám

@ Adám спасибо! это кое-что изящное. Я думаю, что я немного заржавел: P
Уриэль

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 байт (примечание: действительно должен быть y 0встроен «prepend s»)
Эрик Outgolfer

Тьфу, я думал, что это выглядит неловко. Благодарность!
Джонатан Аллан

Многие вещи выглядят неловко, иногда нужно к ним привыкнуть. : P
Эрик Outgolfer


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! Вот тестовый набор - я украл код упаковки из ответа Галена Иванова.
Джонатан Аллан

Добро пожаловать в 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.
Эрик Outgolfer


1

Джапт , 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

Wolfram Language (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преобразуются в десятикратные списки, а затем используются попарно в качестве двумерного индекса в справочную таблицу чисел {1, 0, 0, 1, 0, 2, 2, 2, 1}. Результат снова интерпретируется как десятикратный список и преобразуется обратно в целочисленную форму.

Таблица поиска закодирована как IntegerDigits[6883,3], что коротко, потому что мы перерабатываем IntegerDigitsсимвол.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.