Ausgewogene ternäre Logik

11

Ausgewogene ternäre Logik

Ternary ist normalerweise ein anderer Name für Basis 3, das heißt, jede Ziffer ist 0, 1oder 2, und jeder Ort ist im Wert von 3 - mal so viel wie der nächsten Ort.

Balanced ternäre ist eine Modifikation der ternären , die verwendeten Ziffern -1, 0und 1. Dies hat den Vorteil, dass kein Schild benötigt wird. Jeder Ort ist immer noch dreimal so viel wert wie der nächste Ort. Die ersten paar positive ganze Zahlen sind daher [1], [1, -1], [1, 0], [1, 1], [1, -1, -1]während die ersten paar negative ganze Zahlen sind [-1], [-1, 1], [-1, 0], [-1, -1], [-1, 1, 1].

Sie haben drei Eingänge x, y, z. zentweder -1, 0oder 1, während xund yaus sein kann , -3812798742493um 3812798742493inklusive.

Der erste Schritt ist die Konvertierung xund yvon dezimal nach ausgeglichen ternär. Dies sollte Ihnen 27 Triten (TeRnary-Ziffern) geben. Sie müssen dann die Triten von xund ypaarweise mit einer ternären Operation kombinieren und das Ergebnis dann wieder in eine Dezimalzahl konvertieren.

Sie können auswählen, welche Werte der zKarte jeweils einer dieser drei ternären Operationen zugeordnet werden sollen:

  • A: Bei zwei Triten ist das Ergebnis Null, wenn entweder Null ist, andernfalls ist das Ergebnis -1, wenn sie unterschiedlich sind, oder 1, wenn sie gleich sind.
  • B: Bei zwei Triten ist, wenn einer von beiden Null ist, das Ergebnis der andere Trit, andernfalls ist das Ergebnis Null, wenn sie unterschiedlich sind, oder die Negation, wenn sie gleich sind.
  • C: Bei zwei Triten ist das Ergebnis Null, wenn sie unterschiedlich sind, oder ihr Wert, wenn sie gleich sind.

Beispiel. Angenommen, xist 29und yist 15. Im ausgeglichenen ternären Zustand werden diese [1, 0, 1, -1]und [1, -1, -1, 0]. (Die verbleibenden 23 Nulltrits wurden der Kürze halber weggelassen.) Nach jeder der jeweiligen Operationen werden sie A: [1, 0, -1, 0], B: [-1, -1, 0, -1], C: [1, 0, 0, 0]. Konvertieren zurück in Dezimalzahlen die Ergebnisse sind 24, -37und 27jeweils. Versuchen Sie die folgende Referenzimplementierung für weitere Beispiele:

Die Referenzimplementierung folgt den oben angegebenen Schritten, aber Sie können natürlich jeden Algorithmus verwenden, der dieselben Ergebnisse liefert.

Dies ist , also gewinnt das kürzeste Programm oder die kürzeste Funktion, die keine Standardlücken verletzt!

Neil
quelle
2
Wenn das native Format für Zahlen ternär ausgeglichen ist (im Gegensatz zu binär), dürfen wir es dann wie gewohnt als Eingabe verwenden (was zu keiner Konvertierung in ternär ausgeglichen führt)?
wizzwizz4
2
verwandt
Giuseppe
1
muss zeiner von -1,0,1drei konsistenten und unterschiedlichen Werten sein oder können wir diese auswählen? Ich habe 1,2,3in meiner Antwort ausgewählt, und es gibt einige Verwirrung darüber.
Giuseppe
2
@ Giuseppe Sorry, nur ausgeglichene ternäre Ziffern sind erlaubt.
Neil
2
Ich habe etwas Gegenteiliges gelesen ... Zu viele Wörter und keine Formel
RosLuP

Antworten:

2

Sauber , 231 ... 162 Bytes

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

Definiert die Funktion @, nimmt drei IntSekunden und gibt eine Int.
Operatoren kartieren als 1 -> A, 0 -> B, -1 -> C.

Probieren Sie es online aus!

Die Funktion $faltet ein Lambda über die Ziffernstellen [0..26]in eine Liste ternärer Ziffern. Es verwendet den Kopf der Liste, die es ergibt, um eine aktuelle Gesamtdifferenz von der erforderlichen Anzahl beizubehalten (weshalb es vor der Rückgabe beschnitten wird) und sign(2*t/3^p)um die aktuelle zu ergebende Ziffer zu bestimmen. Der Vorzeichentrick entspricht if(abs(2*t)<3^p)0(sign t).

Οurous
quelle
Ich kenne Clean nicht, aber ich bin fasziniert davon, wie Sie mit $n(glaube ich) zu einem ausgeglichenen Ternär konvertiert sind . Könnten Sie eine Erklärung dafür hinzufügen?
Giuseppe
@ Giuseppe Auf jeden Fall werde ich heute eine Erklärung hinzufügen, wenn ich Zeit habe.
ousurous
@ Giuseppe beantwortet das deine Frage?
ousurous
Ja! Das macht Sinn. Ziemlich schlau!
Giuseppe
1

Gelee , 39 Bytes

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

Ein vollständiges Programm mit zwei Argumenten [x,y]und z
... wo zist {A:-1, B:0, C:1}
das, das das Ergebnis druckt

Probieren Sie es online aus! Hinweis: Die Golfmethode macht es langsam - diese geänderte Version ist schneller (Protokolle um 3, Decken und Inkremente vor jedem kartesischen Produkt)

Wie?

×=       - 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
quelle
Ich kann für mein ganzes Leben keine Golfsprachen lesen. Wenn Sie also "langsam" sagen, wie schlimm ist die zeitliche Komplexität?
ousurous
Um das ausgeglichene Ternär von N zu erhalten, wird eine Liste aller (3 ^ n) Abs (N) -Listen mit Triten (0, -1 und 1) erstellt. Also O (3 ^ max (abs (X), abs (Y)))
Jonathan Allan
Danke, und für die Erklärung, die ich sehe, haben Sie auch hinzugefügt!
ousurous
1
Fügte auch eine schnellere Version mit der gleichen Methode hinzu :)
Jonathan Allan
1

R , 190 172 151 Bytes

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}

Probieren Sie es online aus!

Berechnet alle Kombinationen von Trits und wählt die richtige aus. Es wird tatsächlich einen Speicherfehler mit werfen 27, da 3^27es sich um eine etwas große Zahl handelt, aber es würde theoretisch funktionieren. Die TIO-Verbindung unterstützt nur 11ganzzahlige Tits. Ich bin mir nicht sicher, zu welchem ​​Zeitpunkt eine Zeitüberschreitung oder Speicherfehler auftreten, und ich möchte nicht, dass Dennis sauer auf mich wird, weil er TIO missbraucht hat!

alte Antwort, 170 Bytes

Dieser sollte für alle Eingänge funktionieren, obwohl bei nur 32-Bit-Ganzzahlen die Möglichkeit einer Ungenauigkeit besteht, da R sie automatisch in konvertiert 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)}

Probieren Sie es online aus!

Nimmt -1für A, 0für Bund 1für C.

Enthält den Ansatz in dieser Antwort für die Konvertierung in ein ausgeglichenes ternäres System. Da wir jedoch garantiert nicht mehr als 27 ausgeglichene Tits haben, ist es dafür optimiert.

R , 160 Bytes

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}

Probieren Sie es online aus!

Diese Version wird extrem langsam beendet. Diese Funktion ist ein Trottel der Basiskonvertierung und wählt zufällig Trits aus, bis sie auf magische Weise ( 3^-54Wahrscheinlichkeit ihres Auftretens) die richtigen Trits für aund bfindet und dann die erforderliche Operation ausführt . Dies wird im Grunde nie enden.

Giuseppe
quelle
Ich denke zist beschränkt auf {-1, 0, 1}.
Erik der Outgolfer
@EriktheOutgolfer Sie können auswählen, welche Werte der zKarte jeweils einer dieser drei ternären Operationen zugeordnet werden sollen: [...]
Dennis
@Dennis zist entweder -1, 0oder1 , und ich denke, das sind die "Werte von z", auf die Bezug genommen wird.
Erik der Outgolfer
Es ist eine Zwei-Byte - Differenz, ersetzt switch(z,...)mit , switch(z+2,...)so dass es unabhängig eine triviale Änderung wäre.
Giuseppe
0

Gelee , 47 Bytes

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

Probieren Sie es online aus!

Volles Programm.

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

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

Erik der Outgolfer
quelle
Ich denke nicht, dass es erlaubt ist , xund yin ausgeglichenem ternär zu nehmen: "x und y können von -3812798742493 bis einschließlich 3812798742493 sein. Der erste Schritt besteht darin, x und y von dezimal in ausgeglichenes ternär umzuwandeln."
Jonathan Allan
@ JonathanAllan Kommentar Klarstellung
Erik der Outgolfer
... aber das native Format für Zahlen ist in Jelly nicht ternär ausgeglichen.
Jonathan Allan
@ JonathanAllan Oh, sieht aus wie ich falsch verstanden habe ...
Erik der Outgolfer
@ JonathanAllan eugh ... behoben
Erik der Outgolfer