Implementar o operador "louco" de Malbolge

41

Um dos muitos recursos exclusivos da linguagem de programação Malbolge é seu OPoperador altamente intuitivo , referido apenas como "op" na documentação e no código-fonte, mas conhecido popularmente como operador "louco". Conforme descrito por Ben Olmstead, o criador da linguagem, em sua documentação: " não procure por padrão, ele não está lá ".

op é um operador "tritwise" - opera nos dígitos ternários correspondentes de seus dois argumentos. Para cada trit (bit ternário), o resultado de op é fornecido pela seguinte tabela de pesquisa:

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

Por exemplo, para calcular op(12345, 54321), primeiro escreva os dois números no ternário e, em seguida, procure cada par de trits na tabela:

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

O último ponto importante é que todos os valores em Malbolge têm 10 trits de largura; portanto, os valores de entrada devem ser preenchidos com zeros até uma largura de 10. (Por exemplo, op(0, 0)é1111111111 ternário).

Sua tarefa é pegar dois números inteiros 0 ≤ a, b<59049 como entrada e gerar o valor inteiro deop(a,b) .

Casos de teste (no formato a b op(a,b)):

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

Aqui está uma implementação de referência (copiada diretamente do código fonte do Malbolge).

Maçaneta da porta
fonte
28
isso pode ser respondido em Malboge? ;)
Exibir nome
3
Eu acho que Malbolge é uma boa linguagem de golfe agora!
Ethan
7
Pelo que vale, 54616_3não significa "essa outra coisa é o número decimal 54616, mas representado como base três". Significa "Leia 54616como base 3". O que, é claro, você não pode fazer (existem dígitos que a Valve não pode contar lá). Provavelmente ainda seria tão claro se você se livrasse do _3todo, e mais preciso.
Nic Hartley
@ Orangesandlemons Acho que apenas o uso do operador em Malbolge se enquadra na brecha padrão. Reimplementá-lo usando código diferente seria bom.
Paŭlo Ebermann
7
@ PaŭloEbermann Não, isso não é uma brecha .
precisa saber é o seguinte

Respostas:

43

C (gcc) , 99 98 96 bytes

  • Salvou um byte graças ao ceilingcat ; golfe 19683paraL'䳣' .
  • Salvou dois bytes; golfe 108609para 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;}

Experimente online!

Jonathan Frech
fonte
14
Eu gosto do esquema de nomeação!
Matthieu M.
28

JavaScript (ES7), 56 bytes

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

Experimente online!

Quão?

Dada e em , calculamos:b [ 0..2 ]ab[0..2]

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

Levando a:

 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

Escolha da função

Existem várias outras possíveis funções candidatas do formulário:

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

Um dos mais curtos sendo:

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

Mas o bom de é que ele pode ser executado com operadores bit a bit, descartando implicitamente as partes decimais de e . É por isso que podemos simplesmente dividi-los pora b 3(a+512b+8)ab3 sem arredondar entre cada iteração.

Comentado

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
fonte
Eu acho que (1581093>>b%3*2+a%3*8&3)economiza um byte inteiro!
Neil
@ Neil Infelizmente, estou passando a/3e b/3sem arredondamentos. Isso falharia por causa disso.
Arnauld
9
Interessante como você encontrou um padrão que não existe.
Erik the Outgolfer
Existe alguma razão para preferir k = 9 ... => ~k && ...a k = 10 ... => k && ...?
Falco
1
@Falco Não, não é nem mais curto nem mais eficiente. Eu costumava preferir coisas com índice 0, então prefiro imitar do for(k=9;k>=0;k--)que for(k=10;k>=1;k--).
Arnauld
13

05AB1E , 18 bytes

Código:

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

Usa a codificação 05AB1E . Experimente online!


Explicação do algoritmo

Para obter o número preenchido com zeros, precisamos adicionar 59049 a ambos os números (porque 59049 no ternário é 10000000000 ). Não precisamos deixar de fora o primeiro 1 como . Convertemos os números de decimal em ternário e juntamos cada par como cada número.(1,1)0

Por exemplo, para as entradas 12345 e 54321 , elas são mapeadas para:

12345101212210205432112202111220

O que fornece a seguinte lista de números inteiros unidos:

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

Esses números inteiros precisam ser mapeados pela tabela de pesquisa fornecida no OP. Atualmente, a fórmula que mapeia esses números para seus trits correspondentes ( ) é:01,100,

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

Enquanto denota o xor bit a bit função .

Eventualmente, depois de mapear esta função na lista de números inteiros unidos, tratamos essa lista resultante como um número representado na base 3 e a convertemos da base 3 em decimal.


Código Explicação

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
fonte
Pode 3Tm+3Bø19sm74%3%3βser jogado golfe?
Jonathan Allan
@JonathanAllan Nice find! No entanto, parece impossível continuar a jogar sem usar outro tipo de fórmula de magia negra.
Adnan
11

R , 64 bytes 62

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

Experimente online!

Obrigado ao JAD por alguns truques de golfe com magia negra e -2 bytes!

30801, quando convertido em um número inteiro ternário de 10 trit, é o 1120020210que apenas adiciona um zero à direita na tabela de operações ao ler as colunas. Em seguida, convertemos os dígitos ternários ae belementares em um número inteiro e usamos isso como índice nos dígitos ternários de 30801.

Giuseppe
fonte
1
62 bytes Yay pela precedência do operador!
JAD
1
Sim, desta maneira, você primeiro indexa xusando [.*]. Então todas as %any%operações acontecem. A parte divertida é que se você ver 30801%/%x%%3como f=function(x)30801%/%x%%3que f(x[index]) == (f(x))[index]. Guardar as chaves :)
JAD
@JAD fascinante! E como comentei acima, basicamente magia negra.
Giuseppe
1
Felizmente, admito que isso exigiu muita brincadeira: P
JAD
10

C (gcc) , 74 72 71 bytes

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

Experimente online!

Demolir

A tabela da verdade

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

Pode ser pensado como uma matriz 3x3, onde a é a coluna eb é a linha. Transformar isso em uma lista unidimensional nos dá 100102221. Para economizar espaço, evitamos listas e seqüências de caracteres e transformamos em um número. Para fazer isso, alteramos a ordem e transformamos cada trit em um número de 2 bits. Cole-os juntos e temos um número binário no qual podemos "indexar", mudando para a direita 2 * (b * 3 + a)e mascarando:

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

Em seguida, massageamos a expressão usando o poder da precedência de operação para nos tornar a abominação acima.

3 ^ 9 = 19683, portanto esse é um bom limite de loop. Como multiplicamos o contador por 3 a cada vez, podemos escrever o limite como 2e4alternativa. Também nos salvamos do incômodo pow()ou similar.

Pensando bem, vamos começar com 3 ^ 10 e trabalhar para baixo com um teste e divisão pré-loop.

gastropner
fonte
8

Haskell , 108 bytes

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

Experimente online!

Assistente de Trigo
fonte
6

Geléia ,  23  18 bytes

-1 graças a Erik the Outgolfer (reorganizar 3*⁵¤para ⁵3*)

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

Um link monádico que aceita uma lista de dois números inteiros.

Experimente online! Ou veja uma suíte de testes .

⁹*%733%3é um byte maior que ị⁽½Ṡb3¤:(

Quão?

⁵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

Também 18: ⁵3*+b3ZḌ19*%74%3ḅ3(usa uma fórmula mágica após obter os trits em pares da conversão da base dez e depois levar 19 para esse poder, módulo 74, módulo 3 para obter os trits necessários da saída - encontrado usando uma pesquisa em Python)

Jonathan Allan
fonte
18 bytes (Nota: Não deve realmente ser um "preceder y 0s" built-in)
Erik o Outgolfer
Ugh, eu pensei que isso parecia estranho. Obrigado!
Jonathan Allan
Muitas coisas parecem estranhas, às vezes você precisa se acostumar com elas. : P
Erik the Outgolfer 01/07/19
4

J , 37 bytes

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

Explicação:

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

Acabou sendo relativamente legível, tbh.

dram
fonte
Bem-vindo ao PPCG! Aqui está uma suíte de testes - roubei o código da resposta de Galen Ivanov.
Jonathan Allan
Welcom para PPCG! Ótima solução! Aqui está um link TIO para ele.
Galen Ivanov
30
FrownyFrog
2
28
FrownyFrog
@FrownyFrog nice!
Jonah
3

Carvão , 31 bytes

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

Experimente online! Link é a versão detalhada do código. Explicação:

     χ                          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

Solução alternativa, também 31 bytes:

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

Experimente online! Link é a versão detalhada do código.

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

Ruby , 70 bytes

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

Experimente online!

Decompõe-se ae brecursivamente até obtermos 10 dígitos de cada. 6883fornece a tabela ternária achatada (invertida). Reconstrói de ternário para decimal multiplicando por 3**(10-l).

crashoz
fonte
2

Cjam, 31 bytes

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

Experimente online!

Crómio
fonte
2

J , 43 bytes

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

Certamente pode ser ainda mais jogado.

Explicação:

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

Experimente online!

Galen Ivanov
fonte
2

Pitão 26 25 24 bytes

Guardado 1 byte, graças a @ErikTheOutgolfer

Salvar outro byte, inspirado na resposta de @ JonathanAllan

im@j3422 3id3Cm.[0Tjd3Q3

Entrada é uma lista de 2 elementos [a,b]. Experimente online aqui ou verifique todos os casos de teste aqui .

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
fonte
.Tpode ser C.
Erik the Outgolfer
1

Japt , 24 23 bytes

Fazendo a bola rolar na corrida de Japt como língua do mês - espero ser superado por isso!

Toma a entrada na ordem inversa como uma matriz inteira (ou seja, [b,a]).

ms3 ùTA y_n3 g6883ì3Ãì3

Tente

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
fonte
0

Perl 5 -p , 102 bytes

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

Experimente online!

Xcali
fonte
0

Wolfram Language (Mathematica) , 75 72 60 bytes

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

Experimente online!

versão sem golfe:

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

Ambos ae bsão convertidos em listas de dez trit, usados ​​em pares como um índice 2D em uma tabela de números de pesquisa{1, 0, 0, 1, 0, 2, 2, 2, 1} . O resultado é novamente interpretado como uma lista de dez tritões e convertido novamente em forma de número inteiro.

A tabela de pesquisa é codificada como IntegerDigits[6883,3], que é curta, porque estamos reciclando o IntegerDigitssímbolo.

romano
fonte