Suma y multiplica números desconcertantes

16

Los números complejos divididos , también conocidos como "números perplejos" son similares a los números complejos. En lugar de i^2 = -1, sin embargo, tenemos j^2 = 1; j != +/-1. Cada número toma la forma de z = x + j*y.

En un intento por limitar la complejidad de este desafío, usaré el símbolo -para representar la negación, ya que no habrá ninguna resta.

Aquí hay algunos ejemplos para su placer visual:

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

Desafío

El objetivo de este desafío es evaluar una expresión con números complejos divididos.

Este es el código de golf, gana la menor cantidad de bytes.

Entrada

La entrada será una sola línea que contiene solo los símbolos +*()-, los dígitos 0123456789y la letra j, con una nueva línea opcional. Esta cadena representa una expresión, usando notación infija y precedencia de operador (multiplicación antes de la suma, con agrupación de paréntesis).

  • El símbolo -siempre representará negación, nunca resta. Si lo desea, puede reemplazar -, ya sea con _o~ para la facilidad de E / S.
  • Los paréntesis se pueden anidar hasta tres veces para denotar la agrupación: (1+(1+(1)))
  • La letra jnunca irá directamente precedida de negación y siempre irá seguida de ella *.
  • Los paréntesis no irán precedidos de negación -(7), sino que-1*(j*5+2)
  • Nunca habrá operaciones implícitas. Toda multiplicación se expresará como en (7)*7lugar de (7)7y como en j*5lugar de j5.
  • Sin ceros a la izquierda.

Salida

La salida tendrá la forma de X+j*Y, donde X e Y pueden ser cualquier número entero. Si un número entero es negativo, debe tener como prefijo el signo de negación.

Restricciones Adicionales

Aunque no conozco ningún idioma con soporte nativo, están prohibidos los complementos que tratan con números complejos divididos. Los números complejos regulares son un juego justo.

Casos de prueba

Similar a los ejemplos anteriores, pero ordenado. Entrada en una línea y salida de la línea debajo.

(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
fuente

Respuestas:

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)

Simplemente evaluamos la expresión scon j=1y j=-1, y sacamos la mitad de su suma y la mitad de su diferencia como los coeficientes de 1y j.

Esto funciona porque ambos satisfacen la ecuación de definición j=1y j=-1la ecuación de definición j*j==1. Entonces, las expresiones originales y simplificadas deben ser iguales para ambos valores. La expresión simplificada es lineal, por lo que da dos ecuaciones lineales en dos incógnitas:

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

que está resuelto por x=a+b, y=a-b.

xnor
fuente
Un lenguaje con operaciones matriciales también podría evaluar la expresión con j=[0 1; 1 0]y leer coeficientes de la fila superior.
xnor
2

Pitón 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)`

Probablemente este no sea el mejor enfoque, pero fue la primera vez que OOP parecía una idea aceptable en Python para el golf de código, entonces, ¿por qué no?

Crea una clase cque hereda de complejo pero tiene una muloperación diferente . La addoperación también se cambia para que devuelva un objeto de tipo cy no complex, este comportamiento es necesario para evitar el caso de (a + b) * (c + d)hacer una multiplicación compleja en lugar de este tipo especial.

La cadena de entrada se convierte en una cadena que python puede evaluar de forma natural. Lo hace cambiando cada número en c(number)y luego jen cada c(0,1).

Pruébelo en línea o ejecute un Test Suite

FryAmTheEggman
fuente
1

GAP , 38 bytes

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

Primero jse define como un indeterminado, por lo que podemos crear polinomios en j. Para obtener el número perplejo correspondiente, reducimos (es decir, tomamos el resto de la división polinómica) en j^2-1. Esto proporciona un término lineal (o constante), y podemos confiar en la capacidad de GAP para generar polinomios.

Ejemplos:

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

Advertencia: 1. Esto no toma una cadena como entrada, sino un término real en el lenguaje de GAP. Para arreglarlo, podría usar EvalString. 2. La salida es agradable y clara, pero no exactamente como se especifica: se cambia el orden y se suprimen los ceros innecesarios. Creo y espero que esto siga en el espíritu del desafío, de lo contrario creo que sería mejor usar el enfoque de matriz de @ xnor.

Christian Sievers
fuente
1
Mathematica PolynomialMod[#,j^2-1]&tiene propiedades similares. De hecho, si nunca multiplicamos más de dos números perplejos (como los casos de prueba no lo hacen), entonces es Expand@#/.j^2->1suficiente.
Greg Martin
Del mismo modo, t->t%(j^2-1)en Pari / GP.
alephalpha 05 de
1

Axioma, 20 42 bytes

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

la solución anterior tiene un problema si n<0enj^n pero esto parece más sólido, y aconseja bien dónde hay algo mal, incluso si la perfección sería devolver el ejemplo j ^ 1.2 o j ^ sqrt (-1) la misma expresión no evalúa

(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

si no sigo alguna ley de la pregunta: dígame eso y agrego "no competitivo". Lo digo como un axioma para simplificar la fórmula

RosLuP
fuente
0

Lote, 52 bytes

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

Después de ver la excelente nominación de respuesta de @xnor, me sentí obligado a portarla.

Neil
fuente