Logique ternaire équilibrée

11

Logique ternaire équilibrée

Ternaires est normalement un autre nom pour la base 3, c'est - à - dire, chaque chiffre est 0, 1ou 2, et chaque endroit vaut 3 fois plus que l'endroit suivant.

Ternaire équilibrée est une modification de ternaire qui utilise les chiffres de -1, 0et 1. Cela a l'avantage de ne pas avoir besoin d'un signe. Chaque place vaut encore 3 fois plus que la place suivante. Les premiers entiers positifs sont donc [1], [1, -1], [1, 0], [1, 1], [1, -1, -1]alors que les premiers entiers négatifs sont [-1], [-1, 1], [-1, 0], [-1, -1], [-1, 1, 1].

Vous avez trois entrées x, y, z. zest soit -1, 0ou 1, tout xet ypeut être de -3812798742493la 3812798742493inclus.

La première étape consiste à convertir xet yde décimal en ternaire équilibré. Cela devrait vous donner 27 trits (chiffres TeRnary). Vous devez ensuite combiner les trits de xet ypar paires à l'aide d'une opération ternaire, puis reconvertir le résultat en décimal.

Vous pouvez choisir les valeurs de zmappage pour chacune de ces trois opérations ternaires:

  • A: Étant donné deux trits, si l'un est nul, le résultat est nul, sinon le résultat est -1 s'ils sont différents ou 1 s'ils sont identiques.
  • B: Étant donné deux trits, si l'un est zéro, alors le résultat est l'autre trit, sinon le résultat est zéro s'ils sont différents ou la négation s'ils sont les mêmes.
  • C: Étant donné deux trits, le résultat est nul s'ils sont différents ou leur valeur s'ils sont identiques.

Exemple. Supposons xest 29et yest 15. En ternaire équilibré, ceux-ci deviennent [1, 0, 1, -1]et [1, -1, -1, 0]. (Les 23 zéros restants ont été omis par souci de concision.) Après chacune des opérations respectives, ils deviennent A: [1, 0, -1, 0], B: [-1, -1, 0, -1], C: [1, 0, 0, 0]. Convertis en décimal, les résultats sont 24, -37et 27respectivement. Essayez l'implémentation de référence suivante pour plus d'exemples:

L'implémentation de référence suit les étapes ci-dessus, mais vous êtes bien sûr libre d'utiliser n'importe quel algorithme qui produit les mêmes résultats.

C'est le , donc le programme ou la fonction la plus courte qui ne viole aucune échappatoire standard gagne!

Neil
la source
2
Si le format natif des nombres est ternaire équilibré (par opposition au binaire), sommes-nous autorisés à le prendre comme entrée de la manière habituelle (ce qui n'entraîne aucune conversion en ternaire équilibré)?
wizzwizz4
2
en relation
Giuseppe
1
faut-il zque ce soit une -1,0,1ou pouvons-nous choisir trois valeurs cohérentes et distinctes? J'ai sélectionné 1,2,3dans ma réponse, et il y a une certaine confusion à ce sujet.
Giuseppe
2
@Giuseppe Désolé, seuls les chiffres ternaires équilibrés sont autorisés.
Neil
2
J'ai lu quelque chose de transversal ... Trop de mots et pas de formule
RosLuP

Réponses:

2

Nettoyer , 231 ... 162 octets

import StdEnv
$n=tl(foldr(\p[t:s]#d=sign(2*t/3^p)
=[t-d*3^p,d:s])[n][0..26])
@x y z=sum[3^p*[(a+b)/2,[1,-1,0,1,-1]!!(a+b+2),a*b]!!(z+1)\\a<- $x&b<- $y&p<-[0..26]]

Définit la fonction @en prenant trois Ints et en donnant un Int.
Les opérateurs mappent en tant que 1 -> A, 0 -> B, -1 -> C.

Essayez-le en ligne!

La fonction $replie un lambda sur les emplacements de chiffres [0..26], en une liste de chiffres ternaires. Il utilise le début de la liste qu'il génère pour conserver une différence totale actuelle par rapport au nombre requis (c'est pourquoi il est suivi avant de revenir) et sign(2*t/3^p)pour déterminer le chiffre actuel à générer. L'astuce de signe est équivalente à if(abs(2*t)<3^p)0(sign t).

Οurous
la source
Je ne sais pas Clean, mais je suis intrigué par la façon dont vous vous êtes converti en ternaire équilibré, avec $n(je pense). Pourriez-vous ajouter une explication à cela?
Giuseppe
@ Giuseppe Absolument, j'ajouterai une explication aujourd'hui quand j'aurai le temps.
Οurous
@Giuseppe cela répond-il à votre question?
Janurous
Oui! Ça a du sens. Plutot malin!
Giuseppe
1

Gelée , 39 octets

×=
×
+ị1,-,0
A-r1¤ṗœs2ṚẎị@ȯµ€Uz0ZU⁹ŀ/ḅ3

Un programme complet prenant deux arguments, [x,y]et z
... où zest {A:-1, B:0, C:1}
qui imprime le résultat

Essayez-le en ligne! Remarque: la méthode golfée le rend lent - cette version modifiée est plus rapide (journaux de 3, plafonds et incréments avant chaque produit cartésien)

Comment?

×=       - Link  1 (1), B: list of trits L, list of trits R
×        - L multiplied by... (vectorises):
 =       -   L equal R? (vectorises)

×        - Link -1 (2), A: list of trits L, list of trits R
×        - L multiplied by R (vectorises)

+ị1,-,0  - Link  0 (3), C: list of trits L, list of trits R
+        - L plus R (vectorises)
  1,-,0  - list of integers = [1,-1,0]
 ị       - index into (vectorises) - 1-based & modular, so index -2 is equivalent to
         -                           index 1 which holds the value 1.

A-r1¤ṗœs2ṚẎị@ȯµ€Uz0ZU⁹ŀ/ḅ3 - Main link: list of integers [X,Y], integer Z
              µ€           - for each V in [X,Y]:
A                          -   absolute value = abs(V)
    ¤                      -   nilad followed by link(s) as a nilad:
 -                         -     literal minus one
   1                       -     literal one
  r                        -     inclusive range = [-1,0,1]
     ṗ                     -   Cartesian power, e.g. if abs(V)=3: [[-1,-1,-1],[-1,-1,0],[-1,-1,1],[-1,0,-1],[-1,0,0],[-1,0,1],[-1,1,-1],[-1,1,0],[-1,1,1],[0,-1,-1],[0,-1,0],[0,-1,1],[0,0,-1],[0,0,0],[0,0,1],[0,1,-1],[0,1,0],[0,1,1],[1,-1,-1],[1,-1,0],[1,-1,1],[1,0,-1],[1,0,0],[1,0,1],[1,1,-1],[1,1,0],[1,1,1]]
                           -                   (corresponding to: [-13       ,-12      ,-11      ,-10      ,-9      ,-8      ,-7       ,-6      ,-5      ,-4       ,-3      ,-2      ,-1      ,0      ,1      ,2       ,3      ,4      ,5        ,6       ,7       ,8       ,9      ,10      ,11     ,12     ,13     ] )
        2                  -   literal two
      œs                   -   split into equal chunks           [[[-1,-1,-1],[-1,-1,0],[-1,-1,1],[-1,0,-1],[-1,0,0],[-1,0,1],[-1,1,-1],[-1,1,0],[-1,1,1],[0,-1,-1],[0,-1,0],[0,-1,1],[0,0,-1],[0,0,0]],[[0,0,1],[0,1,-1],[0,1,0],[0,1,1],[1,-1,-1],[1,-1,0],[1,-1,1],[1,0,-1],[1,0,0],[1,0,1],[1,1,-1],[1,1,0],[1,1,1]]]
         Ṛ                 -   reverse                           [[[0,0,1],[0,1,-1],[0,1,0],[0,1,1],[1,-1,-1],[1,-1,0],[1,-1,1],[1,0,-1],[1,0,0],[1,0,1],[1,1,-1],[1,1,0],[1,1,1]],[[-1,-1,-1],[-1,-1,0],[-1,-1,1],[-1,0,-1],[-1,0,0],[-1,0,1],[-1,1,-1],[-1,1,0],[-1,1,1],[0,-1,-1],[0,-1,0],[0,-1,1],[0,0,-1],[0,0,0]]]
          Ẏ                -   tighten                            [[0,0,1],[0,1,-1],[0,1,0],[0,1,1],[1,-1,-1],[1,-1,0],[1,-1,1],[1,0,-1],[1,0,0],[1,0,1],[1,1,-1],[1,1,0],[1,1,1],[-1,-1,-1],[-1,-1,0],[-1,-1,1],[-1,0,-1],[-1,0,0],[-1,0,1],[-1,1,-1],[-1,1,0],[-1,1,1],[0,-1,-1],[0,-1,0],[0,-1,1],[0,0,-1],[0,0,0]]
                           -                   (corresponding to: [1      ,2       ,3      ,4      ,5        ,6       ,7       ,8       ,9      ,10     ,11      ,12     ,13     ,-13       ,-12      ,-11      ,-10      ,-9      ,-8      ,-7       ,-6      ,-5      ,-4       ,-3      ,-2      ,-1      ,0      ] )
           ị@              -   get item at index V (1-based & modular)
             ȯ             -   logical OR with V (just handle V=0 which has an empty list)
                U          - upend (big-endian -> little-endian for each)
                  0        - literal zero           }
                 z         - transpose with filler  } - pad with MSB zeros
                   Z       - transpose              }
                    U      - upend (little-endian -> big-endian for each)
                       /   - reduce with:
                      ŀ    -   link number: (as a dyad)
                     ⁹     -     chain's right argument, Z
                         3 - literal three
                        ḅ  - convert from base
Jonathan Allan
la source
Je ne peux pas pour la vie de moi lire des langues de golf, donc quand vous dites «lent», quelle est la complexité du temps?
Οurous
Pour obtenir le ternaire équilibré de N, il crée une liste de toutes les (3 ^ n) listes abs (N) de trits (0, -1 et 1). Donc O (3 ^ max (abs (X), abs (Y)))
Jonathan Allan
Merci, et pour l'explication, je vois que vous avez ajouté aussi!
Οurous
1
Également ajouté une version plus rapide en utilisant la même méthode :)
Jonathan Allan
1

R , 190 172 151 151 octets

function(a,b,z){M=t(t(expand.grid(rep(list(-1:1),27))))
P=3^(26:0)
x=M[M%*%P==a,]
y=M[M%*%P==b,]
k=sign(x+y)
switch(z+2,x*y,k*(-1)^(x+y+1),k*!x-y)%*%P}

Essayez-le en ligne!

Calcule toutes les combinaisons de trits et sélectionne la bonne. Cela provoquera en fait une erreur de mémoire 27, car il 3^27s'agit d'un nombre assez important, mais cela fonctionnerait en théorie. Le lien TIO ne 11prend en charge que les entiers trit; Je ne sais pas à quel moment cela arrive à expiration ou des erreurs de mémoire en premier, et je ne veux pas que Dennis se fâche contre moi pour avoir abusé de TIO!

ancienne réponse, 170 octets

Celui-ci devrait fonctionner pour toutes les entrées, bien qu'avec seulement des entiers 32 bits, il y ait une possibilité d'imprécision car R les convertira automatiquement en double.

function(a,b,z){x=y={}
for(i in 0:26){x=c((D=c(0,1,-1))[a%%3+1],x)
y=c(D[b%%3+1],y)
a=(a+1)%/%3
b=(b+1)%/%3}
k=sign(x+y)
switch(z+2,x*y,k*(-1)^(x+y+1),k*!x-y)%*%3^(26:0)}

Essayez-le en ligne!

Prend -1pour A, 0pour Bet 1pour C.

Transmet l'approche dans cette réponse pour la conversion en ternaire équilibré, bien que puisque nous sommes garantis de ne pas avoir plus de 27 trits équilibrés, il est optimisé pour cela.

R , 160 octets

function(a,b,z){s=sample
x=y=rep(0,27)
P=3^(26:0)
while(x%*%P!=a&y%*%P!=b){x=s(-1:1,27,T)
y=s(-1:1,27,T)}
k=sign(x+y)
switch(z+2,x*y,k*(-1)^(x+y+1),k*!x-y)%*%P}

Essayez-le en ligne!

Cette version se terminera extrêmement lentement. Le bogosort de la conversion de base, cette fonction sélectionne au hasard les trits jusqu'à ce que d'une manière ou d'une autre (par 3^-54chance qu'il se produise) trouve les bons trits pour aet b, puis effectue l'opération requise. Cela ne se terminera pratiquement jamais.

Giuseppe
la source
Je pense que zse limite à {-1, 0, 1}.
Erik the Outgolfer
@EriktheOutgolfer Vous pouvez choisir les valeurs de zmappage pour chacune de ces trois opérations ternaires: [...]
Dennis
@Dennis zest soit -1, 0ou1 , et je pense que ce sont les « valeurs de z» étant appelées.
Erik the Outgolfer
C'est une différence de deux octets, à remplacer switch(z,...)par switch(z+2,...), ce serait donc un changement trivial.
Giuseppe
0

Gelée , 47 octets

×=
×
N0⁼?ȯȧ?"
ḃ3%3’
0Çḅ3$$⁼¥1#ḢÇṚµ€z0Z⁹+2¤ŀ/Ṛḅ3

Essayez-le en ligne!

Programme complet.

-1= C, 0= A, 1=B

Argument 1: [x, y]
Argument 3:z

Erik le Outgolfer
la source
Je ne pense pas que la prise xet yen ternaire équilibré soit autorisée: "x et y peuvent aller de -3812798742493 à 3812798742493 inclus. La première étape consiste à convertir x et y de décimal en ternaire équilibré."
Jonathan Allan
@JonathanAllan commentaire clarification
Erik the Outgolfer
... mais le format natif des nombres n'est pas équilibré ternaire dans Jelly.
Jonathan Allan
@JonathanAllan Oh, on dirait que j'ai mal compris ....
Erik the Outgolfer
@JonathanAllan eugh ... fixed
Erik the Outgolfer