Zrównoważona logika trójskładnikowa

11

Zrównoważona logika trójskładnikowa

Trójargumentowy jest zwykle inna nazwa podstawy 3, to znaczy, każda cyfra jest 0, 1lub 2, a każde miejsce jest warte 3 razy tyle, ile następnej kolejności.

Zrównoważone trójskładnikowe jest modyfikacją trójskładnikowego wykorzystującą cyfry -1, 0i 1. Ma to tę zaletę, że nie wymaga znaku. Każde miejsce jest nadal warte 3 razy więcej niż następne. Pierwszych kilka całkowite dodatnie są zatem [1], [1, -1], [1, 0], [1, 1], [1, -1, -1]podczas gdy pierwsze kilka negatywnych całkowitymi są [-1], [-1, 1], [-1, 0], [-1, -1], [-1, 1, 1].

Masz trzy wejścia x, y, z. zjest albo -1, 0albo 1, podczas gdy xi ymoże być od -3812798742493do 3812798742493włącznie.

Pierwszym krokiem jest przekształcenie xi yod dziesiętnej na system trójkowy zrównoważony. To powinno dać ci 27 tritów (TeRnary digITS). Następnie trzeba połączyć z trits xi yparami przy użyciu potrójny operację, a następnie przekonwertować wynik do tyłu po przecinku.

Możesz wybrać, które wartości zmapy dla jednej z tych trzech operacji trójskładnikowych każda:

  • A: Biorąc pod uwagę dwie tryty, jeśli jeden z nich jest równy zero, to wynik wynosi zero, w przeciwnym razie wynik wynosi -1, jeśli są różne lub 1, jeśli są takie same.
  • B: Biorąc pod uwagę dwie trity, jeśli jedna z nich jest równa zero, to wynikiem jest druga trit, w przeciwnym razie wynik wynosi zero, jeśli są różne, lub negacja, jeśli są takie same.
  • C: Biorąc pod uwagę dwie tryty, wynik wynosi zero, jeśli są różne, lub ich wartość, jeśli są takie same.

Przykład. Załóżmy, że xjest 29i yjest 15. W zrównoważonej trójce stają się [1, 0, 1, -1]i [1, -1, -1, 0]. (Pozostałe 23 tryty zerowe zostały pominięte ze względu na zwięzłość.) Po każdej z odpowiednich operacji stają się one A: [1, 0, -1, 0], B: [-1, -1, 0, -1], C: [1, 0, 0, 0]. Przekształcany z powrotem na dziesiętne wyniki są 24, -37i 27odpowiednio. Wypróbuj następującą implementację referencyjną, aby uzyskać więcej przykładów:

Implementacja referencyjna postępuje zgodnie z krokami podanymi powyżej, ale oczywiście możesz swobodnie korzystać z dowolnego algorytmu, który daje takie same wyniki.

To jest , więc wygrywa najkrótszy program lub funkcja, która nie narusza żadnych standardowych luk!

Neil
źródło
2
Jeśli natywny format liczb jest zbalansowany trójskładnikowy (w przeciwieństwie do binarnego), czy możemy przyjmować go jako dane wejściowe w zwykły sposób (co powoduje brak konwersji na zrównoważony trójskładnikowy)?
wizzwizz4
2
powiązane
Giuseppe,
1
czy zmusi to być jedna z nich, -1,0,1czy możemy wybrać dowolne trzy spójne i odrębne wartości? Wybrałem 1,2,3w swojej odpowiedzi i jest w tym trochę zamieszania.
Giuseppe,
2
@Giuseppe Przepraszamy, dozwolone są tylko zrównoważone cyfry trójskładnikowe.
Neil
2
Czytam coś w poprzek ... Za dużo słów i brak formuły
RosLuP

Odpowiedzi:

2

Czysty , 231 ... 162 bajtów

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

Definiuje funkcję @, biorąc trzy Intsi dając an Int.
Mapa operatorów jako 1 -> A, 0 -> B, -1 -> C.

Wypróbuj online!

Funkcja $składa lambda nad miejscami cyfr [0..26], na listę cyfr trójskładnikowych. Wykorzystuje nagłówek listy, którą daje, aby zachować bieżącą całkowitą różnicę w stosunku do wymaganej liczby (dlatego jest ona dostosowywana przed zwróceniem) i sign(2*t/3^p)aby określić bieżącą cyfrę do uzyskania. Trik znakowy jest równoważny if(abs(2*t)<3^p)0(sign t).

Obrzydliwe
źródło
Nie znam Clean, ale jestem zaintrygowany tym, jak przeszedłeś na zbalansowane trójskładniki za pomocą $n(tak myślę). Czy możesz dodać wyjaśnienie?
Giuseppe,
@Giuseppe Oczywiście, dodam dzisiaj wyjaśnienie, kiedy będę miał czas.
Οurous
@Giuseppe, czy to odpowiada na twoje pytanie?
Οurous
Tak! To ma sens. Całkiem sprytne!
Giuseppe,
1

Galaretka , 39 bajtów

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

Pełny program pobierający dwa argumenty [x,y]i z
... gdzie zznajduje {A:-1, B:0, C:1}
się wynik

Wypróbuj online! Uwaga: metoda gry w golfa spowalnia - ta zmieniona wersja jest szybsza (loguje się o 3, pułapy i przyrosty przed każdym produktem kartezjańskim)

W jaki sposób?

×=       - 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
źródło
Nie umiem czytać języków golfowych przez całe życie, więc kiedy mówisz „powoli”, jak źle jest złożoność czasu?
Οurous
Aby uzyskać zrównoważony trójskładnik N, tworzy listę wszystkich (3 ^ n) długości abs (N) list tritów (0, -1 i 1). Więc O (3 ^ max (abs (X), abs (Y)))
Jonathan Allan
Dzięki, a dla wyjaśnienia widzę, że ty również dodałeś!
Οurous
1
Dodano także szybszą wersję przy użyciu tej samej metody :)
Jonathan Allan
1

R , 190 172 151 bajtów

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}

Wypróbuj online!

Oblicza wszystkie kombinacje tritów i wybiera właściwą. W rzeczywistości spowoduje to błąd pamięci 27, ponieważ 3^27jest to nieco duża liczba, ale teoretycznie działałoby. Łącze TIO ma tylko 11obsługę liczb całkowitych trit; Nie jestem pewien, w którym momencie upłynie limit czasu lub błędy pamięci i nie chcę, żeby Dennis się na mnie wściekł za nadużywanie TIO!

stara odpowiedź, 170 bajtów

Ten powinien działać na wszystkich wejściach, choć przy 32-bitowych liczbach całkowitych istnieje możliwość niedokładności, ponieważ R automatycznie je przekonwertuje 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)}

Wypróbuj online!

Trwa -1za A, 0za Bi 1za C.

Podaje podejście zawarte w tej odpowiedzi do przejścia na zbalansowane trójskładnikowe, chociaż ponieważ gwarantujemy, że nie będziemy mieć więcej niż 27 zrównoważonych tritów, jest to zoptymalizowane do tego.

R , 160 bajtów

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}

Wypróbuj online!

Ta wersja kończy się bardzo powoli. Bogosort konwersji bazy, ta funkcja losowo wybiera trits, aż w jakiś sposób magicznie ( 3^-54szansa na wystąpienie) znajdzie odpowiednie trits dla ai b, a następnie wykona wymaganą operację. To w zasadzie nigdy się nie skończy.

Giuseppe
źródło
Myślę, że zjest ograniczony do {-1, 0, 1}.
Erik the Outgolfer
@EriktheOutgolfer Możesz wybrać, które wartości zmapy do jednej z tych trzech operacji trójskładnikowych każda: [...]
Dennis
@Dennis zjest albo -1, 0albo1 myślę, że są to „wartości z”, o których mowa.
Erik the Outgolfer
Jest to dwubajtowa różnica, zastępując switch(z,...)ją, switch(z+2,...)więc niezależnie od tego byłaby to banalna zmiana.
Giuseppe,
0

Galaretka , 47 bajtów

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

Wypróbuj online!

Pełny program

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

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

Erik the Outgolfer
źródło
Nie sądzę, aby wzięcie xi yzbalansowanie trójskładnika było dozwolone: ​​„xiy mogą być od -3812798742493 do 3812798742493 włącznie. Pierwszym krokiem jest konwersja xiy z liczb dziesiętnych na zrównoważony trójskładnik”.
Jonathan Allan
@JonathanAllan wyjaśnienie komentarza
Erik the Outgolfer
... ale natywny format liczb nie jest zrównoważony trójskładnikowy w galarecie.
Jonathan Allan
@JonathanAllan Och, wygląda na to, że źle zrozumiałem ....
Erik the Outgolfer
@JonathanAllan eugh ... naprawiono
Erik the Outgolfer