Implementa l'operatore "pazzo" di Malbolge


41

Una delle tante caratteristiche uniche del linguaggio di programmazione Malbolge è il suo OPoperatore altamente non intuitivo , indicato solo come "op" nella documentazione e nel codice sorgente ma popolarmente noto come operatore "pazzo". Come descritto da Ben Olmstead, il creatore della lingua, nella sua documentazione: " non cercare schemi, non è lì ".

op è un operatore "tritwise" - opera sulle cifre ternarie corrispondenti dei suoi due argomenti. Per ogni trit (bit ternario), il risultato di op è dato dalla seguente tabella di ricerca:

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

Ad esempio, per calcolare op(12345, 54321), prima scrivi entrambi i numeri in ternario e poi cerca ogni coppia di trit nella tabella:

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

L'ultimo punto importante è che tutti i valori in Malbolge hanno una larghezza di 10 trits, quindi i valori di input devono essere riempiti con zeri per una larghezza di 10. (Ad esempio, op(0, 0)è 1111111111in ternario).

Il tuo compito è prendere due numeri interi 0 ≤ a, b<59049 come input e produrre il valore intero di op(a,b).

Casi di prova (nel formato a b op(a,b)):

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

Ecco un'implementazione di riferimento (copiata direttamente dal codice sorgente di Malbolge).


28
si può rispondere in Malboge? ;)
Visualizza nome

3
Immagino che Malbolge sia una buona lingua per giocare a golf!
Ethan,

7
Per quello che vale, 54616_3non significa "quest'altra cosa è il numero decimale 54616, ma rappresentato come base tre". Significa "Leggi 54616come base 3". Il che, ovviamente, non puoi fare (ci sono cifre sulle quali Valve non può contare). Probabilmente sarebbe ancora altrettanto chiaro se ti liberassi del _3tutto e più accurato.
Nic Hartley,

@Orangesandlemons Immagino che il solo utilizzo dell'operatore in Malbolge rientri nella scappatoia standard. Reimplementarlo usando un codice diverso sarebbe ok.
Paŭlo Ebermann,

7
@ PaŭloEbermann No, non è una scappatoia .
user202729,

Risposte:



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)

Provalo online!

Come?

Dato e b in [ 0..2 ] , calcoliamo:ab[0..2]

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

Portando 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

Scelta della funzione

Esistono diverse altre possibili funzioni candidate del modulo:

fK,c,p,m(un',B)=((un'+KB+c)pmodm)mod3

Uno dei più brevi è:

f(un',B)=((un'+5B+2)4mod25)mod3

Ma la cosa buona è che può essere eseguita con operatori bit per bit, quindi implicitamente scartando le parti decimali di un e b . Questo è il motivo per cui possiamo semplicemente dividerli per 3 senza arrotondare tra ogni iterazione.(un'+512B+8)un'B3

Commentate

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

Penso che (1581093>>b%3*2+a%3*8&3)salva un intero byte!
Neil,

@Neil Purtroppo sto passando a/3e b/3senza arrotondare. Ciò fallirebbe per questo.
Arnauld,

9
Interessante come hai trovato un modello che non esiste.
Erik the Outgolfer,

C'è qualche ragione per preferire k = 9 ... => ~k && ...a k = 10 ... => k && ...?
Falco,

1
@Falco No, non è né più breve né più efficiente in alcun modo. Avevo appena tendo a preferire roba 0-indicizzato, quindi preferirei mimica for(k=9;k>=0;k--)di for(k=10;k>=1;k--).
Arnauld,

13

05AB1E , 18 byte

Codice:

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

Utilizza la codifica 05AB1E . Provalo online!


Spiegazione dell'algoritmo

Per ottenere il numero imbottito di zeri, è necessario aggiungere 59049 a entrambi i numeri (perché 59049 in ternario è 10000000000 ). Non dobbiamo tralasciare il 1 principale come . Convertiamo i numeri da decimali a ternari e uniamo ogni coppia come ciascun numero.(1,1)0

Ad esempio, per gli input 12345 e 54321 , questi vengono mappati su:

12345101212210205432112202111220

Che fornisce il seguente elenco di numeri interi uniti:

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

01,100,...

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

Alla fine, dopo aver mappato questa funzione nell'elenco di numeri interi uniti, trattiamo questo elenco risultante come un numero rappresentato nella base 3 e lo convertiamo dalla base 3 in decimale.


Spiegazione del codice

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.

Si può 3Tm+3Bø19sm74%3%3βgiocare a golf?
Jonathan Allan,

@JonathanAllan Nice find! Sembra comunque impossibile giocarlo ulteriormente senza usare qualche altro tipo di formula di magia nera.
Adnan,

11

R , 64 62 byte

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

Provalo online!

Grazie a JAD per alcuni trucchi di golf di magia nera e -2 byte!

30801, quando convertito in un intero ternario a 10 triti, è quello 1120020210che aggiunge solo uno zero finale alla tabella delle operazioni, quando viene letto le colonne. Quindi convertiamo le cifre ternarie di aed belementally in un numero intero e usiamo questo come indice nelle cifre ternarie di 30801.


1
62 byte Sì per la precedenza dell'operatore!
JAD

1
Sì, in questo modo, per prima cosa indicizzi xusando [.*]. Quindi tutte le %any%operazioni avvengono. La parte divertente è che se si vede 30801%/%x%%3come f=function(x)30801%/%x%%3, quello f(x[index]) == (f(x))[index]. Salvare le parentesi graffe :)
JAD

@JAD affascinante! E come ho commentato sopra, fondamentalmente magia nera.
Giuseppe,

1
Ammetterò felicemente che ci sia voluto molto tempo: 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;}

Provalo online!

Abbattersi

La tabella della verità

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

Può essere pensato come un array 3x3, dove a è la colonna e b è la riga. Trasformarlo in un elenco unidimensionale ci dà 100102221. Per risparmiare spazio evitiamo elenchi e stringhe e lo trasformiamo invece in un numero. Per fare ciò, capovolgiamo l'ordine e trasformiamo ogni trit in un numero di 2 bit. Incollali insieme e abbiamo un numero binario in cui possiamo "indicizzare" spostandoci a destra 2 * (b * 3 + a)e mascherando:

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

Successivamente, massaggiamo l'espressione usando il potere della precedenza operativa per diventare l'abominio sopra.

3 ^ 9 = 19683 quindi questo è un buon limite di loop. Dato che moltipliciamo il contatore per 3 ogni volta, possiamo scrivere il limite come 2e4invece. Inoltre ci risparmiamo il disturbo pow()o simili.

Ripensandoci, iniziamo da 3 ^ 10 e lavoriamo verso il basso con un divide-and-test pre-loop.




6

Gelatina ,  23  18 byte

-1 grazie a Erik the Outgolfer (riorganizzare 3*⁵¤in ⁵3*)

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

Un collegamento monadico che accetta un elenco di due numeri interi.

Provalo online! Oppure vedi una suite di test .

⁹*%733%3è un byte più lungo di ị⁽½Ṡb3¤:(

Come?

⁵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

Anche 18: ⁵3*+b3ZḌ19*%74%3ḅ3(usa una formula magica dopo aver ottenuto le tratte a coppie di conversione dalla base dieci e poi prendendo 19 a quella potenza, modulo 74, modulo 3 per ottenere i trits necessari dell'output - trovato usando una ricerca in Python)


18 byte (nota: dovrebbe esserci un "prepend y 0s" incorporato)
Erik the Outgolfer,

Pensavo che fosse imbarazzante. Grazie!
Jonathan Allan,

Molte cose sembrano imbarazzanti, a volte devi abituarti. : P
Erik the Outgolfer,


4

J , 37 byte

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

Spiegazione:

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

Finì per essere relativamente leggibile, grazie.


Benvenuti in PPCG! Ecco una suite di test: ho rubato il codice di wrapping dalla risposta di Galen Ivanov.
Jonathan Allan,

Benvenuto in PPCG! Bella soluzione! Ecco un link TIO ad esso.
Galen Ivanov,



@FrownyFrog nice!
Giona


3

Carbone , 31 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

     χ                          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

Soluzione alternativa, anche 31 byte:

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

Provalo online! Il collegamento è alla versione dettagliata del codice.

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

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

Provalo online!

Si decompone ae bricorsivamente fino a quando non si ottengono 10 cifre per ciascuna. 6883dà la tavola ternaria appiattita (invertita). Ricostruisce da ternario a decimale moltiplicando per 3**(10-l).



2

J , 43 byte

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

Può sicuramente essere ulteriormente giocato a golf.

Spiegazione:

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

Provalo online!



2

Pyth 26 25 24 byte

Salvato 1 byte, grazie a @ErikTheOutgolfer

Salva un altro byte, ispirato alla risposta di @ JonathanAllan

im@j3422 3id3Cm.[0Tjd3Q3

L'input è un elenco di 2 elementi [a,b]. Provalo online qui o verifica tutti i casi di test qui .

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

.Tpuò essere C.
Erik the Outgolfer,


1

Japt , 24 23 byte

Far rotolare la palla sulla corsa di Japt come lingua del mese - mi aspetto pienamente di essere superato su questo!

Prende l'input in ordine inverso come un array intero (cioè, [b,a]).

ms3 ùTA y_n3 g6883ì3Ãì3

Provalo

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 byte

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

Provalo online!

versione senza golf:

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

Entrambi ae bvengono convertiti in elenchi a dieci triti, quindi utilizzati in coppia come indice 2D in una tabella di ricerca dei numeri {1, 0, 0, 1, 0, 2, 2, 2, 1}. Il risultato viene nuovamente interpretato come un elenco di dieci triti e convertito nuovamente in un numero intero.

La tabella di ricerca è codificata come IntegerDigits[6883,3], che è breve perché stiamo riciclando il IntegerDigitssimbolo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.