Hãy để lượng giác bắt đầu!


20

Giới thiệu:

Các sin của xđược cho bởi công thức:

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

Các cosin của xđược cho bởi công thức:

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

Bài tập:

Cho giá trị của xn, viết chương trình (không có hàm, v.v.) để xuất giá trị sin(x)cos(x)sửa ncác điều khoản của công thức trên. Giả sử đó xlà bằng radian.

Đầu vào:

x n

Một số thập phân x(có tối đa 3 chữ số thập phân) và một số nguyên n. Đầu vào phải ở trên stdin hoặc hộp thoại nhắc (nếu ngôn ngữ của bạn không hỗ trợ stdin)

Đầu ra:

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

Giá trị của cả hai sin(x)cos(x)nên được làm tròn đến 6 chữ số thập phân. Nếu sin(x)0.5588558855(10 chữ số thập phân), thì nó phải được làm tròn thành 0.558856(6 chữ số thập phân). Việc làm tròn phải diễn ra gần nhất, như được mô tả trong cột thứ năm, "Làm tròn đến gần nhất", của bảng trong bài viết Wiki này .

Các ràng buộc:

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

Mẫu:

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

Ghi chú:

  1. Sơ hở tiêu chuẩn bị cấm.
  2. Các hàm toán học tích hợp và toán tử lượng giác (sin, cos, tan, v.v.), giai thừa và lũy thừa có thể được sử dụng. Bạn có thể tự do sử dụng chức năng làm tròn tích hợp để ước tính kết quả tính toán sin(x)cos(x)đến chữ số thập phân thứ 6.
  3. Không cần xử lý sai đầu vào.
  4. Chỉ các ký tự ASCII có thể được sử dụng trong chương trình, không phải các ký tự Unicode tiếng Trung cho phép nén mã.
  5. Chương trình của bạn phải chấm dứt và hiển thị đầu ra, trong vòng 3 giây kể từ khi nhập.
  6. Câu trả lời của bạn phải đi kèm với mã không được mã hóa, cùng với phần giải thích mã (bắt buộc nếu mã không rõ ràng ngay lập tức đối với các lập trình viên không quen thuộc với ngôn ngữ của bạn, đặc biệt là GolfScript, J, v.v.).
  7. Vui lòng bao gồm một liên kết đến một trình biên dịch trực tuyến nơi chương trình của bạn có thể được kiểm tra.

Ghi điểm:

Câu trả lời với độ dài mã thấp nhất trong các ký tự, bao gồm khoảng trắng, tab, v.v ... sẽ thắng! Người chiến thắng sẽ được tuyên bố vào ngày 21 tháng 5 năm 2014.

EDIT : 21/05/14 Người chiến thắng là aditsu sử dụng ngôn ngữ CJam . Á quân đi theo jpjacobs với ngôn ngữ J , và Á hậu thứ hai là nguyên thủy với ngôn ngữ Perl . Chúc mừng tất cả!


(Ghi chú của Mod: các bình luận bị cấm. Vui lòng ping tôi cho bất kỳ thông tin bị mất nào mà bạn muốn; có vẻ như sau cảnh báo của tôi trước, mọi thứ đều đi vào câu hỏi.)
Doorknob

Trong đoạn đầu tiên, nó phải là "sin", không phải "tội lỗi"
Không phải là Charles

"Round đến gần nhất" vẫn còn là một yêu cầu, hoặc chúng ta có thể sử dụng bất kỳ được xây dựng tại các cơ sở làm tròn? vd: tròn về không?
Chấn thương kỹ thuật số

Yêu cầu tương đương với một mod 2pihoạt động để làm cho các đầu vào hội tụ nhanh hơn sẽ khá hữu ích - đó là một trong nhiều cải tiến mà thế giới thực sử dụng khi xử lý các chức năng này. (thực sự mod pi và nhận biết dấu hiệu).
Floris

1
@Floris Tôi chưa bao giờ biết điều này. Chà, chúng ta không thể làm bất cứ điều gì bây giờ, các quy tắc đã thay đổi nhiều và tôi không muốn tiếp tục thay đổi chúng để làm phiền thêm người trả lời. Nhờ đề nghị mặc dù!
Gaurang Tandon

Câu trả lời:


6

CJam - 42

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

Dùng thử trực tuyến tại http://cjam.aditsu.net

Giải trình:

rđọc mã thông báo từ đầu vào
dchuyển đổi thành hai lần
:Xgán cho biến X
;bật giá trị từ ngăn xếp
1đặt 1 trên ngăn xếp (thuật ngữ đầu tiên)
_sao chép 1
rđọc mã thông báo tiếp theo (n)
ichuyển đổi sang số nguyên
2*,1>{...}/là một loại vòng lặp từ 1 đến 2 * n - 1:
- 2*nhân với 2
- ,tạo một mảng từ 0 đến (giá trị cuối cùng) -1
- 1>xóa mục đầu tiên của mảng (0)
- {...}/thực thi khối cho mỗi mục trong mảng
_nhân đôi "vòng lặp" biến "(hãy gọi nó là k)
2%2*(chuyển đổi từ chẵn / lẻ thành -1/1:
- 2%là modulo 2 (-> 0/1)
- 2*nhân với 2 (-> 0/2)
-(số thập phân (-> -1/1)
*nhân lên, do đó thay đổi dấu hiệu mỗi lần thứ hai
/chia số hạng trên ngăn xếp cho k hoặc -k; đây là "/ k!" một phần của phép tính cùng với sự thay đổi dấu
X*nhân nhân với X; đây là phần "X ^ k" của phép tính; chúng tôi đã thu được thuật ngữ tiếp theo trong chuỗi
_trùng lặp thuật ngữ được sử dụng để tính toán thuật ngữ sau trong lần lặp tiếp theo
;(sau vòng lặp) bật ra thuật ngữ trùng lặp cuối cùng
]thu thập các thuật ngữ trên ngăn xếp trong một mảng
Tại thời điểm này, chúng tôi có một mảng [ 1 X -X ^ 2/2! -X ^ 3/3! X ^ 4/4! X ^ 5/5! ...] chứa chính xác tất cả các thuật ngữ chúng ta cần cho cos (x) và sin (x), xen kẽ
2/chia mảng này thành các cặp
zhoán đổi ma trận, dẫn đến mảng có các thuật ngữ cho cos (x) và mảng với các thuật ngữ cho sin (x), vì "hàng ma trận"
{...}/một lần nữa thực thi khối cho từng mục mảng (hàng ma trận):
- :+thêm các phần tử của hàng ma trận với nhau
- làm 6mOtròn đến 6 số thập phân
Tại thời điểm này, chúng ta có cos (x) và sin (x) mong muốn trên ngăn xếp
pin đại diện của mục cuối cùng trên ngăn xếp (sin (x)) theo sau là một dòng mới
Tại kết thúc chương trình, các nội dung còn lại của ngăn xếp (cos (x)) được in tự động.


1
+1 để giới thiệu cho tôi một ngôn ngữ mà tôi chưa từng nghe đến và có lẽ sẽ không bao giờ sử dụng.
Alex A.

@Alex cảm ơn, CJam có phần giống GolfScript trên steroid
aditsu

Tôi không thích thay đổi quy tắc sau khi đăng câu hỏi, nhưng tôi không cho phép các ký tự Unicode cho phép nén mã, vì tôi không biết các ký tự Unicode có thể được sử dụng để nén mã. Hiện tại chỉ có thể sử dụng các ký tự ASCII. Vui lòng chỉnh sửa bài viết của bạn. Xin lỗi vì sự bất tiện này.
Gaurang Tandon

@GaurangTandon Tôi cũng không thích điều đó lắm. Bạn nghĩ gì khác về các ký tự Trung Quốc có thể được sử dụng cho vấn đề này? Dù sao, đã chỉnh sửa.
aditsu

18

Perl - 72 byte

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

Hoặc, đếm các tùy chọn dòng lệnh là 1 byte mỗi, trong 70 byte :

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

Hoặc, nếu bạn cho phép tôi Perl 5,8, trong 63 byte :

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

nhưng tại sao bạn

Chỉnh sửa : Tuân thủ các quy tắc mới. %fLàm tròn đến 6 nơi theo mặc định, thật tiện lợi!


Thuật toán

Kiểm tra loạt Taylor cho sin (x) :

có thể thấy rằng mỗi thuật ngữ chia đều cho mỗi thuật ngữ liên tiếp. Do đó, nó có thể được chuyển đổi dễ dàng thành một biểu thức lồng nhau:

cos (x) biến đổi tương tự, không có các số hạng x và mẫu số hàng đầu nhỏ hơn.

Ngoài ra, biểu thức lồng nhau này có thể được định dạng lại dưới dạng biểu thức đệ quy ngược:

với s = 0sin (x) = x · s 1 , đó là cuối cùng những gì được sử dụng.


Ung dung

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

Sử dụng mẫu

$ 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

Nếu bạn muốn kiểm tra trực tuyến này, tôi khuyên bạn nên sử dụng compileonline.com . Sao chép-Dán mã vào main.pl, và đầu vào vào STDINhộp, sau đó Execute Script.


2
Thật là một cách sai lầm để phân tích đầu vào ... tôi có thể sử dụng nó trong giải pháp của mình không? :)
Tal

@Tal Hãy thoải mái.
primo

2
Tôi nghĩ perl (và đặc biệt là mã của bạn) được tính là "không rõ ràng ngay lập tức đối với các lập trình viên không quen thuộc với ngôn ngữ của bạn"
aditsu

1
@aditsu Đồng ý. Tôi sẽ thêm một số mã sạch hơn và giải thích về thuật toán.
primo

2
Câu trả lời này thực sự rất giáo dục!
Tal

10

Python 3 (102) / Python 2 (104)

Con trăn 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))

Con trăn 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)

Về cơ bản cùng mã. Chúng tôi lưu hai nhân vật khỏi không cần parens printnhưng mất bốn từ cần raw_input.

Chạy mẫu

Bạn có thể chạy chúng ở đây .

>>>
20 20
-5364.411846
-10898.499385

Giải thích mã

Ý tưởng chính là tính toán 2*ncác điều khoản e^(ix)và sau đó lấy phần ảo và phần thực để lấy sincoscác giá trị gần đúng với ncác điều khoản. Chúng tôi sử dụng cắt ngắn của loạt Taylor:

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

Đây là đa thức trong i * x, nhưng thay vì tính giá trị của nó bằng cách tính tổng mỗi thuật ngữ, chúng tôi sử dụng Phương thức Horner đã sửa đổi để tính toán chuỗi (được định nghĩa theo cách đệ quy ngược)

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

mà cho t_1bằng với giá trị mong muốn.

Các hoạt động định dạng chuỗi Python được sử dụng để có được các giá trị hiển thị được làm tròn lên đến 6 chữ số thập phân.

Chỉnh sửa: Thay đổi thành tròn thành 6 chữ số theo quy tắc mới. Không có thay đổi khác là cần thiết.


Hãy thử ideone cho một trình thông dịch py3 trực tuyến :)
Harry Beadle

@BritishColour Cảm ơn! Tôi đã thêm nó vào bài viết.
xnor

Hãy cập nhật câu trả lời của bạn. Xem chi tiết trong câu hỏi. Cảm ơn.
Gaurang Tandon

8

J 98 70 69 58

Mặc dù điều này có thể được rút ngắn khá nhiều bằng cách sử dụng các chức năng lạ mắt hơn nhưng các ý kiến ​​đều được chào đón:

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

lưu ý 2: đầu vào kết thúc khi nhận EOF (ctrl-D trong linux). Chỉnh sửa: tham gia lũy thừa và giai thừa thành một tổng thể J-ish đẹp hơn : ($ %&(*/) >:@i.@[ ). Điều này sôi xuống để lấy một mảng các bản sao x của y và một mảng các số từ 1 đến y. Nhân mỗi số và chia kết quả. Điều này được loại bỏ các bản sao */.

Nhờ algortihmshark, 7 nhân vật khác tắt.

Loại bỏ cắt để thoát khỏi dòng mới.

Phiên bản dài hơn, mà biết về dĩa là phải.

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

Không có trình thông dịch J trực tuyến, nhưng nó là nguồn mở từ một vài năm; cài đặt dễ dàng với các hướng dẫn sau:

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

Trên #jsoftware trên irc.freenode.org, cũng có bot J.

stdin chỉ hoạt động khi được chạy từ một tệp, từ dòng lệnh, thay thế stdin ''bằng 'a b;'a và b là các số sẽ được truyền trên dòng lệnh.


5
Tôi thích nó bắt đầu bằngexit
Chấn thương kỹ thuật số

Hãy cập nhật câu trả lời của bạn. Xem chi tiết trong câu hỏi. Cảm ơn.
Gaurang Tandon

Cập nhật cho 6 chữ số thập phân. Nếu có cái gì khác, xin vui lòng chỉ định. Cảm ơn
jpjacobs

Bạn có thể loại bỏ &từ 0j6&":để lưu một char. Ngoài ra, (i.@(,&_2)@{:($%&(*/)>:@i.@[)"0{.)có thể được viết lại (($%&(*/)1+i.@[)"0~i.@,&_2)/cho 6. khác
thuật toán

Nhiệm vụ này hét lên T.(chức năng gần đúng của loạt Taylor n-term), nhưng tôi nghĩ đó là verboten như một lỗ hổng tiêu chuẩn.
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

Ung dung:

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

Dòng đầu tiên đọc đầu vào và sử dụng regex để tìm khoảng trắng; cái này tự động đặt giá trị trước khoảng trắng bằng $ `và giá trị sau nó trong $ '.

Bây giờ chúng tôi lặp từ 1 đến 2*n-1. $tlà thuật ngữ của chúng tôi, mà vòng lặp lặp lại nhân với xvà chia cho chỉ số của vòng lặp ( $_). Vòng lặp bắt đầu từ 1 thay vì 0 vì cosin được khởi tạo thành 1, điều này giúp tôi tiết kiệm được việc chia cho 0.

Sau khi cập nhật $t, toán tử ba trả về $sinehoặc $cosine, tùy thuộc vào chỉ mục là số lẻ hay số chẵn và thêm $tgiá trị của nó vào nó. Công thức ma thuật chỉ ra $_&2?-$t:$tliệu có nên cộng hay trừ giá trị này hay không (về cơ bản là sử dụng bitwise - và trên chỉ mục và 2 để tạo chuỗi lặp lại "thêm, thêm, trừ, trừ").

Bạn có thể chạy thử mã này tại compileonline.com .


Vui lòng sửa đầu ra của bạn cho 20 20.
Gaurang Tandon

1
Tôi nghĩ rằng vòng lặp for của bạn có thể cần phải đi từ 1..$n*2-1, thay vì 1..$n. Trong khi tôi ở đây ... $shoàn toàn ổn khi không được khởi tạo, như được undefđánh giá 0trong bối cảnh số. Phân công ternary không cần dấu ngoặc đơn : $_&1?$s:$c+=$t. "%.8f\n%.8f"có thể được rút ngắn lại "%.8f\n"x2, do hậu quả của việc thêm một dòng mới.
primo

@Primo Cảm ơn, tôi không biết về một số trong số đó. Và bây giờ nó thậm chí còn tạo ra kết quả chính xác.
Tal

@Tal Niềm vui của tôi. Ngoài ra, phép thuật tốt hơn một chút: $t*(1-($_&2))=> $_&2?-$t:$t.
primo

Hãy cập nhật câu trả lời của bạn. Xem chi tiết trong câu hỏi. Cảm ơn.
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

Tôi lạm dụng gõ ngầm, nhưng tiếc là không có loại phức tạp ngầm nào như vậy tồn tại, vì vậy tôi phải xác định rõ & phức tạp i. Gfortran cắt giảm sản lượng ở 8 vị trí thập phân một cách tự nhiên, vì vậy chúng tôi rất tốt về thông số đó. Thật không may, phương thức đầu ra ban đầu của tôi print*,t, không đáp ứng được thông số kỹ thuật nên tôi đã phải thêm 16 ký tự để xuất các thành phần thực và tưởng tượng & đạt 8 chữ số thập phân cần thiết.

Nhờ Ventero, tôi đã quản lý để lưu 23 byte giữa đầu ra và vòng lặp. Và một nhân vật khác để có được câu trả lời chính xác và định dạng đầu ra. Và 3 thêm về readtuyên bố.

Ung dung

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

Hãy cập nhật câu trả lời của bạn. Xem chi tiết trong câu hỏi. Cảm ơn!
Gaurang Tandon

1
@GaurangTandon: Có lẽ bạn nên ngừng thay đổi chi tiết của vấn đề.
Kyle Kanos

Tôi biết, và tôi không muốn, nhưng tôi không thể giúp được. Trên thực tế, sau khi kiểm tra 5 câu trả lời, hóa ra hầu như tất cả chúng đều cho kết quả khác nhau (điều này thực sự hoàn toàn không bị ảnh hưởng). Tôi có thể đã làm theo một số cách tiếp cận khác, nhưng điều đó sẽ đòi hỏi sự thay đổi hoàn toàn các thuật toán của các câu trả lời hiện tại. Đây là điều tốt nhất tôi có thể tìm ra.
Gaurang Tandon

2
Chà tôi biết rằng cái của tôi hoạt động hoàn hảo, vì vậy tôi hoàn toàn nên kiểm tra: 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);}

Để lưu một byte, các câu lệnh cập nhật giá trị sin được đặt bên trong for()câu lệnh, nhưng thực tế được thực hiện sau các câu lệnh sau dấu ngoặc đơn đóng cập nhật giá trị cosine. (Tôi đoán tôi cũng có thể lưu thêm một vài byte bằng cách xóa ký tự dòng mới cuối cùng trong đầu ra của chương trình.)

Các biến toàn cầu s, c, rxđược mặc nhiên khởi tạo không, và isẽ có giá trị là 1 miễn là không có đối số cung cấp trên dòng lệnh. Thật không may, printf()mặc định là 6 vị trí của số thập phân, vì vậy định dạng đầu ra hơi dài dòng.

Ung dung:

Đây là mã với một chút sắp xếp lại để sắp xếp thứ tự mọi thứ rõ ràng hơn một chút:

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

Đầu ra mẫu:

$ echo 1.23 4 | ./sincos
0.94247129
0.33410995

Dùng thử trực tuyến:

http://ideone.com/URZWwo


3

Con trăn> = 2.7.3, 186 184 211 200 182 170 ký tự

Kinda đơn giản như địa ngục. Sử dụng công thức từ câu hỏi được tham số hóa cho sin và cos.

Thông dịch viên trực tuyến có thể được tìm thấy đây đây

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

Chỉnh sửa: Phiên bản hợp lệ với tất cả các hạn chế

Edit2: Đã thay đổi trình thông dịch trực tuyến thành ideone.com vì roundđầu ra hàm không hợp lệ trong Python 2.7.1

Edit3: Hóa ra tôi đã sử dụng lambda nội tuyến không cần thiết + thay đổi làm tròn thành định dạng chuỗi (bị đánh cắp từ xnor :))

Edit4: Thay thế joinbằng forvòng lặp chính không có chức năng


Xin chào, gần đây tôi đã chỉnh sửa các quy tắc mà bây giờ không cho phép các toán tử tích hợp để lũy thừa (đó là những gì **tôi đang làm). Vì vậy, tôi nghĩ rằng bạn sẽ phải chỉnh sửa câu trả lời của bạn. Xin lỗi vì sự bất tiện này. Xin hãy sửa tôi nếu tôi sai.
Gaurang Tandon

1
Tôi đoán sửa đổi thêm là vô ích với câu trả lời của xnor :)
avall

@avail Bật 20 20, tôi nhận được đầu ra -5364.4118142500001. Có thể muốn sửa nó thành 8 số thập phân.
Gaurang Tandon

Đó là vì phiên bản repl.it Python 2.7.1. Nếu bạn chạy nó trên ideone.com (Python 2.7.3) thì nó hoạt động đúng. ideone.com/JsYNNK
vào

Nó hoạt động tốt bây giờ! +1
Gaurang Tandon

3

JavaScript - 114 ký tự

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

Dựa trên câu trả lời tuyệt vời của james. Cùng một thuật toán, bước đầu tiên tránh được với việc khởi tạo c = 1 và s = ​​x. Sử dụng 2 vars thay vì một mảng cho đầu ra đơn giản hóa vòng lặp.

Ung dung

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

Lỗi đánh máy nhỏ: Nó sẽ s += (l *= x / ++d)và không có s += (l* = x / ++d)trong mã không được mã hóa.
Gaurang Tandon

1
@GaurangTandon đã sửa
edc65

2

JavaScript (Bản nháp ECMAScript 6) - 97 96 ký tự

Một giải pháp đệ quy:

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

Đầu ra:

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

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

Điều đó không đáp ứng các thông số về làm tròn mặc dù.
Martin Ender

@ m.buettner đã sửa
MT0

1
Nó không đáp ứng định dạng và no functionsyêu cầu đầu vào .
trong

Hãy cập nhật câu trả lời của bạn. Xem chi tiết trong câu hỏi. Cảm ơn.
Gaurang Tandon

2

C, 114

Danh tiếng không đủ để nhận xét, nhưng xa hơn với câu trả lời C của Squeamish Offisrage , giảm 7 byte bằng cách sử dụng float để nhân đôi và xóa khoảng trắng, và kết hợp khai báo và init của 'r' cho

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

thử ở đây .


Chào mừng bạn đến với câu đố lập trình và mã golf. Hoàn thành tốt khi thừa nhận rằng câu trả lời của bạn là một cải tiến nhỏ trên @ squeamishossifrage (Tôi vẫn cố đánh vần sai trong chỉnh sửa của mình.) Tốt nhất không nên tham khảo câu trả lời "ở trên" vì thứ tự thay đổi mỗi khi có chỉnh sửa. BTW, tôi nhận thấy việc khởi tạo rtrong khai báo. Tôi đã không kiểm tra xem liệu floatđưa ra độ chính xác cần thiết.
Cấp sông St

@steveverrill Tôi cũng không nghĩ floatsẽ cung cấp độ chính xác cần thiết, nhưng nó vẫn hoạt động :) Và chào mừng bạn đến với PPCG, user2702245!
Gaurang Tandon

Có phải chỉ có tôi là nhận được câu trả lời sai với floatcác biến sau đó? Cho x=5n=3, tôi nhận được sin(x)=10.20833206cos(x)=14.54166412:-( (Intel Core Duo, trong trường hợp bạn đang tự hỏi)
squossish ossifrage

Bạn có muốn tôi chuyển đổi điều này thành một nhận xét về câu trả lời đã nói không?
Doorknob

@Doorknob Có thể rời khỏi đây ngay bây giờ :-)
ossifrage squeamish

2

GNU bc, được điều khiển bởi bash, 128 byte

Quá nhiều byte dành cho việc đặt vị trí thập phân và làm tròn đến gần nhất. Ồ tốt, đây là dù sao:

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"

Đầu ra:

$ ./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,00000000
1.000000
$ ./trig.sh 20 20
-5364.411846
-10898.499385
$ 

Các công cụ dòng lệnh Linux, 97 ký tự unicode

Câu trả lời hack Unicode đã bị xóa theo yêu cầu của OP. Nhìn vào lịch sử chỉnh sửa nếu bạn quan tâm.


Tôi không thích thay đổi quy tắc sau khi đăng câu hỏi, nhưng tôi không cho phép các ký tự Unicode cho phép nén mã, vì tôi không biết các ký tự Unicode có thể được sử dụng để nén mã. Hiện tại chỉ có thể sử dụng các ký tự ASCII. Vui lòng chỉnh sửa bài viết của bạn. Xin lỗi vì sự bất tiện
Gaurang Tandon

@GaurangTandon Nó không thực sự nén - phiên bản unicode thực sự cần nhiều byte hơn (nhưng ít ký tự hơn). Nhưng tôi đồng ý với tình cảm của bạn - Tôi thực sự thích ghi điểm hoàn toàn bằng cách sử dụng số byte, nhưng không thể cưỡng lại một chút về các ký tự tiếng Trung trong OP của bạn.
Chấn thương kỹ thuật số

Bạn sử dụng toán tử hàm mũ bất hợp pháp
trong

@avall Rất tiếc. Điều đó làm tôi mất 4 byte.
Chấn thương kỹ thuật số

1

Ruby, 336

Có lẽ là cái dài nhất ở đây, nhưng tôi chắc rằng nó có thể được rút ngắn lại :(

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 ký tự

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

Sử dụng một chức năng qcho giai thừa, icho lũy thừa và pđể thực hiện cả sincos. Chạy tại jsbin.com. Sử dụng chính xác công thức mà không cần sửa đổi.

EDIT : Thay đổi 8vị trí 6thập phân thành vị trí thập phân. 15/5/14

Mã bị hủy bỏ :

/*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 ký tự

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

Ung dung

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

Đầu vào phải là hai số nguyên cách nhau không gian, không nằm trong hai hộp thoại khác nhau. Hãy sửa nó đi.
Gaurang Tandon

@GaurangTandon đã sửa - cảm ơn vì đã chỉ ra
James

1

Toán học, 96 ký tự

{{x,n}}=ImportString[InputString[],"Table"];Column@{Im@#,Re@#}&@Fold[1+I#x/#2&,1,2n-Range[2n-1]]

Làm thế nào là định dạng đầu vào, dường như x,nvới tôi?
Gaurang Tandon

@GaurangTandon Đó là x n.
alephalpha

Ok, cảm ơn đã làm rõ.
Gaurang Tandon

1

Hồng ngọc - 160 152 140 ký tự

Sử dụng đệ quy và thực tế là đối với việc thực hiện đệ quy này sin (x, 2n + 1) = 1 + cos (x, 2n - 1), là sin (x, n) và cos (x, n) chuỗi được xác định ở trên cho cos x và 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]

Chỉnh sửa: Đóng góp bởi các bình luận viên (đọc bên dưới).


1
Bạn có thể tiết kiệm rất nhiều nhân vật bằng cách sử dụng lambdas: p=->x,n{...}, f=->n{...}và như vậy, và sau đó sử dụng dấu ngoặc vuông thay vì dấu ngoặc đơn để gọi cho họ, giống như p[x,n-1]. Ngoài ra, tôi nghĩ collectchỉ là một bí danh map, ngắn hơn nhiều và vì bạn chỉ ánh xạ một cuộc gọi thành viên, bạn có thể rút ngắn nó thành gets.split.map &:to_f.
Martin Ender

@ MartinBüttner Cảm ơn! Sẽ thêm cái này! (hy vọng nhận xét của bạn ở đây nói rằng giải pháp này không chỉ của tôi, mà là collab) Thành thật mà nói: Tôi cũng mới sử dụng ruby ​​(chỉ 2 tháng) :)))
Boriel 18/215
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.