Que comece a trigonometria!


20

Introdução:

O seno de xé dado pela fórmula:

sin(x) = x - x^3/3! + x^5/5! - x^7/7! + x^9/9! - x^11/11! // and more follows...

O cosseno de xé dado pela fórmula:

cos(x) = 1 - x^2/2! + x^4/4! - x^6/6! + x^8/8! - x^10/10! // and more follows...

Tarefa:

Dado o valor de xe n, escreva um programa (sem funções, etc.) para gerar o valor sin(x)e cos(x)corrija os ntermos da fórmula acima. Suponha que xesteja em radianos.

Entrada:

x n

Um número decimal x(com até 3 casas decimais) e um número inteiro n. A entrada deve estar no stdin ou em uma caixa de diálogo de prompt (se o seu idioma não suportar stdin)

Saída:

[sin(x)]
[cos(x)]

O valor de ambos sin(x)e cos(x)deve ser arredondado para 6 casas decimais. Se sin(x)for 0.5588558855(10 dígitos decimais), deve ser arredondado para 0.558856(6 dígitos decimais). O arredondamento deve ocorrer para o mais próximo, conforme descrito na quinta coluna, "Arredondar para o mais próximo" da tabela neste artigo do Wiki .

Restrições:

1 <= x <= 20
1 <= n <= 20

Amostras:

----
5 3

10.208333
14.541667
----
8.555 13

0.765431
-0.641092
----
9.26 10

-3.154677
-8.404354
----
6.54 12

0.253986
0.967147
----
5 1

5.000000
1.000000
----
20 20

-5364.411846
-10898.499385
----

Notas:

  1. As brechas padrão são proibidas.
  2. Funções matemáticas internas e operadores de trigonometria (sin, cos, tan, etc.), fatorial e exponenciação não podem ser usados. Você é livre para usar uma função de arredondamento embutida para estimar o resultado da computação sin(x)e cos(x)o sexto dígito decimal.
  3. Não há necessidade de lidar com entradas erradas.
  4. Somente caracteres ASCII podem ser usados ​​no programa, não os caracteres chineses Unicode que permitem a compactação de código.
  5. Seu programa deve terminar e exibir a saída dentro de 3 segundos após a entrada.
  6. Sua resposta deve acompanhar o código não-bloqueado, juntamente com a explicação do código (obrigatório se o código não for imediatamente óbvio para os programadores que não estão familiarizados com sua linguagem, especialmente GolfScript, J, etc.).
  7. Inclua um link para um compilador on-line onde seu programa possa ser testado.

Pontuação:

A resposta com o menor tamanho de código em caracteres, incluindo espaço em branco, guias, etc. vence! O vencedor seria declarado em 21 de maio de 2014.

EDIT : 21/05/14 O vencedor é aditsu usando a linguagem CJam . O segundo colocado segue jpjacobs com a linguagem J e o segundo classificado é primo com a linguagem Perl . Parabéns a todos!


(Nota do mod: comentários bloqueados. Por favor, envie-me um ping para qualquer informação perdida que você possa querer; parece que após o meu aviso com antecedência, tudo entrou na questão.)
Maçaneta da porta

No primeiro parágrafo, deve ser "seno", não "pecado"
não que Charles seja o

O "Arredondar para o mais próximo" ainda é um requisito ou podemos usar quaisquer instalações de arredondamento integradas? por exemplo, volta para zero?
Digital Trauma

Exigir o equivalente a uma mod 2pioperação para converter as entradas mais rapidamente seria bastante útil - é uma das muitas melhorias que o mundo real usa ao lidar com essas funções. (na verdade, mod pi e sinal de conscientização).
Floris 16/05

1
@ Florida Eu nunca soube disso. Bem, não podemos fazer nada agora, as regras já mudaram muito e eu não quero continuar mudando para irritar ainda mais os respondentes. Obrigado pela sugestão!
Gaurang Tandon

Respostas:


6

CJam - 42

rd:X;1_ri2*,1>{_2%2*(*/X*_}/;]2/z{:+6mO}/p

Experimente online em http://cjam.aditsu.net

Explicação:

rlê um token da entrada se
dconverte em
:Xatribuições duplas à variável X
;aparece o valor da pilha
1coloca 1 na pilha (o primeiro termo)
_duplica o 1
rlê o próximo token (n) se
iconverte em número inteiro
2*,1>{...}/é um tipo de loop de 1 a 2 * n - 1:
- 2*multiplica por 2
- ,cria uma matriz de 0 a (último valor) -1
- 1>remove o primeiro item da matriz (0)
- {...}/executa o bloco para cada item da matriz
_duplicando o loop " variável "(vamos chamá-lo de k)
2%2*(converte de par / ímpar em -1/1:
- 2%é o módulo 2 (-> 0/1)
- 2*multiplica por 2 (-> 0/2)
-(decrementa (-> -1/1)
*multiplica, alterando o sinal a cada segunda vez,
/divide o termo na pilha por k ou -k; este é o "/ k!" parte do cálculo, juntamente com a mudança de sinal,
X*multiplica por X; esta é a parte "X ^ k" do cálculo; obtivemos o próximo termo na série
_duplicado, o termo a ser usado para calcular o termo a seguir na próxima iteração
;(após o loop) aparece o último termo duplicado
]coleta os termos na pilha em uma matriz
Neste ponto, temos uma matriz [ 1 X-X ^ 2/2! -X ^ 3/3! X ^ 4/4! X ^ 5/5! ...] contendo exatamente todos os termos que precisamos para cos (x) e sin (x), intercalados
2/dividem esse array em pares
ztranspõe a matriz, resultando na matriz com os termos para cos (x) e na matriz com os termos para sin (x), como "linhas da matriz"
{...}/novamente executa o bloco para cada item da matriz (linha da matriz):
- :+adiciona os elementos da linha da matriz juntos
- 6mOarredonda para 6 casas decimais
Neste ponto, temos o desejado cos (x) e sin (x) na pilha
pimprime a representação do último item na pilha (sin (x)) seguido por uma nova linha
Em No final do programa, o conteúdo restante da pilha (cos (x)) é impresso automaticamente.


1
+1 por me apresentar um idioma que eu nunca ouvi falar e provavelmente nunca usará.
Alex A.

@Alex graças, CJam é um pouco como GolfScript em esteróides
aditsu

Não gosto de alterar regras depois de postar a pergunta, mas não permiti caracteres Unicode de compactação de código permitindo, pois não sabia que caracteres Unicode poderiam ser usados ​​para compactar código. Somente caracteres ASCII podem ser usados ​​agora. Edite sua postagem. Desculpe pela inconveniência.
Gaurang Tandon

@GaurangTandon Também não gosto muito disso. Para que mais você acha que os caracteres chineses poderiam ser usados ​​nesse problema? Enfim, editado.
Aditsu 15/05

18

Perl - 72 bytes

$~=<>=~$"+$'*2;$_=1-$_*$`/$~--/$~*$`for($,,$;)x$';printf'%f
%f',$`*$,,$;

Ou, contando as opções da linha de comando como 1 byte cada, em 70 bytes :

#!perl -n
$-=/ /+$'*2;$_=1-$_*$`/$---/$-*$`for($,,$;)x$';printf'%f
%f',$`*$,,$;

Ou, se você me permitir Perl 5.8, em 63 bytes :

#!perl -p
$.+=$'<</ /;$_=1-$_*$`/$.--/$.*$`for($_=$#='%f
',$\)x$';$_*=$`

mas por que você faria.

Editar : conformidade com as novas regras. %farredonda para 6 lugares por padrão, que conveniente!


Algoritmo

Examinando a série Taylor quanto ao pecado (x) :

pode-se ver que cada termo divide igualmente todos os termos sucessivos. Por isso, pode ser transformado sem esforço em uma expressão aninhada:

cos (x) se transforma da mesma forma, sem o x inicial e o denominador denomina um menor.

Além disso, essa expressão aninhada pode ser reformulada como uma expressão recursiva reversa:

com s = 0 e sin (x) = x · s 1 , que é basicamente o que é usado.


Ungolfed

<> =~ m/ /;          # read one line from stdin, match a space
                     # prematch ($`) is now x, postmatch ($') is now n
($x, $n) = ($`, $'); # reassign, for clarity
$i = 2*$n + 1;       # counting variable (denominators)

for (($s, $c)x$n) {  # iterate over $s and $c, n times each
  # compute the next term of the recursive expression
  # note: inside this loop $_ is not the _value_
  # of $s and $c alternately, it _is_ $s and $c

  $_ = 1 - $_ * $x**2 / $i-- / $i;
}

# formated output
printf("%f\n%f", $x*$s, $c);

Uso da amostra

$ echo 5 3 | perl sin-cos.pl
10.208333
14.541667

$ echo 8.555 13 | perl sin-cos.pl
0.765431
-0.641092

$ echo 9.26 10 | perl sin-cos.pl
-3.154677
-8.404354

$ echo 6.54 12 | perl sin-cos.pl
0.253986
0.967147

$ echo 5 1 | perl sin-cos.pl
5.000000
1.000000

$ echo 20 20 | perl sin-cos.pl
-5364.411846
-10898.499385

Se você quiser testar isso online, recomendo usar o compileonline.com . Copie e cole o código em main.ple a entrada na STDINcaixa Execute Script.


2
Que maneira desonesta de analisar a entrada ... posso usar isso na minha solução? :)
Tal

@Tal Sinta-se livre.
primo

2
Acho perl (e especialmente o seu código) conta como "não imediatamente óbvio para programadores-não-familiares-com-o-language"
aditsu

1
@aditsu Concordou. Vou adicionar um código mais limpo e uma explicação do algoritmo.
Primo 15/05

2
Essa resposta foi realmente extremamente educativa!
Tal

10

Python 3 (102) / Python 2 (104)

Python 3 (102)

x,n=map(float,input().split())
k=2*n
t=1
while k>1:k-=1;t=1+t*1j*x/k
print('%.6f\n'*2%(t.imag,t.real))

Python 2.7 (104)

x,n=map(float,raw_input().split())
k=2*n
t=1
while k>1:k-=1;t=1+t*1j*x/k
print'%.6f\n'*2%(t.imag,t.real)

Basicamente o mesmo código. Nós salvamos dois caracteres por não precisar de parênteses, printmas perdemos quatro por precisar raw_input.

Amostra de execução

Você pode executá-los aqui .

>>>
20 20
-5364.411846
-10898.499385

Explicação do código

A idéia principal é calcular 2*ntermos de e^(ix)e, em seguida, pegar a parte imaginária e real para obter os valores sine cosaproximados dos ntermos. Usamos o truncamento da série Taylor:

e^(ix)≈sum_{k=0}^{2n-1} (i*x)^k/k!

Isso é polinomial em i * x, mas, em vez de calcular seu valor somando cada termo, usamos um método de Horner modificado para calcular a sequência (definida recursivamente ao contrário)

t_{2n} = 1
t_k = 1 + t_{k+1}*i*x/k,

o que dá t_1igual ao valor desejado.

As operações de formatação de seqüência de caracteres Python são usadas para obter os valores exibidos arredondados até 6 dígitos decimais.

Editar: alterado para arredondar para 6 dígitos, de acordo com as novas regras. Não foram necessárias outras alterações.


Tente ideone um intérprete PY3 on-line :)
Harry Beadle

@BritishColour Thanks! Adicionei à postagem.
xnor 14/05

Atualize sua resposta. Veja os detalhes em questão. Obrigado.
Gaurang Tandon

8

J 98 70 69 58

Embora isso possa ser encurtado usando funções mais sofisticadas ... os comentários são bem-vindos:

exit echo 0j6":,.-/(($%&(*/)1+i.@[)"0~i.@,&_2)/".}:stdin''

nota 2: a entrada termina ao receber EOF (ctrl-D no linux). Editar: junte exponenciação e fatorial em um mais agradável, mais J-ish todo: ($ %&(*/) >:@i.@[ ). Isso se resume a obter uma matriz de x replicações de y e uma matriz dos números de 1 a y. Multiplique cada um e divida o resultado. Isso se livra da duplicata */.

Graças a algortihmshark, mais 7 caracteres desligados.

Corte eliminado para se livrar da nova linha à direita.

Versão mais longa, para a qual é essencial conhecer os garfos.

NB. recursive Factorial
f=: */@>:@i.      NB. multiply all from 1 to n
NB. Exponential
e=: */@$          NB. replicate y x times, take the product.
NB. the x t y is the Nth (general) term without sign of the joint series
t=: (e % f@[)"0  NB. pretty straight forward: divide by (x!) on the exponential

NB. Piece the parts together, from right to left:
NB. read from stdin, cut the linefeed off , make the 2 n terms in 2 columns, which
NB. effectively splits out pair and odd terms, put in the minuses, put in rows
NB. instead of columns, echo, exit
exit echo 0j6&": ,. (-/) (i.@(,&_2)@{: t {.) , (". ;. _2) stdin''

Não há intérprete J online, mas é de código aberto há alguns anos; a instalação é fácil com estas instruções:

http://www.jsoftware.com/jwiki/System/Installation/J801

No #jsoftware em irc.freenode.org, também existe um bot J.

stdin funciona apenas quando executado a partir de um arquivo, a partir da linha de comando, substitua stdin ''por 'a b;'onde a e b são os números que seriam passados ​​na linha de comando.


5
Eu amo o que começa comexit
Digital Trauma

Atualize sua resposta. Veja os detalhes em questão. Obrigado.
Gaurang Tandon

Atualizado para as 6 casas decimais. Se houver algo mais, especifique. Obrigado
jpjacobs 19/14

Você pode remover o &de 0j6&":para salvar um caractere. Além disso, (i.@(,&_2)@{:($%&(*/)>:@i.@[)"0{.)pode ser reescrita (($%&(*/)1+i.@[)"0~i.@,&_2)/para um outro 6.
algorithmshark

Essas tarefas gritam por T.(função aproximada da série Taylor de n termos), mas acho que isso é verboten como uma brecha padrão.
FUZxxl

6

Perl, 120 108 104 89 85

<>=~/ /;$c=$t=1;for(1..2*$'-1){$t*=$`/$_;$_%2?$s:$c+=$_&2?-$t:$t}printf"%f\n"x2,$s,$c

Ungolfed:

<> =~ / /;
$cosine = $t = 1;
for (1.. 2*$' - 1){
  $t *= $` / $_;
  ($_%2 ? $sine : $cosine) += $_&2?-$t:$t
}
printf "%.6f\n" x2, $sine, $cosine

A primeira linha lê a entrada e usa regex para encontrar um espaço; isso coloca automaticamente o valor antes do espaço em $ `e o valor depois em $ '.

Agora passamos de 1 para 2*n-1. $té o nosso termo, que o loop multiplica xe divide repetidamente pelo índice do loop ( $_). O loop começa em 1 em vez de 0 porque o cosseno é inicializado em 1, o que me salvou de ter que lidar com a divisão por zero.

Após a atualização $t, o operador trinário retorna um $sineou $cosine, dependendo se o índice é ímpar ou par, e adiciona $tvalor a ele. A fórmula mágica $_&2?-$t:$tindica se você deve adicionar ou subtrair esse valor (basicamente usando um bit a bit - e no índice e 2 para gerar a sequência repetida de "adicionar, adicionar, subtrair, subtrair").

Você pode testar esse código em compileonline.com .


Corrija sua saída para 20 20.
Gaurang Tandon

1
Eu acho que seu loop for pode precisar ir 1..$n*2-1, em vez de 1..$n. Enquanto estou aqui ... $sé perfeitamente bem não inicializado, como undefavalia 0em um contexto numérico. Atribuição ternário não precisa de parênteses: $_&1?$s:$c+=$t. "%.8f\n%.8f"pode ser reduzido para "%.8f\n"x2, na conseqüência da adição de uma nova linha à direita.
Primo 15/05

@ Primimo Obrigado, eu não sabia sobre alguns deles. E agora ele também produz o resultado correto.
Tal

@ Tal Meu prazer. Além disso, mágica um pouco melhor: $t*(1-($_&2))=> $_&2?-$t:$t.
Primo 15/05

Atualize sua resposta. Veja os detalhes em questão. Obrigado.
Gaurang Tandon

5

Fortran: 89 109 125 102 101 98 bytes

complex*16::t=1;read*,x,n;do k=2*n-1,1,-1;t=1+t*(0,1)*x/k;enddo;print'(f0.6)',aimag(t),real(t);end

Abuso de digitação implícita, mas infelizmente não existe esse tipo complexo implícito, então tive que especificar isso e o complexo i. O Gfortran corta a saída em 8 casas decimais naturalmente, por isso somos bons nessa especificação. Infelizmente, meu método original de saída print*,t,, não atendia às especificações, então tive que adicionar 16 caracteres para gerar os componentes imaginários e reais e atingir as 8 casas decimais necessárias.

Graças ao Ventero, consegui salvar 23 bytes entre a saída e o loop. E outro caractere para obter respostas corretas e saída formatada. E mais 3 na readdeclaração.

Ungolfed,

complex*16::t=1
read*,x,n
do k=2*n-1,1,-1
   t=1+t*(0,1)*x/k
enddo
print'(f0.6)',aimag(t),real(t)
end

Atualize sua resposta. Veja os detalhes em questão. Obrigado!
Gaurang Tandon

1
@GaurangTandon: Você provavelmente deve parar de alterar os detalhes do problema.
Kyle Kanos #

Eu sei e não quero, mas não posso evitar. Na verdade, depois de testar 5 respostas, descobriu-se que quase todos estavam dando resultados diferentes (isso era de fato completamente inesperado). Eu poderia ter seguido alguma outra abordagem, mas isso teria exigido a mudança completa dos algoritmos das respostas atuais. Este é o melhor que pude descobrir.
Gaurang Tandon

2
Bem, eu sei que o meu funciona perfeitamente, então eu deveria totalmente obter o cheque: D;)
Kyle Kanos

4

C, 120

double s,c,r,x;main(i,n){for(scanf("%lf %d",&x,&n),r=1;i<n*2;s+=r,r*=-x/i++)c+=r,r*=x/i++;printf("%.8lf\n%.8lf\n",s,c);}

Para salvar um byte, as instruções que atualizam o valor do seno são colocadas dentro da for()instrução, mas na verdade são executadas após as instruções após os parênteses de fechamento que atualizam o valor do cosseno. (Acho que também pude salvar mais alguns bytes removendo o caractere de nova linha final na saída do programa.)

As variáveis globais s, c, re xsão implicitamente inicializado para zero, e iterá um valor de 1, desde que não há argumentos fornecidos na linha de comando. Infelizmente, o printf()padrão é 6 casas decimais, portanto o formato de saída é um pouco detalhado.

Ungolfed:

Aqui está o código com um pouco de reorganização para tornar a ordem em que as coisas são feitas um pouco mais clara:

double s,c,r,x;
main(i,n) {
    scanf("%lf %d",&x,&n);
    r=1;
    for(;i<n*2;) {
        c+=r;
        r*=x/i++;
        s+=r;
        r*=-x/i++;
    }
    printf("%.8lf\n%.8lf\n",s,c);
}

Saída de amostra:

$ echo 1.23 4 | ./sincos
0.94247129
0.33410995

Experimente online:

http://ideone.com/URZWwo


3

Python> = 2.7.3, 186 184 211 200 182 170 caracteres

Meio simples como o inferno. Usa a fórmula da pergunta parametrizada para seno e cosseno.

Intérprete online pode ser encontrado Aqui Aqui

x,n=map(eval,raw_input().split())
f=lambda n:n<2and 1or n*f(n-1.)
for i in[1,0]:print"%.6f"%sum((1-j%2*2)*reduce(lambda o,p:o*p,[x]*(i+2*j),1)/f(i+2*j)for j in range(n))

Editar: versão válida com todas as restrições

Edit2: Alterador do interpretador online para ideone.com devido à roundsaída de função inválida no Python 2.7.1

Edit3: Descobri que eu usei lambda inline desnecessário + alterei o arredondamento para o formato de string (roubado do xnor :))

Edit4: Substituído joinpor forloop principal não funcional


Olá, disponível. Recentemente, editei as regras que agora não permitem a exponenciação dos operadores internos (é isso que **estou fazendo, suponho). Então, acho que você terá que editar sua resposta. Desculpe pela inconveniência. Por favor corrija-me se eu estiver errado.
Gaurang Tandon

1
Eu acho que outras modificações são inúteis com o xnor resposta :)
avall

@avail On 20 20, eu recebo saída -5364.4118142500001. Pode querer corrigi-lo para 8 casas decimais.
Gaurang Tandon

É por causa da versão repl.it Python 2.7.1. Se você executá-lo em ideone.com (Python 2.7.3), ele funcionará corretamente. ideone.com/JsYNNK
avall

Funciona bem agora! +1
Gaurang Tandon

3

JavaScript - 114 caracteres

y=(z=prompt)().split(' ');for(x=l=s=+y[0],c=d=1;--y[1];c+=l*=-x/++d,s+=l*=x/++d);z(s.toFixed(6)+'\n'+c.toFixed(6))

Baseado na grande resposta de James. Mesmo algoritmo, primeiro passo evitado com a inicialização de c = 1 es = x. Usar 2 vars em vez de uma matriz para saída simplifica o loop.

Ungolfed

y = ( z = prompt)().split(' ');
for ( 
    x = l = s = +y[0], /* init to value x, note the plus sign to convert from string to number */
    c = d = 1;
    --y[1]; /* No loop variable, just decrement counter */
    c += (l *= -x / ++d), /* Change sign of multiplier on each loop */
    s += (l *= x / ++d) 
); /* for body is empty */
z(s.toFixed(6) + '\n' + c.toFixed(6))     

Erro de digitação menor: seria s += (l *= x / ++d)e não s += (l* = x / ++d)no código não destruído.
Gaurang Tandon

1
@GaurangTandon fixed
edc65

2

JavaScript (ECMAScript 6 Draft) - 97 96 caracteres

Uma solução recursiva:

f=(x,n,m=1,i=0,s=x,c=1)=>i<2*n?f(x,n,m*=-x*x/++i/++i,i,s+m*x/++i,c+m):[s,c].map(x=>x.toFixed(8))

Saída:

f(0.3,1)
["0.29550000", "0.95500000"]

f(0.3,24)
["0.29552021", "0.95533649"]

Isso não atende às especificações de arredondamento.
Martin Ender

@ m.buettner fixed
MT0

1
Não atende aos no functionsrequisitos e formato de entrada .
Avall

Atualize sua resposta. Veja os detalhes em questão. Obrigado.
Gaurang Tandon

2

C, 114

Reputação insuficiente para comentar, mas, além da resposta C da Squeamish Offisrage , a redução de 7 bytes usando float para dobrar e remover espaços, e combinando declaração e init de 'r', fornece

float s,c,r=1,x;main(i,n){for(scanf("%f%d",&x,&n);i<n*2;s+=r,r*=-x/i++)c+=r,r*=x/i++;printf("%.8f\n%.8f\n",s,c);}

tente aqui .


Bem-vindo à programação de quebra-cabeças e código de golfe. Parabéns por reconhecer que sua resposta é uma pequena melhoria em relação à @ squeamishossifrage (eu ainda consegui escrever errado na minha edição.) É melhor não se referir à resposta "acima" porque a ordem muda sempre que há uma edição. BTW, notei a inicialização de rna declaração. Não testei para ver se floatdá a precisão necessária.
Level River St

@steveverrill Nem eu acho floatque daria a precisão necessária, mas funciona :) E bem-vindo ao PPCG, user2702245!
Gaurang Tandon

Sou apenas eu que estou obtendo respostas erradas com floatvariáveis ​​então? Para x=5e n=3, recebo sin(x)=10.20833206e cos(x)=14.54166412:-( (Intel Core Duo, em caso você estava pensando)
ossifrage escrúpulos

Deseja que eu converta isso em um comentário sobre a resposta?
Maçaneta

@Doorknob Maio, bem deixá-lo agora :-)
ossifrage escrúpulos

2

GNU bc, controlado por bash, 128 bytes

Muitos bytes gastos configurando casas decimais e o arredondamento mais próximo. Oh bem, aqui está assim mesmo:

bc -l<<<"m=1000000
w=s=$1
c=1
for(p=2;p/2<$2;s+=w){w*=-1*$1/p++
c+=w
w*=$1/p++}
s+=((s>0)-.5)/m
c+=((c>0)-.5)/m
scale=6
s/1
c/1"

Saída:

$ ./trig.sh 5 3
10.208333
14.541667
$ ./trig.sh 8,555 13
.765431
-.641092
$ ./trig.sh 9,26 10
-3.154677
-8.404354
$ ./trig.sh 6,54 12
.253986
.967147
$ ./trig.sh 5 1
5.000000
1.000000
$ ./trig.sh 20 20
-5364.411846
-10898.499385
$ 

Ferramentas de linha de comando do Linux, 97 caracteres unicode

Resposta de corte Unicode removida a pedido do OP. Veja o histórico de edições, se estiver interessado.


Não gosto de alterar regras depois de postar a pergunta, mas não permiti caracteres Unicode de compactação de código permitindo, pois não sabia que caracteres Unicode poderiam ser usados ​​para compactar código. Somente caracteres ASCII podem ser usados ​​agora. Edite sua postagem. Desculpe pela inconveniência #
Gaurang Tandon 15/05

@GaurangTandon Não é realmente uma compactação - a versão unicode realmente leva mais bytes (mas menos caracteres). Mas concordo com o seu sentimento - prefiro que a pontuação seja estritamente feita com contagem de bytes, mas não pude resistir um pouco aos caracteres chineses no seu OP.
Digital Trauma

Você usar o operador exponencial ilegal
avall

@avall Oops. Isso me custou 4 bytes.
Digital Trauma

1

Ruby, 336

Provavelmente o mais longo aqui, mas tenho certeza de que poderia ser menor :(

def f(n)
n==0 ? 1: 1.upto(n).inject(:*)
end
def p(x,y)
i=1
return 1 if y==0 
y.times {i *= x}
i
end
def s(x,n)
a = 0.0
for k in 0...n
a += p(-1,k) * p(x.to_f, 1+2*k)/f(1+2*k)
end
a.round(8)
end
def c(x,n)
a= 0.0
for k in 0...n
a +=p(-1,k) * p(x.to_f, 2*k)/f(2*k)
end
a.round(8)
end
x = gets.chomp
n = gets.chomp.to_i
puts s(x,n), c(x,n)

1

JavaScript (ES6) - 185 caracteres

i=(h,n)=>n?h*i(h,n-1):1;q=x=>x?x*q(x-1):1;p=(a,j,n)=>{for(c=b=0,e=1;c++<n;j+=2,e=-e)b+=e*i(a,j)/q(j);return b.toFixed(6)}
_=(y=prompt)().split(" ");y(p(_[0],1,_[1])+"\n"+p(_[0],0,_[1]))

Usa uma função qpara fatorial, ipara exponenciação e ppara executar ambos sine cos. Execute em jsbin.com. Usa exatamente a fórmula sem nenhuma modificação.

EDIT : 8casas decimais alteradas para 6casas decimais. 15 / Mai / 14

Código Ungolfed :

/*Note that `name=args=>function_body` is the same as `function name(args){function_body} */

// factorial
function fact(x) {
    return x > 1 ? x * fact(x - 1) : 1
}

// Exponentiation
function expo(number, power){
    return power > 0 ? number * expo(number, power - 1) : 1;
}

function sin_and_cos(number, starter, terms) {
    for (count = sum = 0, negater = 1;
            count++ < terms;
            starter += 2, negater = -negater) 

        sum += (negater * expo(number, starter)) / fact(starter);

    // to 6-decimal places
    return sum.toFixed(6);
}

input = (out = prompt)().split(" ");

out(sin_and_cos(input[0], 1,input[1]) 
        + "\n" +                
        sin_and_cos(input[0], 0, input[1]));

1

JavaScript - 133 caracteres

y=(z=prompt)().split(" "),s=[0,0],l=1;for(i=0;i<y[1]*2;i++){s[i%2]+=i%4>1?-1*l:l;l*=y[0]/(i+1)}z(s[1].toFixed(6));z(s[0].toFixed(6));

Ungolfed

var y = prompt().split(" ");

var out = [0,0]; // out[1] is sin(x), out[0] is cos(x)
var l = 1; // keep track of last term in series
for (var i=0; i < y[1] * 2; i++) {
    out[i % 2] += (i % 4 > 1) ? -1 * l : l;
    l *= y[0] / (i + 1);
}

prompt(out[1].toFixed(6));
prompt(out[0].toFixed(6));

A entrada deve ser dois números inteiros separados por espaço, não em duas caixas de diálogo diferentes. Por favor, conserte isso.
Gaurang Tandon

@GaurangTandon corrigido - obrigado por apontar isso #: #
James James


1

Ruby - 160 152 140 Chars

Usando recursão e o fato de que, para essa implementação recursiva, sin (x, 2n + 1) = 1 + cos (x, 2n - 1), sendo sin (x, n) e cos (x, n) as séries definidas acima para cos xe pecado x.

p=->x,n{n<1?1:x*p[x,n-1]}
f=->n{n<2?1:n*f[n-1]}
c=->x,n{n<1?1:p[x,n]/f[n]-c[x,n-2]}
x,n=gets.split.map &:to_f
n*=2
puts c[x,n-1]+1,c[x,n-2]

Editar: Contribuído por comentaristas (leia abaixo).


1
Você pode salvar muitos caracteres usando lambdas: p=->x,n{...} , f=->n{...}e assim por diante, e, em seguida, usar colchetes em vez de parênteses para chamá-los, como p[x,n-1]. Além disso, acho que collecté apenas um apelido para map, que é muito mais curto, e como você está mapeando apenas uma chamada de membro, pode abreviá-lo gets.split.map &:to_f.
Martin Ender

@ MartinBüttner Obrigado! Adicionará isto! (espero que o seu comentário aqui afirmou que esta solução não é só minha, mas collab) Para ser honesto: Eu também sou novo para Ruby (apenas 2 mês) :)))
Boriel
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.