Сбалансированная троичная логика

11

Сбалансированная троичная логика

Троичный обычно другое название для основания 3, то есть сказать, каждая цифра 0, 1или 2, и каждое место стоит в 3 раза больше, чем на следующем месте.

Сбалансированный троичный является модификацией троичного, который использует цифры -1, 0и 1. Это имеет то преимущество, что не нуждается в знаке. Каждое место по-прежнему стоит в 3 раза больше, чем следующее место. Первые несколько положительных целых чисел, следовательно [1], [1, -1], [1, 0], [1, 1], в [1, -1, -1]то время как первые отрицательные целые числа [-1], [-1, 1], [-1, 0], [-1, -1], [-1, 1, 1].

У вас есть три входа x, y, z. zили -1, 0или 1, в то время как xи yможет быть от -3812798742493до 3812798742493включительно.

Первым делом нужно перевести xи yиз десятичной в сбалансированную троичную форму. Это должно дать вам 27 тритов (терарных цифр). Затем вам нужно объединить триты из xи yв парах, используя троичную операцию, а затем преобразовать результат обратно в десятичную.

Вы можете выбрать, какие значения zотображаются на одну из этих трех троичных операций каждая:

  • A: Если дано два трита, если любой равен нулю, то результат равен нулю, в противном случае результат равен -1, если они разные, или 1, если они одинаковы.
  • B: Если дано два трита, если один из них равен нулю, то результатом является другой трит, в противном случае результат равен нулю, если они разные, или отрицание, если они одинаковы.
  • C: С учетом двух значений trit результат равен нулю, если они различны, или их значение, если они одинаковы.

Пример. Предположим, xесть 29и yесть 15. В сбалансированном троичном, они становятся [1, 0, 1, -1]и [1, -1, -1, 0]. (Остальные 23 нулевых тритов были опущены для краткости.) После каждой из соответствующих операций они становятся A: [1, 0, -1, 0], B: [-1, -1, 0, -1], C: [1, 0, 0, 0]. Преобразованы обратно в десятичные результаты 24, -37и, 27соответственно. Попробуйте следующую справочную реализацию для большего количества примеров:

Эталонная реализация следует приведенным выше шагам, но вы, конечно, можете использовать любой алгоритм, который дает те же результаты.

Это , поэтому выигрывает самая короткая программа или функция, которая не нарушает стандартные лазейки!

Нил
источник
2
Если собственный формат чисел является сбалансированным троичным (в отличие от двоичного), можем ли мы принимать его как входные данные обычным способом (что не приводит к преобразованию в сбалансированный троичный)?
wizzwizz4
2
связанные
Джузеппе
1
это zдолжен быть один из , -1,0,1или мы можем выбрать любые три последовательных и различных значений? Я выбрал 1,2,3в своем ответе, и есть некоторая путаница по этому поводу.
Джузеппе
2
@Giuseppe К сожалению, разрешены только сбалансированные троичные цифры.
Нил
2
Я читаю что-то вразрез ... Слишком много слов и нет формулы
RosLuP

Ответы:

2

Чисто , 231 ... 162 байта

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

Определяет функцию @, принимая три Intс и давая Int.
Операторы отображаются как 1 -> A, 0 -> B, -1 -> C.

Попробуйте онлайн!

Функция $складывает лямбду по [0..26]разрядам цифр в список троичных цифр. Он использует заголовок списка, который он выводит, чтобы сохранить текущую итоговую разницу от требуемого числа (именно поэтому он повторяется до возврата) и sign(2*t/3^p)определить текущую цифру для получения. Трюк со знаком эквивалентен if(abs(2*t)<3^p)0(sign t).

Οurous
источник
Я не знаю Clean, но я заинтригован тем, как ты превратился в сбалансированную троицу с $n(я думаю). Не могли бы вы добавить объяснение этому?
Джузеппе
@ Giuseppe Абсолютно, я добавлю объяснение сегодня, когда у меня будет время.
Οurous
@ Giuseppe это отвечает на ваш вопрос?
августа
Да! Это имеет смысл. Довольно умно!
Джузеппе
1

Желе , 39 байт

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

Полная программа принимает два аргумента, [x,y]и z
... где zэто , {A:-1, B:0, C:1}
который печатает результат

Попробуйте онлайн! Примечание: метод игры в гольф делает его медленным - эта измененная версия быстрее (регистрирует на 3, потолки и приращения перед каждым декартовым произведением)

Как?

×=       - 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
Джонатан Аллан
источник
Я не могу на всю жизнь читать языки игры в гольф, поэтому, когда вы говорите «медленно», насколько плохо сложность времени?
Οurous
Чтобы получить сбалансированную тройку N, он создает список всех (3 ^ n) списков абс (N) длины тритов (0, -1 и 1). Итак, O (3 ^ max (abs (X), abs (Y)))
Джонатан Аллан
Спасибо, и за объяснение, которое я вижу, вы добавили тоже!
Οurous
1
Также добавлена ​​более быстрая версия с использованием того же метода :)
Джонатан Аллан
1

R , 190 172 151 байт

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}

Попробуйте онлайн!

Вычисляет все комбинации тритов и выбирает правильную. Это на самом деле вызовет ошибку памяти 27, поскольку 3^27это довольно большое число, но теоретически это сработает. Ссылка TIO имеет только 11целочисленную поддержку trit; Я не уверен, в какой момент это время или ошибки памяти первыми, и я не хочу, чтобы Деннис разозлился на меня за злоупотребление TIO!

старый ответ, 170 байт

Это должно работать для всех входных данных, хотя только с 32-разрядными целыми числами есть вероятность неточности, поскольку R автоматически преобразует их в 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)}

Попробуйте онлайн!

Принимает -1за A, 0за Bи 1за C.

В этом ответе переносится подход к преобразованию в сбалансированный троичный, хотя, поскольку у нас гарантировано не более 27 сбалансированных тритов, он оптимизирован для этого.

R 160 байт

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}

Попробуйте онлайн!

Эта версия прекратит работу очень медленно. Богосорт базового преобразования, эта функция случайным образом выбирает триты, пока каким-то волшебным образом ( 3^-54вероятность того, что это произойдет) не найдет нужные триты для aи b, а затем выполнит требуемую операцию. Это в основном никогда не закончится.

Giuseppe
источник
Я думаю zограничен {-1, 0, 1}.
Эрик Outgolfer
@EriktheOutgolfer Вы можете выбрать, какие значения zсопоставлять с одной из этих трех троичных операций каждая: [...]
Деннис
@Dennis z- это или -1, 0или1 , и я думаю, что это «ценности z», на которые мы ссылаемся.
Эрик Outgolfer
Это двухбайтовая разница, заменяемая switch(z,...)на switch(z+2,...)так, что это было бы тривиальным изменением независимо.
Джузеппе
0

Желе , 47 байт

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

Попробуйте онлайн!

Полная программа.

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

Аргумент 1: [x, y]
Аргумент 3:z

Эрик Outgolfer
источник
Я не думаю, что принимать xи yв сбалансированной троичной форме разрешено: «x и y могут быть от -3812798742493 до 3812798742493 включительно. Первый шаг - преобразовать x и y из десятичной в сбалансированную троичную».
Джонатан Аллан
@JonathanAllan разъяснение комментария
Эрик Outgolfer
... но родной формат чисел не сбалансирован в троице в желе.
Джонатан Аллан
@JonathanAllan О, похоже, я неправильно понял ...
Эрик Игрок в гольф
@JonathanAllan eugh ... исправлено
Эрик Outgolfer