Mettre en œuvre l'opérateur "fou" de Malbolge

41

L'une des nombreuses caractéristiques uniques du langage de programmation Malbolge est son OPopérateur extrêmement peu intuitif , désigné uniquement par "op" dans la documentation et le code source, mais communément appelé l'opérateur "fou". Comme le décrit Ben Olmstead, le créateur du langage, dans sa documentation: " ne cherchez pas de motif, il n'y est pas ".

op est un opérateur "tritwise" - il opère sur les chiffres ternaires correspondants de ses deux arguments. Pour chaque trit (bit ternaire), le résultat de op est donné par la table de consultation suivante:

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

Par exemple, pour calculer op(12345, 54321), écrivez d'abord les deux nombres en ternaire, puis recherchez chaque paire d'erreurs dans le tableau:

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

Le dernier point important est que toutes les valeurs dans Malbolge ont une largeur de 10 passages. Par conséquent, les valeurs en entrée doivent être complétées avec des zéros jusqu'à une largeur de 10. (Par exemple, elle op(0, 0)est 1111111111en ternaire.)

Votre tâche consiste à prendre deux nombres entiers 0 ≤ a, b<59049 en entrée et à afficher la valeur entière de op(a,b).

Cas de test (dans le format a b op(a,b)):

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

Voici une implémentation de référence (copiée directement du code source de Malbolge).

Poignée de porte
la source
28
Peut-on répondre à Malboge? ;)
Nom complet
3
Je suppose que le Malbolge est une bonne langue pour jouer au golf maintenant!
Ethan
7
Car ce que cela vaut 54616_3ne signifie pas "cette autre chose est le nombre décimal 54616, mais représenté en base trois". Cela signifie "lire 54616en base 3". Ce que vous ne pouvez bien sûr pas faire (il y a des chiffres que Valve ne peut pas compter). Il serait probablement toujours aussi clair si vous vous en débarrassiez _3entièrement et de manière plus précise.
La poursuite de Monica le
@Orangesandlemons J'imagine que le simple fait d'utiliser l'opérateur de Malbolge relèverait de l'échappatoire standard. Réimplémenter en utilisant un code différent serait bien.
Paŭlo Ebermann
7
@ PaŭloEbermann Non, ce n'est pas une échappatoire .
user202729

Réponses:

43

C (gcc) , 99 98 96 octets

  • Sauvegardé un octet grâce à ceilingcat ; jouer 19683au golf L'䳣'.
  • Sauvé deux octets; jouer 108609au golf 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;}

Essayez-le en ligne!

Jonathan Frech
la source
14
J'aime le schéma de nommage!
Matthieu M.
28

JavaScript (ES7), 56 octets

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

Essayez-le en ligne!

Comment?

Étant donné et b dans [ 0..2 ] , nous calculons:ab[0..2]

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

Menant à:

 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

Choix de fonction

Il existe plusieurs autres fonctions possibles du formulaire:

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

L'un des plus courts étant:

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

Mais la bonne chose à propos de est qu’elle peut être exécutée avec des opérateurs au niveau des bits, éliminant ainsi implicitement les parties décimales de a et b . C'est pourquoi nous pouvons simplement les diviser par 3 sans arrondir entre chaque itération.(a+512b+8)ab3

Commenté

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
la source
Je pense (1581093>>b%3*2+a%3*8&3)sauve un octet entier!
Neil
@ Neil Malheureusement, je passe a/3et b/3sans arrondir. Cela échouerait à cause de cela.
Arnauld
9
Intéressant comment vous avez trouvé un motif qui n'existe pas.
Erik l'Outgolfer
Y at - il raison de préférer k = 9 ... => ~k && ...à k = 10 ... => k && ...?
Falco
1
@ Falco Non, il n'est en aucun cas plus court ni plus efficace. J'aurais juste tendance à préférer les trucs indexés 0, alors je préférerais imiter for(k=9;k>=0;k--)que for(k=10;k>=1;k--).
Arnauld
13

05AB1E , 18 octets

Code:

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

Utilise le codage 05AB1E . Essayez-le en ligne!


Explication de l'algorithme

(1,1)0

Par exemple, pour les entrées 12345 et 54321 , celles-ci sont mappées sur:

12345101212210205432112202111220

Ce qui donne la liste suivante des entiers joints:

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

01,100,

F(X)=((X+5)3-5) mod 3

Finalement, après avoir mappé cette fonction sur la liste des entiers joints, nous traitons cette liste résultante comme un nombre représenté en base 3 et la convertissons de la base 3 en décimale.


Explication du code

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
la source
Peut 3Tm+3Bø19sm74%3%3βêtre joué au golf?
Jonathan Allan
@ JonathanAllan Belle trouvaille! Il semble cependant impossible de jouer au golf plus loin sans utiliser un autre type de formule magique noire.
Adnan
11

R , 64 62 octets

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

Essayez-le en ligne!

Merci à JAD pour quelques astuces de golf magie noire et -2 octets!

30801lorsqu’il est converti en un entier ternaire de 10 chiffres, 1120020210ajoute simplement un zéro final à la table des opérations, lors de la lecture des colonnes. Ensuite, nous convertissons les chiffres ternaires de aet bélément par élément en un entier et l’utilisons comme index dans les chiffres ternaires de 30801.

Giuseppe
la source
1
62 octets Yay pour la priorité de l'opérateur!
JAD
1
Oui, de cette façon, vous devez d' abord l' index à l' xaide [.*]. Ensuite, toutes les %any%opérations se produisent. La partie amusante est que si vous voyez 30801%/%x%%3comme f=function(x)30801%/%x%%3ça f(x[index]) == (f(x))[index]. Sauver les accolades :)
JAD
@JAD fascinant! Et comme je le dis ci-dessus, fondamentalement la magie noire.
Giuseppe
1
J'admets volontiers que cela a pris beaucoup de tripes: P
JAD
10

C (gcc) , 74 72 71 octets

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

Essayez-le en ligne!

Panne

La table de vérité

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

Peut être considéré comme un tableau 3x3, où a est la colonne et b est la ligne. Transformer cela en une liste unidimensionnelle nous donne 100102221. Pour économiser de l'espace, nous évitons les listes et les chaînes et nous en faisons un nombre. Pour ce faire, nous inversons l'ordre et transformons chaque analyse en un nombre de 2 bits. Collez-les ensemble et nous avons un nombre binaire dans lequel nous pouvons "indexer" en déplaçant vers la droite 2 * (b * 3 + a)et en masquant:

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

Ensuite, nous masquons l'expression en utilisant la puissance de la priorité des opérations pour devenir l'abomination ci-dessus.

3 ^ 9 = 19683, donc c'est une bonne limite de boucle. Puisque nous multiplions le compteur par 3 à chaque fois, nous pouvons écrire la limite comme à la 2e4place. Aussi, nous nous épargnons la peine pow()ou similaire.

À la réflexion, commençons à 3 ^ 10 et descendons avec une division et un test de pré-boucle.

gastropner
la source
8

Haskell , 108 octets

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

Essayez-le en ligne!

Assistant de blé
la source
6

Gelée ,  23 à  18 octets

-1 grâce à Erik le Outgolfer (rearrange 3*⁵¤à ⁵3*)

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

Un lien monadique acceptant une liste de deux entiers.

Essayez-le en ligne! Ou voir une suite de tests .

⁹*%733%3est un octet plus long que ị⁽½Ṡb3¤:(

Comment?

⁵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

Aussi 18: ⁵3*+b3ZḌ19*%74%3ḅ3(utilise une formule magique après avoir obtenu les qualités par paires de convertir de la base dix puis prendre 19 à cette puissance, modulo 74, modulo 3 pour obtenir les qualités requises de la sortie - trouvées à l'aide d'une recherche en Python)

Jonathan Allan
la source
18 octets (note: il devrait vraiment y avoir un "prepend y 0s" intégré)
Erik the Outgolfer
Ugh je pensais que ça avait l'air bizarre. Merci!
Jonathan Allan
Beaucoup de choses semblent bizarres, il faut parfois s'y habituer. : P
Erik the Outgolfer
4

J , 37 octets

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

Explication:

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

Fini par être relativement lisible, tbh.

drachme
la source
Bienvenue chez PPCG! Voici une suite de tests - J'ai volé le code d'emballage de la réponse de Galen Ivanov.
Jonathan Allan
Bienvenue à PPCG! Belle solution! Voici un lien TIO pour cela.
Galen Ivanov
30
FrownyFrog le
2
28
FrownyFrog le
@FrownyFrog sympa!
Jonah
3

Charbon de bois , 31 octets

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

Essayez-le en ligne! Le lien est vers la version verbeuse du code. Explication:

     χ                          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

Solution alternative, également 31 octets:

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

Essayez-le en ligne! Le lien est vers la version verbeuse du code.

        χ                  χ    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
la source
2

Ruby , 70 octets

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

Essayez-le en ligne!

Se décompose aet brécursivement jusqu'à obtenir 10 chiffres de chacun. 6883donne la table ternaire aplatie (inversée). Reconstruit de ternaire à décimal en multipliant par 3**(10-l).

crashoz
la source
2

J , 43 octets

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

On peut certainement jouer au golf plus loin.

Explication:

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

Essayez-le en ligne!

Galen Ivanov
la source
2

Pyth 26 25 24 octets

Enregistré 1 octet, grâce à @ErikTheOutgolfer

Enregistrez un autre octet, inspiré par la réponse de @ JonathanAllan

im@j3422 3id3Cm.[0Tjd3Q3

L'entrée est une liste de 2 éléments [a,b]. Essayez-le en ligne ici ou vérifiez tous les cas de test ici .

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
la source
.Tpeut être C.
Erik the Outgolfer
1

Japt , 24 23 octets

Faire rouler la balle sur la course de Japt comme langue du mois - je m'attends vraiment à être dépassé sur ce point!

Prend les entrées dans l'ordre inverse sous la forme d'un tableau entier (c'est-à-dire [b,a]).

ms3 ùTA y_n3 g6883ì3Ãì3

L'essayer

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
Hirsute
la source
0

Perl 5 -p , 102 octets

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

Essayez-le en ligne!

Xcali
la source
0

Wolfram Language (Mathematica) , 75 72 60 octets

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

Essayez-le en ligne!

version non-golfée:

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

Les deux aet bsont convertis en listes à dix chiffres, puis utilisés par paire comme index 2D dans une table de correspondance de nombres {1, 0, 0, 1, 0, 2, 2, 2, 1}. Le résultat est à nouveau interprété comme une liste de dix notes et reconverti en un nombre entier.

La table de consultation est codée ainsi IntegerDigits[6883,3], ce qui est court car nous recyclons le IntegerDigitssymbole.

romain
la source