Addiere und multipliziere verwirrende Zahlen


16

Die aufgeteilten komplexen Zahlen , auch als "Perplexzahlen" bekannt, sind den komplexen Zahlen ähnlich. Stattdessen i^2 = -1haben wir jedoch j^2 = 1; j != +/-1. Jede Zahl hat die Form von z = x + j*y.

In einem Versuch, die Komplexität dieser Herausforderung zu begrenzen, werde ich das Symbol verwenden, -um die Negation darzustellen, da es keine Subtraktion geben wird.

Hier einige Beispiele für Ihr Sehvergnügen:

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

Herausforderung

Das Ziel dieser Herausforderung besteht darin, einen Ausdruck mit aufgeteilten komplexen Zahlen zu bewerten.

Das ist Code-Golf, die wenigsten Bytes gewinnen.

Eingang

Die Eingabe erfolgt in einer einzelnen Zeile, die nur die Symbole +*()-, die Ziffern 0123456789und den Buchstaben enthält j, und optional in einer neuen Zeile. Diese Zeichenfolge stellt einen Ausdruck unter Verwendung der Infixnotation und der Operatorpriorität dar (Multiplikation vor Addition mit Klammergruppierung).

  • Das Symbol -steht immer für Negation, niemals für Subtraktion. Wenn Sie dies wünschen, können Sie -entweder_~ I / O durch I / O oder I / O durch I / O ersetzen .
  • Klammern können bis zu dreimal geschachtelt werden, um die Gruppierung zu kennzeichnen: (1+(1+(1)))
  • Dem Brief jwird niemals direkt die Verneinung vorangestellt, sondern immer gefolgt von *.
  • Klammern wird keine Negation vorangestellt -(7), sondern gefällt-1*(j*5+2)
  • Es wird niemals implizite Operationen geben. Alle Multiplikationen werden als (7)*7statt (7)7und als j*5statt ausgedrückt j5.
  • Keine führenden Nullen.

Ausgabe

Die Ausgabe erfolgt in der Form X+j*Y, wobei X und Y eine beliebige Ganzzahl sein können. Wenn eine Ganzzahl negativ ist, muss ihr das Negationszeichen vorangestellt werden.

Zusätzliche Einschränkungen

Obwohl ich keine Sprache mit nativer Unterstützung kenne, sind integrierte Funktionen, die sich mit aufgeteilten komplexen Zahlen befassen, verboten. Regelmäßige komplexe Zahlen sind Freiwild.

Testfälle

Ähnlich den obigen Beispielen, aber aufgeräumt. Geben Sie in eine Zeile ein und geben Sie die Zeile darunter aus.

(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

Antworten:


13

Python 2, 62 Bytes

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

Wir werten einfach den Ausdruck smit j=1und aus j=-1und geben die Hälfte ihrer Summe und die Hälfte ihrer Differenz als Koeffizienten von 1und aus j.

Dies funktioniert, weil beide j=1und j=-1die definierende Gleichung definierende Gleichung erfüllen j*j==1. Daher müssen der ursprüngliche und der vereinfachte Ausdruck für beide Werte gleich sein. Der vereinfachte Ausdruck ist linear, sodass sich zwei lineare Gleichungen in zwei Unbekannten ergeben:

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

was gelöst wird durch x=a+b, y=a-b.


Eine Sprache mit Matrixoperationen könnte auch den Ausdruck mit j=[0 1; 1 0]Koeffizienten in der obersten Zeile auswerten und davon ablesen.
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)`

Dies ist wahrscheinlich nicht der beste Ansatz, aber es war das erste Mal, dass OOP in Python als passable Idee für Codegolf erschien. Warum also nicht?

Erstellt eine Klasse c, die von complex erbt, aber eine andere mulOperation hat. Die addOperation wird auch so geändert, dass sie ein Objekt vom Typ zurückgibt cund nicht complex. Dieses Verhalten ist erforderlich, um zu verhindern, dass (a + b) * (c + d)anstelle dieser speziellen Art eine komplexe Multiplikation durchgeführt wird.

Die Eingabezeichenfolge wird dann in eine Zeichenfolge konvertiert, die von Python auf natürliche Weise ausgewertet werden kann. Dies geschieht, indem jede Zahl in c(number)und dann in geändert jwird c(0,1).

Probieren Sie es online aus oder führen Sie eine Test Suite aus


1

GAP , 38 Bytes

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

Zunächst jwird definiert, dass es sich um eine unbestimmte Zahl handelt, sodass wir Polynome in erstellen können j. Um die entsprechende verwirrende Zahl zu erhalten, reduzieren wir (dh nehmen den Rest der Polynomdivision) um j^2-1. Dies ergibt einen linearen (oder konstanten) Term, und wir können uns auf die Fähigkeit von GAP verlassen, Polynome auszugeben.

Beispiele:

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

Vorsichtsmaßnahme: 1. Hierbei wird kein String als Eingabe verwendet, sondern ein realer Begriff in der Sprache von GAP. Zum Reparieren könnte ich verwenden EvalString. 2. Die Ausgabe ist schön und klar, aber nicht genau wie angegeben: Die Reihenfolge wird geändert und unnötige Nullen werden unterdrückt. Ich denke und hoffe, dass dies immer noch im Geiste der Herausforderung ist, andernfalls würde ich wohl besser @ xnors Matrixansatz verwenden.


1
Mathematica's PolynomialMod[#,j^2-1]&hat ähnliche Eigenschaften. In der Tat, wenn wir nie mehr als zwei perplexe Zahlen miteinander multipliziert haben (wie die Testfälle nicht), dann Expand@#/.j^2->1reicht das aus.
Greg Martin

Ebenso t->t%(j^2-1)in Pari / GP.
Alephalpha

1

Axiom, 20 42 Bytes

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

die vorhergehende lösung hat ein problem, wenn n<0in j^n aber dies solider erscheint, und gut beraten, wo etwas nicht stimmt, auch wenn die perfektion zum beispiel j ^ 1.2 oder j ^ sqrt (-1) den gleichen ausdruck nicht auswerten würde

(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

Wenn ich ein Gesetz der Frage nicht befolge: Sag mir das und ich füge hinzu "nicht wettbewerbsfähig". Ich meine es als ein Axiom zur Vereinfachung der Formel


0

Batch, 52 Bytes

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

Nachdem ich @ xnors ausgezeichnete Antwortnominierung gesehen hatte, fühlte ich mich gezwungen, sie zu portieren.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.