Che la trigonometria abbia inizio!


20

Introduzione:

Il seno di xè dato dalla formula:

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

Il coseno di xè dato dalla formula:

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

Compito:

Dato il valore di xe n, scrivere un programma (nessuna funzione, ecc.) Per generare il valore sin(x)e cos(x)correggere fino ai ntermini della formula sopra. Supponiamo che xsia in radianti.

Ingresso:

x n

Un numero decimale x(con massimo 3 cifre decimali) e un numero intero n. L'input deve essere su stdin o su una finestra di dialogo del prompt (se la tua lingua non supporta stdin)

Produzione:

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

Il valore di entrambi sin(x)e cos(x)deve essere arrotondato al 6 decimale. Se sin(x)è 0.5588558855(10 cifre decimali), deve essere arrotondato a 0.558856(6 cifre decimali). L'arrotondamento deve avvenire al più vicino, come descritto nella quinta colonna, "Arrotondamento al più vicino", della tabella in questo articolo Wiki .

vincoli:

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

Campioni:

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

Appunti:

  1. Sono vietate le scappatoie standard .
  2. Le funzioni matematiche integrate e gli operatori di trigonometria (peccato, cos, abbronzatura, ecc.), Fattoriale ed esponenziale non possono essere utilizzati. Sei libero di usare una funzione di arrotondamento integrata per stimare il risultato dell'informatica sin(x)e cos(x)la cifra decimale 6.
  3. Non è necessario gestire input errati.
  4. Nel programma è possibile utilizzare solo caratteri ASCII, non quelli Unicode cinesi che consentono la compressione del codice.
  5. Il programma deve terminare e visualizzare l'output, entro 3 secondi dall'input.
  6. La tua risposta deve accompagnare il codice non golfato, insieme alla spiegazione del codice (obbligatorio se il codice non è immediatamente ovvio per i programmatori che non hanno familiarità con il tuo linguaggio, in particolare GolfScript, J, ecc.).
  7. Includere un collegamento a un compilatore online in cui è possibile testare il programma.

punteggio:

La risposta con la lunghezza di codice più bassa in caratteri, inclusi spazi bianchi, tabulazioni, ecc. Vince! Il vincitore sarà dichiarato il 21 maggio 2014.

EDIT : 21/05/14 Il vincitore è aditsu usando il linguaggio CJam . Il secondo classificato segue jpjacobs con il linguaggio J , mentre il secondo classificato è primo con il linguaggio Perl . Complimenti a tutti!


(Nota Mod: commenti commentati. Per favore, inviami un ping per qualsiasi informazione persa che potresti desiderare; sembra che dopo il mio avvertimento in anticipo, tutto si è fatto strada nella domanda però.)
Maniglia della porta

Nel primo paragrafo, dovrebbe essere "sinusoidale", non "sin"
Non che Charles

È "Round al più vicino" ancora un requisito, o possiamo usare qualsiasi built-in arrotondamento strutture? ad es. arrotondare verso zero?
Digital Trauma,

Richiedere l'equivalente di mod 2piun'operazione per far convergere gli input più velocemente sarebbe piuttosto utile: è uno dei molti miglioramenti che il mondo reale usa quando si occupa di queste funzioni. (in realtà mod pi e firma consapevolezza).
Floris,

1
@Floris Non l'ho mai saputo. Bene, non possiamo fare nulla ora, le regole sono già cambiate molto e non voglio continuare a cambiarle per infastidire ulteriormente i rispondenti. Grazie per il suggerimento però!
Gaurang Tandon,

Risposte:


6

CJam - 42

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

Provalo online su http://cjam.aditsu.net

Spiegazione:

rlegge un token dall'input
dconverte in doppi
:Xassegnamenti alla variabile X
;pop il valore dallo stack
1mette 1 nello stack (il primo termine)
_duplica il 1
rlegge il token successivo (la n)
iconverte in intero
2*,1>{...}/è una specie di loop da 1 a 2 * n - 1:
- 2*moltiplica per 2
- ,crea un array da 0 a (ultimo valore) -1
- 1>rimuove il primo elemento dell'array (0)
- {...}/esegue il blocco per ciascun elemento dell'array
_duplica il "loop variabile "(chiamiamolo k)
2%2*(converte da pari / dispari a -1/1:
- 2%è modulo 2 (-> 0/1)
- si 2*moltiplica per 2 (-> 0/2)
-(i decrementi (-> -1/1) si
*moltiplicano, cambiando così il segno ogni seconda volta che
/divide il termine in pila per k o -k; questo è il "/ k!" parte del calcolo insieme al cambio di segno si
X*moltiplica per X; questa è la parte "X ^ k" del calcolo; abbiamo ottenuto che il termine successivo nella serie
_duplica il termine da utilizzare per calcolare il termine seguente nella successiva iterazione
;(dopo il ciclo). L'ultimo termine duplicato
]raccoglie i termini sullo stack in un array.
A questo punto abbiamo un array [ 1 X -X ^ 2/2! -X ^ 3/3! X ^ 4/4! X ^ 5/5! ...] contenente esattamente tutti i termini di cui abbiamo bisogno per cos (x) e sin (x), interlacciato
2/divide questo array in coppie
ztraspone la matrice, risultando nella matrice con i termini per cos (x) e la matrice con i termini per sin (x), poiché "righe di matrice"
{...}/esegue nuovamente il blocco per ciascun elemento di matrice (riga di matrice):
- :+aggiunge gli elementi della riga matrice insieme
- 6mOarrotondamenti a 6 decimali
A questo punto abbiamo il cos (x) e sin (x) desiderati nella pila
pstampa la rappresentazione dell'ultimo elemento nella pila (sin (x)) seguito da una nuova riga
At Alla fine del programma, i contenuti rimanenti della pila (cos (x)) vengono stampati automaticamente.


1
+1 per avermi fatto conoscere una lingua di cui non ho mai sentito parlare e che probabilmente non userò mai.
Alex A.,

@Alex grazie, CJam è un po 'come GolfScript sugli steroidi
aditsu,

Non mi piace cambiare le regole dopo aver postato la domanda, ma ho vietato i caratteri Unicode di compressione del codice, poiché non sapevo che i caratteri Unicode potessero essere usati per comprimere il codice. Al momento è possibile utilizzare solo caratteri ASCII. Modifica il tuo post. Scusa per l'inconveniente.
Gaurang Tandon,

@GaurangTandon Neanche a me piace molto. Per cos'altro pensavi che i caratteri cinesi potessero essere usati in questo problema? Ad ogni modo, modificato.
aditsu,

18

Perl - 72 byte

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

Oppure, contando le opzioni della riga di comando come 1 byte ciascuna, in 70 byte :

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

Oppure, se mi permetti Perl 5.8, in 63 byte :

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

ma perché dovresti.

Modifica : conformità alle nuove regole. %fArrotonda a 6 posti di default, com'è conveniente!


Algoritmo

Esame della serie Taylor per sin (x) :

si può vedere che ogni termine divide uniformemente ogni termine successivo. Per questo motivo, può essere trasformato piuttosto facilmente in un'espressione nidificata:

cos (x) si trasforma in modo simile, senza la x iniziale , e i termini denominatore sono più piccoli.

Inoltre, questa espressione nidificata può essere riformulata come espressione ricorsiva inversa:

con s = 0 e sin (x) = x · s 1 , che è in definitiva ciò che viene utilizzato.


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);

Esempio di utilizzo

$ 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 vuoi testarlo online, ti consiglio di usare compileonline.com . Copia e incolla il codice in main.pl, quindi l'input nella STDINcasella, quindi Execute Script.


2
Che modo subdolo per analizzare l'input ... posso usarlo nella mia soluzione? :)
Tal

@Tal Sentiti libero.
primo

2
Penso che il perl (e in particolare il tuo codice) sia considerato "non immediatamente ovvio per i programmatori che non hanno familiarità con il tuo linguaggio"
aditsu,

1
@aditsu Concordato. Aggiungerò del codice più pulito e una spiegazione dell'algoritmo.
primo

2
Questa risposta è stata davvero estremamente 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)

Fondamentalmente lo stesso codice. Salviamo due personaggi dal non aver bisogno di parentesi printma ne perdiamo quattro dal bisogno raw_input.

Esecuzione del campione

Puoi eseguirli qui .

>>>
20 20
-5364.411846
-10898.499385

Spiegazione del codice

L'idea principale è di calcolare i 2*ntermini di e^(ix), e quindi prendere la parte immaginaria e reale per ottenere i valori sine cosapprossimati ai ntermini. Usiamo il troncamento della serie Taylor:

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

Questo è polinomiale in i * x, ma piuttosto che calcolare il suo valore sommando ogni termine, usiamo un metodo di Horner modificato per calcolare la sequenza (definita ricorsivamente al contrario)

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

che dà t_1uguagliando il valore desiderato.

Le operazioni di formattazione della stringa Python vengono utilizzate per ottenere i valori da visualizzare arrotondati fino a 6 cifre decimali.

Modifica: modificato per arrotondare a 6 cifre secondo le nuove regole. Non sono state necessarie altre modifiche.


Prova ideone per un interprete py3 online :)
Harry Beadle

@BritishColour Grazie! L'ho aggiunto al post.
xnor

Aggiorna la tua risposta. Vedi i dettagli in questione. Grazie.
Gaurang Tandon,

8

J 98 70 69 58

Anche se questo può probabilmente essere abbreviato un po 'usando funzioni più fantasiose ... i commenti sono ben accetti:

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

nota 2: l'ingresso termina quando si riceve EOF (ctrl-D in linux). Edit: unire elevamento a potenza e fattoriale in un posto più bello, più J-ish intero: ($ %&(*/) >:@i.@[ ). Questo si riduce a prendere una matrice di repliche x di y e una matrice dei numeri da 1 a y. Moltiplicare ciascuno e dividere il risultato. Questo elimina il duplicato */.

Grazie ad algortihmshark, altri 7 caratteri.

Taglio eliminato per sbarazzarsi della newline finale.

Versione più lunga, per la quale è indispensabile conoscere le forcelle.

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''

Non esiste un interprete J online, ma è open source da alcuni anni; l'installazione è semplice con queste istruzioni:

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

Su #jsoftware su irc.freenode.org, c'è anche un bot J.

stdin funziona solo quando eseguito da un file, dalla riga di comando, altrimenti sostituisce stdin ''con 'a b;'dove aeb sono i numeri che sarebbero stati passati sulla riga di comando.


5
Mi piace che si comincia conexit
Digital Trauma

Aggiorna la tua risposta. Vedi i dettagli in questione. Grazie.
Gaurang Tandon,

Aggiornato per le 6 cifre decimali. Se c'è qualcos'altro, specifica. Grazie
jpjacobs,

È possibile rimuovere il &da 0j6&":per salvare un carattere. Inoltre, (i.@(,&_2)@{:($%&(*/)>:@i.@[)"0{.)può essere riscritto (($%&(*/)1+i.@[)"0~i.@,&_2)/per un altro 6.
algoritmo

Questo compito grida T.(funzione approssimativa della serie n-term di Taylor), ma penso che sia verboten come una scappatoia standard.
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

La prima riga legge l'input e usa regex per trovare uno spazio; questo mette automaticamente il valore prima dello spazio in $ `e il valore dopo in $ '.

Ora passiamo da 1 a 2*n-1. $tè il nostro termine, che il ciclo moltiplica xe divide ripetutamente per l'indice del ciclo ( $_). Il ciclo inizia da 1 invece di 0 perché il coseno è inizializzato su 1, il che mi ha risparmiato di dover affrontare la divisione per zero.

Dopo l'aggiornamento $t, l'operatore trinario restituisce uno $sineo $cosine, a seconda che l'indice sia pari o dispari, e aggiunge $til valore ad esso. La formula magica $_&2?-$t:$tindica se aggiungere o sottrarre questo valore (fondamentalmente usando un bit-e sull'indice e 2 per generare la sequenza ripetitiva di "aggiungi, aggiungi, sottrai, sottrai").

Puoi testare questo codice su compileonline.com .


Correggi l'output di 20 20.
Gaurang Tandon,

1
Penso che il tuo ciclo for potrebbe dover andare 1..$n*2-1, invece di 1..$n. Mentre sono qui ... $sva benissimo lasciato non inizializzato, come undefvaluta 0in un contesto numerico. Assegnazione ternario non ha bisogno di parentesi: $_&1?$s:$c+=$t. "%.8f\n%.8f"può essere abbreviato in "%.8f\n"x2, a seguito dell'aggiunta di una nuova riga finale.
primo

@Primo Grazie, non ne sapevo nulla. E ora produce anche il risultato corretto.
Tal,

@Tal Piacere mio. Inoltre, magia leggermente migliore: $t*(1-($_&2))=> $_&2?-$t:$t.
primo

Aggiorna la tua risposta. Vedi i dettagli in questione. Grazie.
Gaurang Tandon,

5

Fortran: 89 109 125 102 101 98 byte

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 della digitazione implicita, ma sfortunatamente non esiste un tipo così implicito complesso, quindi ho dovuto specificare questo e il complesso i. Gfortran taglia l'output con 8 cifre decimali in modo naturale, quindi siamo bravi su quella specifica. Sfortunatamente, il mio metodo di output originale print*,tnon soddisfaceva le specifiche, quindi ho dovuto aggiungere 16 caratteri per produrre i componenti immaginari e reali e raggiungere gli 8 decimali richiesti.

Grazie a Ventero, sono riuscito a salvare 23 byte tra l'output e il loop. E un altro personaggio per ottenere risposte corrette e output formattato. E altri 3 sull'affermazione read.

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

Aggiorna la tua risposta. Vedi i dettagli in questione. Grazie!
Gaurang Tandon,

1
@GaurangTandon: probabilmente dovresti smettere di cambiare i dettagli del problema.
Kyle Kanos,

Lo so e non voglio, ma non posso farci niente. In realtà, dopo aver testato 5 risposte, si è scoperto che quasi tutti stavano dando risultati diversi (questo era davvero completamente insospettato). Avrei potuto seguire un altro approccio, ma ciò avrebbe richiesto il completo cambiamento degli algoritmi delle risposte correnti. Questo è il migliore che ho potuto capire.
Gaurang Tandon,

2
Beh, so che il mio funziona perfettamente, quindi dovrei assolutamente ottenere l'assegno: 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);}

Per salvare un byte, le istruzioni che aggiornano il valore del seno vengono inserite all'interno for()dell'istruzione, ma vengono effettivamente eseguite dopo le istruzioni che seguono la parentesi di chiusura che aggiorna il valore del coseno. (Suppongo che potrei anche salvare un paio di byte in più rimuovendo il carattere di nuova riga finale nell'output del programma.)

Le variabili globali s, c, re xsono implicitamente inizializzato a zero, e iavrà un valore di 1 fino a quando non ci sono argomenti forniti sulla linea di comando. Sfortunatamente il printf()valore predefinito è 6 cifre decimali, quindi il formato di output è un po 'dettagliato.

Ungolfed:

Ecco il codice con un po 'di riarrangiamento per rendere più chiaro l'ordine in cui le cose sono fatte:

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);
}

Uscita campione:

$ echo 1.23 4 | ./sincos
0.94247129
0.33410995

Provalo online:

http://ideone.com/URZWwo


3

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

Un po 'semplice da morire. Utilizza la formula della domanda parametrizzata per seno e coseno.

Interprete online può essere trovato Qui Qui

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))

Modifica: versione valida con tutte le restrizioni

Edit2: Interprete online modificato in ideone.com a causa dell'output della roundfunzione non valido in Python 2.7.1

Edit3: ho scoperto che ho usato lambda inline non necessaria + ho cambiato l'arrotondamento nel formato stringa (rubato da xnor :))

Edit4: sostituito joincon forloop principale non funzionale


Buongiorno, ho recentemente modificato le regole che ora non consentono agli operatori integrati di essere esponenziali (questo è ciò **che sto facendo suppongo). Quindi, penso che dovrai modificare la tua risposta. Scusa per l'inconveniente. Perfavore, correggimi se sbaglio.
Gaurang Tandon,

1
Immagino che ulteriori modifiche siano inutili con la risposta di xnor :)
Avall

@avail On 20 20, ottengo l'output -5364.4118142500001. Potrebbe voler aggiustarlo a 8 decimali.
Gaurang Tandon,

È a causa di repl.it versione di Python 2.7.1. Se lo esegui su ideone.com (Python 2.7.3) funziona correttamente. ideone.com/JsYNNK
avall

Funziona bene ora! +1
Gaurang Tandon,

3

JavaScript - 114 caratteri

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))

Basato sulla grande risposta di James. Stesso algoritmo, primo passo evitato con l'inizializzazione di c = 1 e s = x. L'uso di 2 var invece di un array per l'output semplifica il 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))     

Errore di battitura minore: sarebbe s += (l *= x / ++d)e non s += (l* = x / ++d)nel codice non salvato.
Gaurang Tandon,

1
@GaurangTandon fixed
edc65

2

JavaScript (ECMAScript 6 Draft) - 97 96 caratteri

Una soluzione ricorsiva:

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))

Produzione:

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

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

Tuttavia, ciò non soddisfa le specifiche relative all'arrotondamento.
Martin Ender,

@ m.buettner fixed
MT0

1
Non soddisfa il formato e i no functionsrequisiti di input .
Avall

Aggiorna la tua risposta. Vedi i dettagli in questione. Grazie.
Gaurang Tandon,

2

C, 114

Reputazione insufficiente per commentare, ma oltre alla risposta C di Squeamish Offisrage , riduzione di 7 byte usando float per raddoppiare e rimuovere spazi, e combinando dichiarazione e init di 'r' si ottiene

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);}

prova qui .


Benvenuti nella programmazione di puzzle e code golf. Ben fatto per riconoscere che la tua risposta è un piccolo miglioramento su @ squeamishossifrage (sono ancora riuscito a scriverlo male nella mia modifica.) Meglio non fare riferimento alla risposta "sopra" perché l'ordine cambia ogni volta che c'è una modifica. A proposito, ho notato l'inizializzazione rnella dichiarazione. Non ho testato per vedere se floatoffre la precisione richiesta.
Level River St,

@steveverrill Nemmeno io pensavo che floatavrebbe dato la precisione richiesta, ma funziona :) E benvenuto in PPCG, user2702245!
Gaurang Tandon,

Sono solo io a ottenere le risposte sbagliate con le floatvariabili? Per x=5e n=3, ottengo sin(x)=10.20833206e cos(x)=14.54166412:-( (Intel Core Duo, nel caso te lo stessi chiedendo)
ossifrage schizzinoso

Vorresti che lo convertissi in un commento su detta risposta?
Maniglia della porta

Anche @Doorknob può lasciarlo ora :-)
ossifrage schizzinoso

2

GNU bc, pilotato da bash, 128 byte

Troppi byte spesi per impostare i decimali e l'arrotondamento più vicino. Oh bene, eccolo qui:

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"

Produzione:

$ ./trig.sh 5 3
10.208333
14.541667
$ ./trig.sh 8.555 13
0,765,431 mila
-.641092
$ ./trig.sh 9.26 10
-3,154677
-8,404354
$ ./trig.sh 6.54 12
0,253,986 mila
0,967,147 mila
$ ./trig.sh 5 1
5.000000
1.000000
$ ./trig.sh 20 20
-5.364,411,846 mila
-10.898,499,385 mila
$ 

Strumenti da riga di comando di Linux, 97 caratteri unicode

Risposta di hacking Unicode rimossa su richiesta dell'OP. Guarda la cronologia delle modifiche se ti interessa.


Non mi piace cambiare le regole dopo aver postato la domanda, ma ho vietato i caratteri Unicode di compressione del codice, poiché non sapevo che i caratteri Unicode potessero essere usati per comprimere il codice. Al momento è possibile utilizzare solo caratteri ASCII. Modifica il tuo post.
Ci

@GaurangTandon Non è proprio la compressione: la versione unicode in realtà richiede più byte (ma meno caratteri). Ma sono d'accordo con il tuo sentimento: in realtà preferisco che il punteggio sia rigorosamente fatto usando il conteggio dei byte, ma non ho resistito al bit sui caratteri cinesi nel tuo OP.
Digital Trauma,


@avall Oops. Mi è costato 4 byte.
Trauma digitale,

1

Ruby, 336

Probabilmente il più lungo qui, ma sono sicuro che potrebbe essere abbreviato :(

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 caratteri

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]))

Utilizza una funzione qper fattoriale, iesponenziale e pper eseguire sia sine cos. Corri su jsbin.com. Utilizza esattamente la formula senza alcuna modifica.

EDIT : 8posizioni decimali modificate in posizioni 6decimali. 15 / Maggio / 14

Codice 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 caratteri

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));

L'input deve essere due numeri interi separati da spazio, non in due diverse finestre di dialogo. Per favore, sistemalo.
Gaurang Tandon,

@GaurangTandon risolto - grazie per averlo sottolineato
James,


1

Rubino - 160 152 140 caratteri

Usando la ricorsione e il fatto che per questa implementazione ricorsiva sin (x, 2n + 1) = 1 + cos (x, 2n - 1), essendo sin (x, n) e cos (x, n) la serie definita sopra per cos x e sin 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]

Modifica: contributo di commentatori (leggi sotto).


1
È possibile salvare un sacco di caratteri utilizzando lambda: p=->x,n{...}, f=->n{...}e così via, e quindi utilizzare le parentesi quadre al posto delle parentesi per chiamarli, come p[x,n-1]. Inoltre, penso che collectsia solo un alias per map, che è molto più breve, e poiché stai mappando solo una chiamata del membro, puoi accorciarla gets.split.map &:to_f.
Martin Ender,

@ MartinBüttner Grazie! Aggiungerò questo! (spero che il tuo commento qui affermi che questa soluzione non è solo mia, ma collab) Ad essere sincero: sono anche nuovo di Ruby (solo 2 mesi) :)))
Boriel
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.