Lógica ternária equilibrada

11

Lógica ternária equilibrada

Ternário é normalmente um outro nome para a base 3, ou seja, cada dígito é 0, 1ou 2, e cada lugar vale 3 vezes mais do que o próximo lugar.

Ternário equilibrado é uma modificação do ternário que usa dígitos de -1, 0e 1. Isso tem a vantagem de não precisar de um sinal. Cada local ainda vale 3 vezes mais que o próximo. Os primeiros números inteiros positivos são, portanto [1], [1, -1], [1, 0], [1, 1], [1, -1, -1]enquanto os primeiros números inteiros negativos são [-1], [-1, 1], [-1, 0], [-1, -1], [-1, 1, 1].

Você tem três entradas x, y, z. zou é -1, 0ou 1, ao mesmo tempo xe ypode ser de -3812798742493até 3812798742493inclusiva.

O primeiro passo é converter xe yde decimal em ternário equilibrado. Isso deve fornecer 27 trits (dígitos iniciais). Você precisa combinar os trits de xe yem pares usando uma operação ternária e depois converter o resultado novamente em decimal.

Você pode escolher quais valores do zmapa para uma dessas três operações ternárias cada:

  • A: Dados dois trits, se um for zero, o resultado será zero; caso contrário, o resultado será -1 se forem diferentes ou 1 se forem iguais.
  • B: Dados dois trits, se um for zero, o resultado será o outro trit; caso contrário, o resultado será zero se forem diferentes ou a negação se forem iguais.
  • C: Dados dois trits, o resultado será zero se eles forem diferentes ou seu valor se forem iguais.

Exemplo. Suponha que xseja 29e yseja 15. No ternário equilibrado, eles se tornam [1, 0, 1, -1]e [1, -1, -1, 0]. (Os 23 trits zero restantes foram omitidos por questões de brevidade.) Após cada uma das respectivas operações, eles se tornam A: [1, 0, -1, 0], B: [-1, -1, 0, -1], C: [1, 0, 0, 0]. Volta convertido para decimal, os resultados são 24, -37e 27respectivamente. Tente a seguinte implementação de referência para obter mais exemplos:

A implementação de referência segue as etapas fornecidas acima, mas você é livre para usar qualquer algoritmo que produz os mesmos resultados.

Isso é , então o programa ou função mais curto que não viola nenhuma brecha padrão ganha!

Neil
fonte
2
Se o formato nativo para números é ternário balanceado (em oposição a binário), podemos tomá-lo como entrada da maneira usual (o que resulta em nenhuma conversão para ternário balanceado)?
Wizzwizz4
2
relacionado
Giuseppe
1
não ztem que ser um dos -1,0,1ou podemos escolher quaisquer três valores consistentes e distintas? Eu selecionei 1,2,3na minha resposta, e há alguma confusão sobre isso.
Giuseppe
2
@ Giuseppe Desculpe, apenas dígitos ternários balanceados são permitidos.
Neil
2
Eu li algo trasverse ... Demasiado palavras e nenhuma fórmula
RosLuP

Respostas:

2

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

Define a função @, obtendo três se Intdando um Int.
Operadores mapeiam como 1 -> A, 0 -> B, -1 -> C.

Experimente online!

A função $dobra uma lambda sobre os dígitos [0..26], em uma lista de dígitos ternários. Ele usa o cabeçalho da lista que gera para manter uma diferença total atual do número necessário (e é por isso que é seguido antes de retornar) e sign(2*t/3^p)para determinar o dígito atual a ser produzido. O truque de sinal é equivalente a if(abs(2*t)<3^p)0(sign t).

Furioso
fonte
Não conheço o Clean, mas estou intrigado com a forma como você se converteu em ternário equilibrado com $n(eu acho). Você poderia adicionar uma explicação para isso?
Giuseppe
@ Giuseppe Absolutamente, vou adicionar uma explicação hoje quando tiver tempo.
Οurous
@Giuseppe, isso responde à sua pergunta?
Οurous
Sim! Isso faz sentido. Bastante inteligente!
Giuseppe
1

Geléia , 39 bytes

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

Um programa completo com dois argumentos [x,y], e z
... onde zé {A:-1, B:0, C:1}
que imprime o resultado

Experimente online! Nota: o método golfed torna lento - esta versão alterada é mais rápida (registros em 3, tetos e incrementos antes de cada produto cartesiano)

Quão?

×=       - 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
fonte
Eu não consigo ler idiomas de golfe, então quando você diz "devagar", quão ruim é a complexidade do tempo?
Οurous
Para obter o ternário balanceado de N, ele cria uma lista de todas as (3 ^ n) listas abs (N) de trits (0, -1 e 1). Assim, O (3 ^ max (abs (x), ABS (Y)))
Jonathan Allan
Obrigado, e pela explicação, vejo que você adicionou também!
Οurous
1
Também foi adicionado uma versão mais rápida usando o mesmo método :)
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}

Experimente online!

Calcula todas as combinações de trits e seleciona a correta. Na verdade, ele gera um erro de memória 27, já que 3^27é um número um tanto grande, mas teoricamente funcionaria. O link TIO possui apenas 11suporte a trit inteiro; Não tenho certeza em que ponto o tempo limite deve exceder ou os erros de memória primeiro e não quero que Dennis fique bravo comigo por abusar do TIO!

resposta antiga, 170 bytes

Este deve funcionar para todas as entradas, embora com apenas números inteiros de 32 bits, exista a possibilidade de imprecisão, pois o R as converterá automaticamente 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)}

Experimente online!

Toma -1para A, 0de Be 1para C.

Portos a abordagem nesta resposta para converter em ternário equilibrado, embora, como é garantido que não tenha mais de 27 trits equilibrados, ele é otimizado para isso.

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}

Experimente online!

Esta versão terminará extremamente lentamente. O bogoort da conversão de base, essa função seleciona aleatoriamente trits até que de alguma forma magicamente ( 3^-54chance disso ocorra) encontre os trits corretos para ae b, e depois faça a operação necessária. Isso basicamente nunca termina.

Giuseppe
fonte
Eu acho que zé restrito a {-1, 0, 1}.
Erik the Outgolfer
@EriktheOutgolfer Você pode escolher quais valores do zmapa para uma dessas três operações ternárias cada: [...]
Dennis
@Dennis zé ou -1, 0ou1 , e acho que esses são os "valores de z" que estão sendo mencionados.
Erik the Outgolfer
É uma diferença de dois bytes, substituindo- switch(z,...)a switch(z+2,...)por isso seria uma mudança trivial, independentemente.
Giuseppe
0

Geléia , 47 bytes

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

Experimente online!

Programa completo.

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

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

Erik, o Outgolfer
fonte
Eu não acho que aceitar xe yternário balanceado é permitido: "x e y podem ser de -3812798742493 a 3812798742493, inclusive. O primeiro passo é converter x e y de decimal em ternário balanceado".
Jonathan Allan
@JonathanAllan esclarecimento de comentários
Erik the Outgolfer
... mas o formato nativo para números não é ternário balanceado no Jelly.
Jonathan Allan
@ JonathanAllan Oh, parece que eu entendi mal ...
Erik the Outgolfer
@JonathanAllan eugh ... fixado
Erik the Outgolfer