Добавить и умножить недоумение номера

16

В сплит-комплексные числа , также известный как «озадачить чисел» подобны комплексных чисел. Но вместо этого i^2 = -1мы имеем j^2 = 1; j != +/-1. Каждый номер принимает форму z = x + j*y.

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

Вот несколько примеров для вашего удовольствия от просмотра:

6 * 9 = 54            // real numbers still act normally
5 + -7 = -2
j*1 + j*1 = j*2           // two `j`s added together make a j*2
7 * j*1 = j*7           // multiplication is commutative & associative
j*1 + 2 = 2+j*1           // like oil and water, "combine" to form a split-complex number
j*1 + j*-3 = j*-2          // seems okay so far
j*j*1 = j*-1*j*-1 = 1     // kinda sketchy, but such is its inherent nature
j*j*-1 = j*-1*j*1 = -1  
(2+j*3)+(4+j*7) = 6+j*10  // combine like terms
7 * (2+j*3) = 14+j*21 // distributive property
j * (2+j*3) = (j*2) + (j*j*3) = 3+j*2   // since j^2 = 1, multiplying my j "swaps" the coefficients
(2+j*3)*(4+j*7) = (2*4)+(2*j*7)+(j*3*4)+(j*3*j*7) = 8+j*14+j*12+21 = 29+j*26 // a complete multiplication

Вызов

Цель этой задачи состоит в том, чтобы оценить выражение с комплексными числами.

Это код-гольф, побеждает меньше всего байтов.

вход

Ввод будет отдельной строкой, содержащей только символы +*()-, цифры 0123456789и букву j, с необязательной новой строкой. Эта строка представляет выражение с использованием инфиксной нотации и приоритета оператора (умножение перед сложением с группировкой в ​​скобках).

  • Символ -всегда будет представлять отрицание, а не вычитание. Если вы хотите, вы можете заменить -либо на, _либо~ для простоты ввода / вывода.
  • Круглые скобки могут быть вложены до трех раз для обозначения группировки: (1+(1+(1)))
  • Буква jникогда не будет иметь префикс с отрицанием и всегда будет сопровождаться *.
  • Круглым скобкам не будет предшествовать отрицание -(7), а вместо этого-1*(j*5+2)
  • Там никогда не будет неявных операций. Все умножение будет выражаться как (7)*7вместо (7)7, так и j*5вместо j5.
  • Нет ведущих нулей.

Выход

Вывод будет в виде X+j*Y, где X и Y могут быть любым целым числом. Если целое число отрицательное, оно должно начинаться со знака отрицания.

Дополнительные ограничения

Хотя я не знаю ни одного языка с нативной поддержкой, встроенные модули, работающие с комплексными числами, запрещены. Обычные комплексные числа являются честной игрой.

Тестовые случаи

Аналогичен приведенным выше примерам, но приведен в порядок. Ввод в одну строку и вывод строки ниже.

(2+j*3)+(4+j*7)
6+j*10

(2+j*3)*(4+j*7)
29+j*26

(-5+j*1+j*2+2)*(4+j*7)
9+j*-9

(1+j*-1)*(1+j*1)
0+j*0 // this is why division does not exist.

j*((j*-1)+2)
-1+j*2

(2+(5+-1*(j*1))+2)
9+j*-1
PhiNotPi
источник

Ответы:

13

Python 2, 62 байта

def f(s):b,a=[eval(s)/2.for j in-1,1];print'%d+j*%d'%(a+b,a-b)

Мы просто оцениваем выражение sс помощью j=1и j=-1и выводим половину их суммы и половину их разности как коэффициенты 1и j.

Это работает, потому что оба j=1и j=-1удовлетворяют определяющему уравнению, определяющему уравнение j*j==1. Таким образом, исходные и упрощенные выражения должны быть равны для обоих этих значений. Упрощенное выражение является линейным, поэтому это дает два линейных уравнения с двумя неизвестными:

x + 1*y  = s(1)  = 2*a
x - 1*y  = s(-1) = 2*b

которая решается путем x=a+b, y=a-b.

XNOR
источник
Язык с матричными операциями также может оценивать выражение с j=[0 1; 1 0]коэффициентами из верхней строки и считывать их.
xnor
2

Python 2, 258

class c(complex):__mul__=lambda s,o:c(s.real*o.real+s.imag*o.imag,s.real*o.imag+s.imag*o.real);__add__=lambda s,o:c(sum(map(complex,[s,o])))
import re
r=eval(re.sub("j","c(0,1)",re.sub(r"(-?\d+)",r"c(\1)",raw_input())))
print`int(r.real)`+"+j*"+`int(r.imag)`

Вероятно, это не лучший подход, но это был первый раз, когда ООП выглядело как сносная идея в Python для кода гольф, так почему бы и нет?

Создает класс, cкоторый наследуется от сложного, но выполняет другую mulоперацию. addОперация также изменяется таким образом , что он возвращает объект типа cи не complexтакое поведение необходимо предотвратить случай (a + b) * (c + d)делать комплексное умножение вместо этого специального вида.

Входная строка затем преобразуется в строку, которая может быть оценена естественным образом с помощью Python. Это делается путем изменения каждого числа в, c(number)а затем каждый jв c(0,1).

Попробуйте онлайн или запустите Test Suite

FryAmTheEggman
источник
1

GAP , 38 байт

j:=X(Integers,"j");f:=t->t mod(j^2-1);

Первый jопределяется как неопределенный, поэтому мы можем создавать многочлены в j. Чтобы получить соответствующее запутанное число, мы уменьшаем (т.е. берем остаток от полиномиального деления) на j^2-1. Это дает линейный (или постоянный) член, и мы можем положиться на способность GAP выводить полиномы.

Примеры:

gap> f((2+j*3)+(4+j*7));
10*j+6
gap> f((1+j*-1)*(1+j*1));
0

Предостережение: 1. Это не принимает строку как ввод, но реальный термин на языке GAP. Чтобы исправить, я мог бы использовать EvalString. 2. Вывод хороший и четкий, но не совсем такой, как указано: порядок изменен, а ненужные нули подавлены. Я думаю и надеюсь, что это все еще в духе задачи, в противном случае, я думаю, мне было бы лучше использовать матричный подход @ xnor.

Кристиан Сиверс
источник
1
Mathematica PolynomialMod[#,j^2-1]&имеет схожие свойства. В самом деле, если мы никогда не умножаем больше двух ошибочных чисел (как в тестовых случаях), то Expand@#/.j^2->1достаточно.
Грег Мартин
Точно так же t->t%(j^2-1)в пари / гп.
алефальфа
1

Аксиома, 20 42 байта

f(x,n)==x^(n rem 2);m:=rule('j^n==f('j,n))

предыдущее решение имеет проблему, если n<0в, j^n но это кажется более солидным, и хорошо посоветуйте, где что-то не так, даже если совершенство будет возвращать пример j ^ 1.2 или j ^ sqrt (-1) то же выражение не оценивать

(9) -> f(x,n)==x^(n rem 2);m:=rule('j^n==f('j,n))
         n
   (9)  j  == 'f(j,n)
                    Type: RewriteRule(Integer,Integer,Expression Integer)
(10) -> [m((2+j*3)+(4+j*7)), m((2+j*3)*(4+j*7)), m((-5+j*1+j*2+2)*(4+j*7))]
   (10)  [10j + 6,26j + 29,- 9j + 9]
                                            Type: List Expression Integer
(11) -> [m((1+j*-1)*(1+j*1)), m(j*((j*-1)+2)), m(2+(5+-1*(j*1))+2)]
   (11)  [0,2j - 1,- j + 9]
                                            Type: List Expression Integer
(12) -> [m(j*j*j*j),m(j*j*j),m(j^200)]
   (12)  [1,j,1]
                                            Type: List Expression Integer
(13) -> [m(j^0),m(j^-1),m(j^-2), m(j^-3)]
            1   1
   (13)  [1,-,1,-]
            j   j
                                            Type: List Expression Integer
(14) -> m(j^(3.4))
   There are no library operations named m
      Use HyperDoc Browse or issue

если я не следую некоторому закону вопроса: скажи мне это, и я добавлю «неконкурентоспособен». Я имею в виду как одну аксиому для упрощения формулы

RosLuP
источник
0

Пакет, 52 байта

@set/aj=1,a=%1,j=-1,a-=b=(a-(%1))/2
@echo %a%+j*%b%

Увидев замечательный ответ @ xnor, я почувствовал необходимость перенести его.

Нил
источник