Dodaj i pomnóż kłopotliwe liczby

16

Te numery Split-kompleks , znany również jako „numerów perplex” są podobne do liczb zespolonych. Zamiast tego i^2 = -1mamy j^2 = 1; j != +/-1. Każda liczba ma postać z = x + j*y.

W jednej próbie ograniczenia złożoności tego wyzwania użyję tego symbolu -do przedstawienia negacji, ponieważ nie będzie żadnego odejmowania.

Oto kilka przykładów przyjemności oglądania:

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

Wyzwanie

Celem tego wyzwania jest ocena wyrażenia o liczbach zespolonych.

To jest golf golfowy, wygrywa najmniej bajtów.

Wejście

Wprowadzony zostanie pojedynczy wiersz zawierający tylko symbole +*()-, cyfry 0123456789i literę j, z opcjonalnym znakiem nowej linii. Ten ciąg reprezentuje wyrażenie, używając notacji infiksowej i pierwszeństwa operatora (mnożenie przed dodaniem, z grupowaniem w nawiasach).

  • Symbol -zawsze będzie reprezentował negację, nigdy odejmowanie. Jeśli chcesz, możesz zastąpić -jedną z nich _lub~ dla łatwości we / wy.
  • Nawiasy można zagnieżdżać maksymalnie trzy razy, aby wskazać grupowanie: (1+(1+(1)))
  • List jnigdy nie będzie poprzedzony zaprzeczeniem i zawsze będzie po nim następował *.
  • Nawiasy nie będą poprzedzone zaprzeczeniem -(7), ale zamiast tego-1*(j*5+2)
  • Nigdy nie będzie operacji niejawnych. Wszelkie pomnożenie będzie wyrażone jako (7)*7zamiast (7)7i jako j*5zamiast j5.
  • Brak wiodących zer.

Wynik

Dane wyjściowe będą miały postać X+j*Y, gdzie X i Y mogą być dowolną liczbą całkowitą. Jeśli liczba całkowita jest ujemna, powinna być poprzedzona znakiem negacji.

Dodatkowe ograniczenia

Chociaż nie znam żadnego języka z natywną obsługą, wbudowane funkcje dotyczące liczb zespolonych są zabronione. Regularne liczby zespolone są uczciwą grą.

Przypadki testowe

Podobne do powyższych przykładów, ale uporządkowane. Wprowadź jedną linię i wyślij linię poniżej.

(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
źródło

Odpowiedzi:

13

Python 2, 62 bajty

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

Po prostu oceniamy wyrażenie za spomocą j=1i j=-1, i wyprowadzamy połowę ich sumy i połowę ich różnicy jako współczynniki 1i j.

Działa to, ponieważ oba spełniają j=1i j=-1spełniają równanie definiujące równanie definiujące j*j==1. Tak więc oryginalne i uproszczone wyrażenia muszą być równe dla obu tych wartości. Uproszczone wyrażenie jest liniowe, więc daje dwa równania liniowe w dwóch niewiadomych:

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

który rozwiązuje x=a+b, y=a-b.

xnor
źródło
Język z operacjami macierzowymi może również oceniać wyrażenie za pomocą j=[0 1; 1 0]i odczytywać współczynniki z górnego rzędu.
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)`

Prawdopodobnie nie jest to najlepsze podejście, ale po raz pierwszy OOP wyglądał jak zadowalający pomysł w Pythonie na golfa kodu, więc dlaczego nie?

Tworzy klasę, cktóra dziedziczy ze złożonego, ale ma inną muloperację. addOperacja jest również zmieniona tak, że zwraca obiekt typu ci niecomplex , to zachowanie jest niezbędne, aby zapobiec przypadek (a + b) * (c + d)robi złożonego mnożenia zamiast tego szczególnego rodzaju.

Łańcuch wejściowy jest następnie konwertowany na łańcuch, który może być oceniany naturalnie przez python. Robi to, zmieniając każdą liczbę na, c(number)a następnie każdąj na c(0,1).

Wypróbuj online lub uruchom pakiet testowy

FryAmTheEggman
źródło
1

GAP , 38 bajtów

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

Pierwszy jjest zdefiniowany jako nieokreślony, więc możemy tworzyć wielomiany w j. Aby uzyskać odpowiednią liczbę kłopotliwą, zmniejszamy (tj. Przyjmujemy pozostałą część podziału wielomianowego) oj^2-1 . Daje to termin liniowy (lub stały) i możemy polegać na zdolności GAP do generowania wielomianów.

Przykłady:

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

Zastrzeżenie: 1. To nie przyjmuje ciągu jako danych wejściowych, ale prawdziwy termin w języku GAP. Aby to naprawić, mogę użyć EvalString. 2. Dane wyjściowe są ładne i wyraźne, ale nie dokładnie takie, jak podano: Kolejność jest zmieniana, a zbędne zera są pomijane. Myślę i mam nadzieję, że nadal jest to zgodne z duchem wyzwania, w przeciwnym razie myślę, że lepiej byłoby użyć macierzy @ xnor.

Christian Sievers
źródło
1
Mathematica PolynomialMod[#,j^2-1]&ma podobne właściwości. Rzeczywiście, jeśli nigdy nie pomnożyliśmy więcej niż dwóch liczb zakłopotanych (tak jak w przypadkach testowych nie), to Expand@#/.j^2->1wystarczy.
Greg Martin
Podobnie t->t%(j^2-1)w Pari / GP.
alephalpha
1

Aksjomat, 20 42 bajtów

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

poprzednie rozwiązanie ma problem, jeśli jest n<0w, j^n ale wydaje się bardziej solidne i dobrze doradza tam, gdzie coś jest nie tak, nawet jeśli doskonałością byłby zwracany przykład j ^ 1.2 lub j ^ sqrt (-1) to samo wyrażenie nie ocenia

(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

jeśli nie przestrzegam jakiegoś prawa pytania: powiedz mi to i dodaję „niekonkurencyjny”. Mam na myśli to jako jeden aksjomat dla uproszczenia formuły

RosLuP
źródło
0

Partia, 52 bajty

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

Po zobaczeniu doskonałej nominacji @ xnor poczułem się zmuszony do przeniesienia jej.

Neil
źródło