Me ajude com trigonometria!

8

Muito obrigado pela ajuda no cálculo . Agora preciso de ajuda com o meu próximo teste de trigonometria.

No teste, precisarei simplificar expressões. Receberei informações como 4sin(x)/(2cos(x))e terei que produzir uma expressão mais simples, mas equivalente (como 2tan(x)). Todos os ângulos estão em graus, e vamos fingir que não há problemas de divisão por zero ou domínio inválido. (Por exemplo, assumiremos que tan (x + 1) cot (x + 1) sin (x) / sin (x) é sempre 1.)

Entrei no escritório do professor e recebi uma lista de 100 problemas que poderiam estar em teste. Por favor, me dê o código para resolvê-los todos. É possível que alguns dos problemas já estejam simplificados o máximo possível; Nesse caso, apenas devolva a entrada.

Preciso que as expressões sejam simplificadas, mas também quero um programa (ou função) curto para que o professor não perceba. Tente minimizar a soma do comprimento do programa e o comprimento total de todas as soluções.

Apenas para esclarecer, não há problema se algumas das expressões forem retornadas inalteradas ou mesmo retornadas de forma equivalente, mas mais longa. Além disso, o programa precisa apenas trabalhar nas expressões listadas abaixo; pode retornar resultados incorretos ou até interromper para outras entradas.

Como você pode ver, todos os problemas seguem um formato semelhante. xé a única variável usada, não há espaços e os parênteses seguem o nome de cada função. (As funções são sin, cos, tan, sec, csc, e tan.) Não existem funções aninhadas, mas dentro de uma função pode ser uma expressão como 3x+4.5ou -2-.7x. Os expoentes podem ser usados, mas apenas em funções (por exemplo sin(x-.5)^7), e a potência é sempre um número inteiro acima de um. A multiplicação é indicada por concatenação.

As saídas também precisarão estar neste formato. Inválido: sin x, sin(x)/cos(x)tan(x)[? É a tangente multiplicados ou divididos], cos(x[fechar todos os parênteses], 4*sin(x),sec(x)^1

Eu posso usar qualquer linguagem de programação, a menos que ela dependa de funções integradas de simplificação ou manipulação de expressão. As funções trigonométricas incorporadas estão bem. (Vou ter uma calculadora científica muito básica durante o teste.) Além disso, como vou ler o programa escrito em papel, só posso usar caracteres ASCII imprimíveis (0x20 a 0x7E) e novas linhas.

1/(sec(x))
4+sin(x)+3
(cos(7x+4)-sin(-3x))/(sin(-3x))
2sin(x)2tan(x).25cos(x)^3cos(x)+1+1
7cos(x)sec(x)/(14tan(x)csc(x))
sin(x)cos(x)/sec(x)
8sin(x)cos(x)sin(x)/tan(x)+8sin(x)
sin(x)^9cos(x)cot(x)sec(x)csc(x)sec(x)tan(x)/(cot(x)^2tan(x)cos(x)^4cot(x)sin(x))
tan(x)cos(x)csc(x)
tan(x+1)sin(x-1)cos(x+1)^3tan(x-1)^2sin(-x+1)csc(x+1)tan(-x+1)/(cos(x-1)cot(x+1))
(cos(2x)+cot(2x)-sin(2x)+csc(2x)^3)/(cot(2x)+sin(2x))
cos(90-x)cos(x)
sin(x+180)sec(450-x)
tan(-x)sin(x+90)sec(x-90)
tan(x+180)^2
cot(-x)cos(-x)
cot(180-x)^3cos(270-x)^2
sin(.1x-.2)sin(.1x-.2)sin(.1x-.2)sin(.2-.1x)sin(.2-.1x)
sin(x)
sin(90-x)sin(x)+cos(90-x)/sec(x)
tan(3x+2)cos(3x+2)/sin(3x+2)-1
cos(x)cos(x)cos(x)cos(x)cos(x)
sec(2x+1)sec(-1-2x)+sec(-2x-1)sec(2x+1)
cos(4x)cot(4x)tan(4x)sin(4x)csc(4x)
-cos(x)+cos(x)+sin(2x-4)-1/csc(2x-4)
sec(x)sec(x+2)cot(x)tan(x-2)tan(x+180)
tan(x)(tan(x))
3sin(x)sin(x)/(3)
cos(x)sin(x)
tan(x)sec(x)^2
tan(x)^2-sec(x)^2
7+sin(x)csc(x)csc(x)+cot(x)^2
sin(90)+cos(-90)+sec(180)
csc(1)+csc(10)-csc(30)-csc(60)+csc(90)
sin(36000001)
csc(800)+(cot(720+x)-sec(4x-720))
sin(-x)+sin(x)
csc(-x)+csc(x)
4sin(x)-sin(x)+tan(x)-2tan(x)
cot(x)+10cot(x+90)+99cot(x+180)+.01cot(x-90)
tan(x)tan(x+180)
sec(x)sin(x+180)tan(x-270)cot(x-450)csc(x+90)
sin(x)/cot(x)+sin(x)/cot(x)
sin(x)csc(x)+tan(x)cot(x)+cos(x)sec(x)
cot(x)
9tan(x+90)+90tan(x+9)
cos(x-9999)+tan(x+99999)
2tan(x)tan(x)/2
tan(x)/tan(x-360)+cos(x+180)/cos(x)
csc(4x)sec(270-4x)
cot(91+x)tan(x-449)
csc(2x)(csc(2x)-sin(2x))
csc(x+1)^2-cot(x+1)cot(x+1)
cot(x)cot(x)+1
tan(x)^2-sec(x)sec(x)
tan(x)/cot(x)+csc(x)/csc(x)
cot(x)sin(x)/cos(x)
csc(x)tan(x)cos(x)
csc(x)cot(x)cos(x)
csc(x+90)csc(-x+270)-1
cot(x)/cot(x)+tan(x)/cot(x)+cot(x)cot(x)
sec(x)sec(x)sec(x)sec(x+90)sec(x-90)sec(x+180)
1-cos(x)cos(x+180)+sin(x)^2
sec(x)sec(x)sec(x)sec(x)/cos(x)+cot(x)
cot(x+1)csc(x-1)sec(x+1)tan(x-1)sin(x+1)cos(x-1)
sin(x)-cos(x)+tan(x)-sec(x)+cos(x)-csc(x)
tan(x+23515)-sec(-.27x-23456)
sec(-.9x)
-tan(-x)-csc(360-x)
cos(-x)sec(x)sin(x)csc(-x)
tan(-x)^2-sin(-x)/sin(x)
tan(x)tan(x)+1
csc(x)^2-1
cot(2x)cot(2x)-csc(2x)/sin(2x)
2sec(x)/(6cos(x))
sec(0)+tan(30)cos(60)-csc(90)sin(120)cot(150)+tan(180)csc(210)sin(240)-cos(270)sec(300)+cot(330)
tan(x-1234567)sec(4781053+x)^2
tan(-1234567x)sec(4781053x)^2
sin(x)^9+cos(x)^7+csc(x)^5-cot(x)^3
cos(-33x-7.7)
sec(-.1-x)+tan(-2x-77)
tan(x)+sin(x)-cos(x)+tan(x)-sin(x)
cos(x)-sec(x)/tan(x)+tan(x)/sin(x)
cot(x)-cos(x)/sin(x)
3cos(x)+2/sec(x)-10sin(x)/(2tan(x))
tan(x+3)^11+sin(x+3)^8-cos(x+3)^5+5
sec(x)+sec(x)
csc(.1x)csc(-.1x)csc(x)
cot(x-7)cot(x-7)cot(x+173)cot(x-7)cot(x+173)cot(x-367)
cos(.0001x+1234567)
cot(45)+tan(225)-sin(210)+cos(-60)
sin(12345)cos(23456)tan(34567)sec(45678)csc(56789)cot(67890)
cos(1234x)+cot(1234)+tan(1234x)+sec(1234)+csc(1234)+sin(1234x)
sec(x)sec(x)sec(x)sec(x)sec(x)sec(x)
csc(x)cot(x)sec(x)csc(x)tan(x)sec(x)cot(x)csc(x)cot(x)cos(x)cos(x)cot(x)sin(x)sin(x)cot(x)
csc(2553273)+cot(1507348)-sec(5518930)+csc(5215523)+tan(3471985)-sec(4985147)
sin(20x)+cos(20x)-tan(20x)+sin(20x)-csc(20x)+cot(20x)-tan(20x)+csc(20x)
cot(100000)+cot(100000x)+cot(100000x)+cot(100000)
csc(5x+777)sin(5x+777)
csc(4.5x)

Nota: Este cenário é totalmente fictício. Na vida real, enganar e ajudar os outros a trapacear é errado e nunca deve ser feito.

Ypnypn
fonte
5
Eu conto nada menos que quarenta identidades diferentes e axiomas matemáticos que seriam necessários para simplificar isso. Mesmo analisando uma das expressões e colocando-a em algum tipo de forma interna estruturada seria necessário um bom código. Rico demais para mim. Mas talvez haja alguns aqui procurando por esse tipo de desafio.
COTO 30/09
@ COTO, você não precisa analisá-lo. Você pode tentar detectar qual problema e codificar as respostas em formato compactado. Pode até ser mais curto que analisar.
Ingo Bürk
3
se a sua impressora não conseguir imprimir caracteres não ASCII, você precisará de uma impressora melhor.
John Dvorak
3
Eu só acho que esse cara ainda tem UPVOTES? Então eu notei que não era math.SE, soo ... o contexto importa =)
flawr
1
@Ypnypn Ah, ok, por exemplo, não podemos reduzir sin(36000001) para #.017452
Digital Trauma

Respostas:

8

Python, 436 + 1909 = 2345

Essa deve ser uma das soluções mais ineficientes que os imagináveis ​​e os matemáticos provavelmente irão se encolher, mas eu consegui juntar algo que realmente simplifica cerca de metade das expressões sem nenhuma codificação:

from math import*
import exrex,re
d=lambda f:lambda x:f(x*pi/180)
sin,cos,tan=d(sin),d(cos),d(tan)
i=lambda f:lambda x:1/f(x)
sec,csc,cot=i(cos),i(sin),i(tan)
t=lambda s:[round(eval(re.sub('([\d\).])([\(a-z])','\\1*\\2',s).replace('^','**')+'+0')*1e9)for x in[1,44]]
def f(I):
 try:return min((s for s in exrex.generate('(-?\d|\(1/\d\.\))?([+-]?(sin|cos|tan|cot|sec|csc)\(x\)(\^\d)?){0,4}')if s and t(s)==t(I)),key=len)
 except:return I

A saída para os 100 casos de teste deve ser a seguinte (em que #marca expressões que não foram simplificadas):

cos(x)
7+sin(x)
#
2+tan(x)^2cos(x)^2
(1/2.)cos(x)
sin(x)cos(x)^2
#
sin(x)^2tan(x)^7
1
#
#
sin(x)cos(x)
-1
-1
tan(x)^2
-cot(x)cos(x)
-cot(x)cos(x)^2
#
sin(x)
2sin(x)cos(x)
0
cos(x)^5
#
#
#
#
tan(x)^2
sin(x)^2
sin(x)cos(x)
tan(x)sec(x)^2
-1
7+cot(x)^2+csc(x)
0
#
#
#
0
0
3sin(x)-tan(x)
#
tan(x)^2
-tan(x)sec(x)
2sin(x)tan(x)
3
cot(x)
#
#
tan(x)^2
0
#
1
#
1
csc(x)^2
-1
sec(x)^2
1
1
cot(x)^2
-1-sec(x)^2
cot(x)^2+sec(x)^2
sec(x)^4csc(x)^2
2
cot(x)+sec(x)^5
#
sin(x)+tan(x)-csc(x)-sec(x)
#
#
tan(x)+csc(x)
-1
sec(x)^2
sec(x)^2
cot(x)^2
-1
(1/3.)sec(x)^2
#
#
#
#
#
#
2tan(x)-cos(x)
cos(x)-csc(x)+sec(x)
0
0
#
2sec(x)
#
#
#
3
#
#
sec(x)^6
cot(x)^4csc(x)
#
#
#
1
#

A ideia é bastante simples:

  • gerar uma enorme quantidade de expressões possíveis
  • selecione aqueles que produzem o mesmo resultado da expressão que você deseja simplificar, comparando-os com alguns (aqui dois) valores x
  • das expressões equivalentes retornam a mais curta

O problema é que existem muitas expressões possíveis a serem verificadas, então eu a limitei a um subconjunto.

Para ser sincero, não tive a paciência de testar o código acima. (Diga-me se você acha que isso é trapaça.) Em vez disso, usei uma regra muito mais longa, porém mais eficiente, para gerar um subconjunto ainda menor de expressões que, espero, ainda contém todas as simplificações desejadas. Se você quiser tentar isso, substitua a expressão regular da penúltima linha do código pela seguinte (e esteja preparado para alguns minutos de tempo de computação):

'0|((-1|\(1/[23]\.\)|[1237])[+-]?)?(sin\(x\)(\^2)?)?-?(tan\(x\)(\^[27])?)?(cot\(x\)(\^[24])?)?[+-]?(cos\(x\)(\^[25])?)?(sec\(x\)(\^[2456])?)?(csc\(x\)(\^2)?)?'

O programa também contém algumas despesas gerais necessárias para fazer o Python entender as expressões matemáticas. Isso envolveu

  • redefinindo sin, cose tanpara tirar argumentos em graus em vez de radiens (que é o que eu acho que o OP pretendido)
  • definindo sec, csce cotque não são parte do mathpacote
  • inserindo todos os sinais de multiplicação implícitos
  • substituindo o operador de exponenciação
Emil
fonte
@Doorknob Como as expressões de força bruta e a comparação de dois valores são mais uma "solução real" que as outras?
Ingo Bürk
@Emil Como você compara apenas dois valores diferentes para `x ', garantiu que as simplificações estão realmente corretas?
Ingo Bürk
Dando uma olhada rápida, não consigo encontrar simplificações incorretas (impressionantes), mas, para meu entendimento, 1/3.sec(x)^2não é uma saída válida.
Ingo Bürk
1
@ IngoBürk, todas as respostas foram calculadas manualmente ou com o WolframAlpha primeiro e depois as comparei com a saída do programa. Em dois ou três casos, o programa realmente encontrou simplificações que o WolframAlpha não produziu, mas pude confirmar que as teses também estavam corretas. Mas é claro que você está certo, pode haver colisões. É apenas que a natureza das funções em questão torna bastante improvável que dois gráficos distintos se cruzem nos meus dois pontos dentro da precisão usada. Vi colisões se usar apenas um ponto ou se os dois pontos estiverem muito próximos.
Emil
1
@Emil Alright. Eu realmente amo essa solução btw!
Ingo Bürk
6

CJam, 1 + 3000 = 3001

Assim como a solução básica para dar às pessoas algo a vencer:

l

Isso lê STDIN na pilha, cujo conteúdo é impresso no final do programa.

Tenho certeza de que isso pode ser derrotado, mas também tenho certeza de que muitas otimizações não podem ser implementadas nos personagens que seriam obtidos.

Martin Ender
fonte
Em algum lugar foi declarado como calcular a pontuação? Eu gosto do seu método. No entanto, eu não iria considerar as novas linhas, de modo que a pontuação básica seria 3000.
Emil
@Emil "Tente minimizar a soma do comprimento do programa e do comprimento total de todas as soluções." - Eu tive que ler várias vezes também.
Ingo Bürk
Eu me pergunto por que Martin não usou o Golfscript. Não há necessidade de ler explicitamente a entrada lá = D
Ingo Bürk
Eu não entendo Como é esta resposta e abaixo de um qualquer forma relacionada com a questão, que pergunta sobre trigonometria e outras coisas
Optimizer
2
@ IngoBürk Porque eu não conheço o GolfScript. : P
Martin Ender
5

Javascript (438 + 2498 = 2936)

O objeto no meio, opcionalmente, contém saídas simplificadas com base no comprimento da entrada e no primeiro caractere. Caso contrário, a entrada será retornada sem modificação.

s='sin(x)';(p=prompt)({
    352:s+"^2cos(x)^3+2",
    307:"cos(x)/2",
    348:s+"8(1+cos(x)^2)",
    "81s":s+"^2tan(x)^7",
    "55s":"-sin(0.2-0.1x)^5",
    "39s":"2sec(2x+1)^2",
    "35c":"cos(4x)",
    "36-":0,
    173:s+"^2",
    "25s":0,
    294:s+"3-tan(x)",
    "27s":s+"2/cot(x)",
    "40c":"1+tan(x)^2+cot(x)^2",
    "48c":1,
    "41s":s+"+tan(x)-csc(x)-sec(x)",
    "26c":-1,
    "24t":"1+tan(x)^2",
    "96s":"2.5+1/cos(30)",
    "34t":"2tan(x)-cos(x)",
    353:0,
    "36s":"6sec(x)",
    "90s":"cot(x)^4csc(x)"
}[(i=p()).length+i[0]]||i)

O espaço em branco é apenas para decoração e não está incluído na contagem de caracteres.

É uma pena que a adição de todas essas soluções tenha me salvado apenas alguns caracteres, mas melhor do que nada. A simplificação foi feita via wolframalpha - vou confiar.

Ingo Bürk
fonte