Adicionar e multiplicar números desconcertantes

16

Os números de complexo dividido , também conhecidos como "números perplexos" são semelhantes aos números complexos. Em vez de i^2 = -1, no entanto, temos j^2 = 1; j != +/-1. Cada número assume a forma de z = x + j*y.

Em uma tentativa de limitar a complexidade desse desafio, usarei o símbolo -para representar negação, pois não haverá subtração.

Aqui estão alguns exemplos para o seu prazer:

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

Desafio

O objetivo deste desafio é avaliar uma expressão com números complexos complexos.

Isso é código-golfe, o menor número de bytes vence.

Entrada

A entrada será uma única linha contendo apenas os símbolos +*()-, os dígitos 0123456789e a letraj , com uma nova linha opcional. Essa sequência representa uma expressão, usando notação de infixo e precedência de operador (multiplicação antes da adição, com agrupamento de parênteses).

  • O símbolo -sempre representará negação, nunca subtração. Se desejar, você pode substituir -por um _ou outro~ para facilitar a E / S.
  • Os parênteses podem ser aninhados até três vezes para indicar o agrupamento: (1+(1+(1)))
  • A letra jnunca será prefixada diretamente com negação e sempre será seguida por* .
  • Parênteses não serão precedidos de negação -(7) , mas sim como-1*(j*5+2)
  • Nunca haverá operações implícitas. Toda multiplicação será expressa como em (7)*7vez de (7)7, e como em j*5vez dej5 .
  • Sem zeros à esquerda.

Resultado

A saída será na forma de X+j*Y, onde X e Y podem ser qualquer número inteiro. Se um número inteiro for negativo, deverá ser prefixado com o sinal de negação.

Restrições adicionais

Embora eu não conheça nenhum idioma com suporte nativo, são proibidos os internos que lidam com números complexos. Números complexos regulares são um jogo justo.

Casos de teste

Semelhante aos exemplos acima, mas arrumado. Insira uma linha e produza a linha abaixo.

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

Respostas:

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)

Simplesmente avaliamos a expressão scom j=1e j=-1, e produzimos metade de sua soma e metade de sua diferença como coeficientes de 1e j.

Isso funciona porque ambos j=1e j=-1satisfazer a definição de equação equação definindo j*j==1. Portanto, as expressões originais e simplificadas devem ser iguais para esses dois valores. A expressão simplificada é linear, portanto, isso fornece duas equações lineares em duas incógnitas:

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

que é resolvido por x=a+b, y=a-b.

xnor
fonte
Uma linguagem com operações de matriz também pode avaliar a expressão j=[0 1; 1 0]e ler coeficientes da linha superior.
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)`

Essa provavelmente não é a melhor abordagem, mas foi a primeira vez que o OOP parecia uma idéia aceitável em Python para o código de golfe, então por que não?

Cria uma classe cque herda de complexo, mas tem uma muloperação diferente . A addoperação também é alterada para que ele retorne um objeto do tipo ce não complex, esse comportamento é necessário para evitar o caso de (a + b) * (c + d)fazer multiplicação complexa em vez desse tipo especial.

A sequência de entrada é então convertida em uma sequência que pode ser avaliada naturalmente por python. Ele faz isso mudando a cada número em c(number)e depois a cada jem c(0,1).

Experimente online ou execute um Conjunto de Testes

FryAmTheEggman
fonte
1

GAP , 38 bytes

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

Primeiro jé definido como indeterminado, para que possamos criar polinômios em j. Para obter o número desconcertante correspondente, reduzimos (ou seja, pegamos o restante da divisão polinomial) em j^2-1. Isso fornece um termo linear (ou constante), e podemos confiar na capacidade do GAP de produzir polinômios.

Exemplos:

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

Advertência: 1. Isso não aceita uma string como entrada, mas um termo real no idioma do GAP. Para consertar, eu poderia usar EvalString. 2. A saída é agradável e clara, mas não exatamente como especificado: a ordem é alterada e os zeros desnecessários são suprimidos. Penso e espero que isso ainda esteja no espírito do desafio, caso contrário, acho que seria melhor usar a abordagem matricial do @ xnor.

Peneiradores cristãos
fonte
1
O Mathematica PolynomialMod[#,j^2-1]&tem propriedades semelhantes. De fato, se nunca multiplicamos mais de dois números perplexos (como os casos de teste não), Expand@#/.j^2->1basta.
Greg Martin
Da mesma forma, t->t%(j^2-1)em Pari / GP.
alephalpha
1

Axioma, 20 42 bytes

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

a solução anterior tem um problema se n<0em, j^n mas isso parece mais sólido, e aconselha bem onde há algo errado, mesmo que a perfeição retornasse exemplo j ^ 1.2 ou j ^ sqrt (-1) a mesma expressão não avalie

(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

se eu não seguir alguma lei da pergunta: diga-me isso e acrescento "não competitivo". Quero dizer isso como um axioma para simplificar a fórmula

RosLuP
fonte
0

Lote, 52 bytes

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

Depois de ver a excelente nomeação de respostas do @ xnor, senti-me compelido a portá-lo.

Neil
fonte