Biarkan trigonometri dimulai!


20

Pengantar:

The sinus dari xdiberikan oleh rumus:

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

The cosinus dari xdiberikan oleh rumus:

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

Tugas:

Diberi nilai xdan n, tulis sebuah program (tidak ada fungsi, dll.) Untuk menampilkan nilai sin(x)dan cos(x)memperbaiki nketentuan rumus di atas. Anggap itu xdalam radian.

Memasukkan:

x n

Angka desimal x(dengan hingga 3 tempat desimal) dan bilangan bulat n. Masukan harus di stdin atau kotak dialog prompt (jika bahasa Anda tidak mendukung stdin)

Keluaran:

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

Nilai keduanya sin(x)dan cos(x)harus dibulatkan ke 6 tempat desimal. Jika sin(x)ini 0.5588558855(10 digit desimal), itu harus dibulatkan ke 0.558856(6 digit desimal). Pembulatan harus dilakukan ke yang terdekat, seperti yang dijelaskan dalam kolom kelima, "Bulatkan ke yang terdekat", dari tabel di artikel Wiki ini .

Kendala:

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

Sampel:

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

Catatan:

  1. Celah standar dilarang.
  2. Fungsi matematika bawaan dan operator trigonometri (sin, cos, tan, dll.), Faktorial, dan eksponensial tidak dapat digunakan. Anda bebas menggunakan fungsi pembulatan bawaan untuk memperkirakan hasil komputasi sin(x)dan cos(x)ke angka desimal ke-6.
  3. Tidak perlu menangani input yang salah.
  4. Hanya karakter ASCII yang dapat digunakan dalam program, bukan karakter Unicode Cina yang memungkinkan kompresi kode.
  5. Program Anda harus menghentikan, dan menampilkan output, dalam 3 detik input.
  6. Jawaban Anda harus menyertai kode yang tidak disatukan, bersama dengan penjelasan kode (wajib jika kode tidak segera jelas bagi programmer-tidak-akrab-dengan-bahasa Anda, terutama GolfScript, J, dll).
  7. Harap sertakan tautan ke kompiler online tempat program Anda dapat diuji.

Mencetak:

Jawaban dengan panjang kode terendah dalam karakter, termasuk spasi, tab, dll. Menang! Pemenang akan diumumkan pada 21 Mei 2014.

EDIT : 21/05/14 Pemenang adalah aditsu menggunakan bahasa CJam . Runner up mengikuti jpjacobs dengan bahasa J , dan runner up kedua primo dengan bahasa Perl . Selamat semua!


(Mod note: comments nuked. Harap ping saya untuk informasi yang hilang yang mungkin Anda inginkan; sepertinya setelah peringatan saya sebelumnya, semuanya masuk ke pertanyaan.)
Gagang Pintu

Dalam paragraf pertama, itu harus "sinus", bukan "dosa"
Bukan berarti Charles

Apakah "Putaran ke terdekat" masih merupakan persyaratan, atau bisakah kita menggunakan fasilitas pembulatan bawaan? misal, bulat menuju nol?
Trauma Digital

Membutuhkan operasi yang setara mod 2piuntuk membuat input bertemu lebih cepat akan lebih bermanfaat - ini adalah salah satu dari banyak perbaikan yang digunakan dunia nyata ketika berhadapan dengan fungsi-fungsi ini. (Sebenarnya mod pi dan tanda kesadaran).
Floris

1
@ Floris Saya tidak pernah tahu ini. Yah, kita tidak bisa melakukan apa-apa sekarang, peraturannya sudah banyak berubah, dan saya tidak ingin terus mengubahnya untuk lebih mengganggu penjawab. Terima kasih untuk sarannya!
Gaurang Tandon

Jawaban:


6

CJam - 42

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

Cobalah online di http://cjam.aditsu.net

Penjelasan:

rmembaca token dari input
dconvert to double
:Xassigns ke variabel X
;muncul nilai dari stack
1menempatkan 1 pada stack (istilah pertama)
_menduplikasi 1
rmembaca token berikutnya (n)
imengkonversi ke integer
2*,1>{...}/adalah semacam loop dari 1 hingga 2 * n - 1:
- 2*dikalikan 2
- ,membuat array dari 0 hingga (nilai terakhir) -1
- 1>menghapus item pertama dari array (0)
- {...}/mengeksekusi blok untuk setiap item dalam array
_menduplikasi "loop" variabel "(sebut saja k)
2%2*(mengonversi dari even / odd ke -1/1:
- 2%adalah modulo 2 (-> 0/1)
- 2*dikalikan dengan 2 (-> 0/2)
-(decrements (-> -1/1)
*mengalikan, dengan demikian mengubah tanda setiap detik
/membagi istilah pada stack dengan k atau -k; ini adalah "/ k!" bagian dari perhitungan bersama dengan tanda perubahan
X*dikalikan dengan X; ini adalah bagian "X ^ k" dari perhitungan; kami memperoleh istilah berikutnya dalam seri
_duplikat istilah yang akan digunakan untuk menghitung istilah berikut dalam iterasi berikutnya
;(setelah loop) muncul istilah duplikat terakhir
]mengumpulkan istilah pada tumpukan di dalam array.
Pada titik ini kami memiliki array [ 1 X -X ^ 2/2! -X ^ 3/3! X ^ 4/4! X ^ 5/5! ...] berisi persis semua istilah yang kita butuhkan untuk cos (x) dan sin (x), yang disatukan
2/membagi array ini menjadi pasangan
ztransposes matriks, menghasilkan array dengan syarat untuk cos (x) dan array dengan syarat untuk sin (x), sebagai "baris matriks"
{...}/lagi mengeksekusi blok untuk setiap item array (baris matriks):
- :+menambahkan elemen dari baris matriks bersama
- 6mObulat ke 6 desimal
Pada titik ini kita memiliki cos (x) dan sin (x) yang diinginkan pada stack
pmencetak representasi item terakhir pada stack (sin (x)) diikuti oleh baris baru
At akhir program, isi tumpukan yang tersisa (cos (x)) dicetak secara otomatis.


1
+1 untuk memperkenalkan saya ke bahasa yang belum pernah saya dengar dan mungkin tidak akan pernah digunakan.
Alex A.

@Alex terima kasih, CJam agak seperti GolfScript tentang steroid
aditsu

Saya tidak suka mengubah aturan setelah memposting pertanyaan, tetapi saya telah melarang kode-kompresi-memungkinkan-karakter Unicode, karena saya tidak tahu karakter Unicode dapat digunakan untuk mengompresi kode. Hanya karakter ASCII yang dapat digunakan sekarang. Harap edit posting Anda. Maaf atas ketidaknyamanan
Gaurang Tandon

@ GaurangTandon Saya juga tidak terlalu menyukainya. Menurut Anda, apa karakter Cina yang dapat digunakan untuk masalah ini? Pokoknya diedit.
aditsu

18

Perl - 72 byte

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

Atau, menghitung opsi baris perintah masing-masing 1 byte, dalam 70 byte :

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

Atau, jika Anda mengizinkan saya Perl 5.8, dalam 63 byte :

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

tapi mengapa kamu mau.

Sunting : Kepatuhan dengan aturan baru. %fberkeliling ke 6 tempat secara default, betapa nyamannya!


Algoritma

Meneliti deret Taylor untuk dosa (x) :

dapat dilihat bahwa setiap istilah secara merata membagi setiap istilah yang berurutan. Karena itu, ini dapat ditransformasikan dengan mudah menjadi ekspresi bersarang:

cos (x) mentransformasikannya dengan cara yang sama, tanpa x terkemuka , dan istilah penyebutnya lebih kecil.

Selain itu, ekspresi bersarang ini dapat diformulasi ulang sebagai ekspresi rekursif terbalik:

dengan s = 0 dan sin (x) = x · s 1 , yang pada akhirnya adalah apa yang digunakan.


Tidak disatukan

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

Contoh Penggunaan

$ 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

Jika Anda ingin menguji ini secara online, saya sarankan menggunakan compileonline.com . Salin-tempel kode ke main.pl, dan input ke dalam STDINkotak, lalu Execute Script.


2
Cara licik apa untuk mengurai input ... dapatkah saya menggunakannya dalam solusi saya? :)
Tal

@Tal Merasa bebas.
Primo

2
Saya pikir perl (dan terutama kode Anda) dianggap sebagai "tidak segera jelas bagi programmer-tidak-akrab-dengan-bahasa Anda"
aditsu

1
@aditsu Setuju. Saya akan menambahkan beberapa kode pembersih, dan penjelasan tentang algoritma.
Primo

2
Jawaban ini sangat mendidik!
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)

Pada dasarnya kode yang sama. Kami menyimpan dua karakter dari tidak perlu parens untuk printtetapi kehilangan empat dari membutuhkan raw_input.

Contoh dijalankan

Anda dapat menjalankan ini di sini .

>>>
20 20
-5364.411846
-10898.499385

Penjelasan kode

Gagasan utamanya adalah untuk menghitung 2*nistilah e^(ix), dan kemudian mengambil bagian imajiner dan nyata untuk mendapatkan sindan cosnilai - nilai didekati dengan nistilah. Kami menggunakan pemotongan seri Taylor:

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

Ini polinomial dalam i * x, tetapi daripada menghitung nilainya dengan menjumlahkan setiap istilah, kami menggunakan Metode Horner yang dimodifikasi untuk menghitung urutan (didefinisikan secara rekursif secara terbalik)

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

yang memberikan t_1sama dengan nilai yang diinginkan.

Operasi pemformatan string python digunakan untuk mendapatkan nilai untuk menampilkan dibulatkan hingga 6 digit desimal.

Sunting: Diubah menjadi bulat menjadi 6 digit sesuai aturan baru. Tidak ada perubahan lain yang diperlukan.


Cobalah ideone untuk penerjemah py3 online :)
Harry Beadle

@BritishColour Terima kasih! Saya telah menambahkannya ke pos.
xnor

Harap perbarui jawaban Anda. Lihat detail yang dimaksud. Terima kasih.
Gaurang Tandon

8

J 98 70 69 58

Meskipun ini mungkin dapat dipersingkat sedikit menggunakan fungsi yang lebih mewah ... komentar dipersilahkan:

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

Catatan 2: input berakhir ketika menerima EOF (ctrl-D di linux). Edit: bergabung eksponensial dan faktorial menjadi lebih bagus, lebih J-ish keseluruhan: ($ %&(*/) >:@i.@[ ). Ini intinya untuk mengambil array x replikasi y dan array angka dari 1 ke y. Lipat gandakan masing-masing dan bagi hasilnya. Ini menghilangkan duplikat */.

Berkat algortihmshark, ada 7 karakter lagi.

Potongan yang dihapus karena menyingkirkan baris baru yang tertinggal.

Versi yang lebih panjang, yang mengetahui tentang garpu adalah suatu keharusan.

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

Tidak ada penerjemah online J, tapi ini open source sejak beberapa tahun; instalasi mudah dengan instruksi ini:

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

Di #jsoftware di irc.freenode.org, ada bot J juga.

stdin hanya berfungsi ketika dijalankan dari file, dari baris perintah, atau ganti stdin ''dengan di 'a b;'mana a dan b adalah angka-angka yang akan diteruskan pada baris perintah.


5
Saya suka itu dimulai denganexit
Trauma Digital

Harap perbarui jawaban Anda. Lihat detail yang dimaksud. Terima kasih.
Gaurang Tandon

Diperbarui untuk 6 tempat desimal. Jika ada hal lain, harap jelaskan. Terima kasih
jpjacobs

Anda dapat menghapus &dari 0j6&":untuk menyimpan char. Juga, (i.@(,&_2)@{:($%&(*/)>:@i.@[)"0{.)dapat ditulis ulang (($%&(*/)1+i.@[)"0~i.@,&_2)/untuk 6. lainnya
algoritmashark

Tugas-tugas ini berteriak untuk T.(perkiraan fungsi dengan n-term seri Taylor), tapi saya pikir itu verboten sebagai celah standar.
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

Tidak Terkumpul:

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

Baris pertama membaca input dan menggunakan regex untuk menemukan spasi; ini secara otomatis menempatkan nilai sebelum spasi dalam $ `dan nilai setelahnya dalam $ '.

Sekarang kita beralih dari 1 ke 2*n-1. $tadalah istilah kami, yang loop berulang kali dikalikan xdan dibagi dengan indeks loop ( $_). Loop dimulai pada 1 daripada 0 karena cosinus diinisialisasi ke 1, yang menyelamatkan saya harus berurusan dengan pembagian dengan nol.

Setelah memperbarui $t, operator trinary mengembalikan salah satu $sineatau $cosine, tergantung pada apakah indeksnya ganjil atau genap, dan menambah $tnilai padanya. Rumus ajaib $_&2?-$t:$tangka apakah akan menambah atau mengurangi nilai ini (pada dasarnya menggunakan bitwise-dan pada indeks dan 2 untuk menghasilkan urutan berulang dari "tambah, tambah, kurangi, kurangi").

Anda dapat menguji-coba kode ini di compileonline.com .


Harap perbaiki hasil Anda 20 20.
Gaurang Tandon

1
Saya pikir untuk for loop Anda mungkin perlu beralih 1..$n*2-1, bukan 1..$n. Sementara saya di sini ... $sbaik-baik saja dibiarkan tidak diinisialisasi, seperti undefmengevaluasi 0dalam konteks numerik. Tugas terner tidak perlu kurung: $_&1?$s:$c+=$t. "%.8f\n%.8f"dapat disingkat menjadi "%.8f\n"x2, pada konsekuensi menambahkan baris baru.
Primo

@ Primo Terima kasih, saya tidak tahu tentang itu. Dan sekarang bahkan menghasilkan hasil yang benar juga.
Tal

@Tal kesenangan saya. Juga, sihir yang sedikit lebih baik: $t*(1-($_&2))=> $_&2?-$t:$t.
primo

Harap perbarui jawaban Anda. Lihat detail yang dimaksud. Terima kasih.
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

Saya menyalahgunakan pengetikan tersirat, tetapi sayangnya tidak ada jenis rumit tersirat seperti itu, jadi saya harus menentukan itu & kompleks i. Gfortran memangkas output pada 8 tempat desimal secara alami, jadi kami bagus untuk spek itu. Sayangnya, metode keluaran saya yang asli print*,t,, tidak memenuhi spesifikasi jadi saya harus menambahkan 16 karakter untuk menampilkan komponen imajiner dan nyata & menekan 8 tempat desimal yang diperlukan.

Berkat Ventero, saya berhasil menghemat 23 byte antara output dan loop. Dan karakter lain untuk mendapatkan jawaban yang benar dan output yang diformat. Dan 3 lagi pada readpernyataan itu.

Tidak disatukan,

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

Harap perbarui jawaban Anda. Lihat detail yang dimaksud. Terima kasih!
Gaurang Tandon

1
@ GaurangTandon: Anda mungkin harus berhenti mengubah detail masalah.
Kyle Kanos

Saya tahu, dan saya tidak mau, tetapi saya tidak bisa menahannya. Sebenarnya, setelah menguji 5 jawaban, ternyata hampir semua dari mereka memberikan hasil yang berbeda (ini memang sama sekali tidak terduga). Saya bisa saja mengikuti beberapa pendekatan lain, tetapi itu akan membutuhkan perubahan algoritma lengkap dari jawaban saat ini. Yang ini adalah yang terbaik yang bisa saya pikirkan.
Gaurang Tandon

2
Yah saya tahu bahwa milik saya berfungsi dengan baik, jadi saya harus benar - benar mendapatkan cek: 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);}

Untuk menyimpan byte, pernyataan yang memperbarui nilai sinus ditempatkan di dalam for()pernyataan, tetapi sebenarnya dieksekusi setelah pernyataan mengikuti tanda kurung penutup yang memperbarui nilai cosinus. (Saya kira saya juga bisa menyimpan beberapa byte lagi dengan menghapus karakter baris baru terakhir dalam output program.)

Variabel global s, c, rdan xsecara implisit diinisialisasi ke nol, dan iakan memiliki nilai 1 selama tidak ada argumen yang diberikan pada baris perintah. Sayangnya printf()standarnya adalah 6 desimal, jadi format outputnya agak bertele-tele.

Tidak Terkumpul:

Berikut kode dengan sedikit penataan ulang untuk membuat urutan di mana hal-hal dilakukan lebih jelas:

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

Output sampel:

$ echo 1.23 4 | ./sincos
0.94247129
0.33410995

Cobalah online:

http://ideone.com/URZWwo


3

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

Agak sederhana sekali. Menggunakan rumus dari pertanyaan parameter untuk sinus dan cosinus.

Penerjemah online dapat ditemukan sini sini

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

Sunting: Versi yang valid dengan semua batasan

Sunting2: Mengubah juru online ke ideone.com karena roundkeluaran fungsi tidak valid di Python 2.7.1

Sunting3: Ternyata saya menggunakan lambda inline yang tidak perlu + mengubah pembulatan ke format string (dicuri dari xnor :))

Sunting4: Diganti joindengan forloop utama yang tidak berfungsi


Halo, saya baru-baru ini mengedit aturan yang sekarang tidak mengizinkan operator built-in untuk eksponensial (itulah yang **saya lakukan). Jadi, saya pikir Anda harus mengedit jawaban Anda. Maaf atas ketidaknyamanan Tolong koreksi saya jika saya salah.
Gaurang Tandon

1
Saya kira modifikasi lebih lanjut tidak berguna dengan jawaban xnor :)
avall

@avail On 20 20, saya mendapatkan output -5364.4118142500001. Mungkin ingin memperbaikinya menjadi 8 desimal.
Gaurang Tandon

Hal ini karena repl.it versi Python 2.7.1. Jika Anda menjalankannya di ideone.com (Python 2.7.3) itu berfungsi dengan baik. ideone.com/JsYNNK
avall

Ini berfungsi dengan baik sekarang! +1
Gaurang Tandon

3

JavaScript - 114 karakter

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

Berdasarkan jawaban james yang bagus. Algoritma yang sama, langkah pertama dihindari dengan inisialisasi c = 1 dan s = x. Menggunakan 2 vars bukan array untuk output menyederhanakan loop.

Tidak disatukan

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

Kesalahan ketik kecil: Itu akan terjadi s += (l *= x / ++d)dan tidak ada s += (l* = x / ++d)dalam kode yang tidak diserang.
Gaurang Tandon

1
@GaurangTandon diperbaiki
edc65

2

JavaScript (ECMAScript 6 Draft) - 97 96 Karakter

Solusi rekursif:

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

Keluaran:

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

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

Itu tidak memenuhi spesifikasi tentang pembulatan.
Martin Ender

@ m.buettner diperbaiki
MT0

1
Itu tidak memenuhi format dan no functionspersyaratan input .
avall

Harap perbarui jawaban Anda. Lihat detail yang dimaksud. Terima kasih.
Gaurang Tandon

2

C, 114

Reputasi yang tidak memadai untuk berkomentar, tetapi lebih jauh ke jawaban C Squeamish Offisrage , reduksi 7 byte dengan menggunakan float untuk menggandakan dan menghilangkan spasi, dan menggabungkan deklarasi dan init dari 'r' memberi

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

coba di sini .


Selamat datang di teka-teki pemrograman dan golf kode. Bagus untuk mengakui bahwa jawaban Anda adalah perbaikan kecil pada @ squeamishossifrage's (saya masih berhasil mengeja salah dalam edit saya.) Terbaik untuk tidak merujuk pada jawaban "di atas" karena urutannya berubah setiap kali ada edit. BTW, saya perhatikan inisialisasi rdalam deklarasi. Saya belum diuji untuk melihat apakah floatmemberikan presisi yang dibutuhkan.
Level River St

@steveverrill Saya juga tidak berpikir floatakan memberikan presisi yang diperlukan, tetapi itu berhasil :) Dan selamat datang di PPCG, user2702245!
Gaurang Tandon

Apakah hanya saya yang mendapatkan jawaban yang salah dengan floatvariabel? Untuk x=5dan n=3, saya dapat sin(x)=10.20833206dan cos(x)=14.54166412:-( (Intel Core Duo, kalau-kalau Anda bertanya-tanya)
ossifrage mual

Apakah Anda ingin saya mengonversi ini menjadi komentar pada jawaban yang dikatakan?
Gagang Pintu

@Doorknob May tinggalkan juga sekarang :-)
squeamish ossifrage

2

GNU bc, digerakkan oleh bash, 128 byte

Terlalu banyak byte yang dihabiskan untuk mengatur tempat desimal dan pembulatan ke-terdekat. Oh well, ini dia:

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"

Keluaran:

$ ./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
0,967147
$ ./trig.sh 5 1
5.000000
1,000000
$ ./trig.sh 20 20
-5364.411846
-10898.499385
$ 

Alat baris perintah Linux, 97 karakter unicode

Jawaban hack Unicode dihapus atas permintaan OP. Lihatlah riwayat edit jika Anda tertarik.


Saya tidak suka mengubah aturan setelah memposting pertanyaan, tetapi saya telah melarang kode-kompresi-memungkinkan-karakter Unicode, karena saya tidak tahu karakter Unicode dapat digunakan untuk mengompresi kode. Hanya karakter ASCII yang dapat digunakan sekarang. Harap edit posting Anda. Maaf atas ketidaknyamanan ini
Gaurang Tandon

@ GaurangTandon Ini bukan kompresi - versi unicode sebenarnya membutuhkan lebih banyak byte (tetapi lebih sedikit karakter). Tapi saya setuju dengan sentimen Anda - Saya sebenarnya lebih suka mencetak dilakukan dengan benar menggunakan hitungan byte, tetapi tidak bisa menahan sedikit tentang karakter Cina di OP Anda.
Digital Trauma

Anda menggunakan operator eksponensial ilegal
Avall

@avall Ups. Harganya 4 byte.
Trauma Digital

1

Ruby, 336

Mungkin yang terpanjang di sini, tapi saya yakin itu bisa dibuat lebih pendek :(

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 karakter

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

Menggunakan fungsi q untuk faktorial, iuntuk eksponensial, dan puntuk melakukan keduanya sindan cos. Jalankan di jsbin.com. Menggunakan formula persis tanpa modifikasi apa pun.

EDIT : Mengubah 8tempat 6desimal ke tempat desimal. 15 / Mei / 14

Kode Tidak Terkunci :

/*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 karakter

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

Tidak disatukan

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

Input harus berupa dua bilangan bulat yang dipisahkan oleh spasi, bukan dalam dua kotak dialog yang berbeda. Tolong perbaiki itu.
Gaurang Tandon

@GaurangTandon memperbaiki - terima kasih telah menunjukkannya
James


1

Ruby - 160 152 140 Karakter

Menggunakan rekursi dan fakta bahwa untuk implementasi implementasi rekursif ini dosa (x, 2n + 1) = 1 + cos (x, 2n - 1), menjadi sin (x, n) dan cos (x, n) seri yang ditentukan di atas untuk cos x dan dosa 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]

Sunting: Dikontribusikan oleh komentator (baca di bawah).


1
Anda dapat menyimpan banyak karakter dengan menggunakan lambdas: p=->x,n{...}, f=->n{...}dan sebagainya, dan kemudian menggunakan kurung bukan kurung untuk memanggil mereka, seperti p[x,n-1]. Juga, saya pikir collectitu hanya alias untuk map, yang jauh lebih pendek, dan karena Anda hanya memetakan panggilan anggota, Anda dapat mempersingkatnya menjadi gets.split.map &:to_f.
Martin Ender

@ MartinBüttner Terima kasih! Akan menambahkan ini! (harap komentar Anda di sini menyatakan bahwa solusi ini bukan hanya milik saya, tetapi collab) Sejujurnya: Saya juga baru
mengenal
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.