ให้ตรีโกณมิติเริ่มต้น!


20

บทนำ:

ไซน์ของxจะได้รับจากสูตร:

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

โคไซน์ของxจะได้รับจากสูตร:

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

งาน:

รับค่าของxและnเขียนโปรแกรม (ไม่มีฟังก์ชั่น ฯลฯ ) เพื่อส่งออกค่าsin(x)และcos(x)แก้ไขnข้อตกลงของสูตรข้างต้น สมมติว่าxเป็นเรเดียน

การป้อนข้อมูล:

x n

จำนวนทศนิยมx(มีไม่เกิน 3 ตำแหน่งทศนิยม) nและจำนวนเต็ม ข้อมูลที่ป้อนต้องอยู่ใน stdin หรือกล่องโต้ตอบแจ้ง (ถ้าภาษาของคุณไม่รองรับ stdin)

เอาท์พุท:

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

ค่าของทั้งคู่sin(x)และcos(x)ควรปัดเศษเป็นทศนิยม 6 ตำแหน่ง ถ้าsin(x)เป็น0.5588558855(ทศนิยม 10 หลัก) ก็ควรปัดเศษเป็น0.558856(6 หลักทศนิยม) ปัดเศษต้องใช้สถานที่ที่ใกล้ที่สุดตามที่อธิบายไว้ในคอลัมน์ที่ห้า "รอบที่ใกล้ที่สุด" ของตารางในบทความวิกิพีเดียนี้

ข้อ จำกัด :

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

ตัวอย่าง:

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

หมายเหตุ:

  1. ช่องโหว่มาตรฐานเป็นสิ่งต้องห้าม
  2. ฟังก์ชันทางคณิตศาสตร์ในตัวและโอเปอเรเตอร์ของตรีโกณมิติ (sin, cos, tan ฯลฯ ), factorial และ exponentiation ไม่สามารถใช้ได้ คุณมีอิสระในการใช้ฟังก์ชั่นการปัดเศษในตัวเพื่อประเมินผลลัพธ์ของการคำนวณsin(x)และcos(x)ตัวเลขทศนิยม 6 หลัก
  3. ไม่จำเป็นต้องจัดการกับอินพุตที่ไม่ถูกต้อง
  4. เฉพาะอักขระ ASCII เท่านั้นที่สามารถใช้ในโปรแกรมไม่ใช่ตัวอักษร Chinese Unicode ที่อนุญาตให้ใช้การบีบอัดรหัส
  5. โปรแกรมของคุณจะต้องยุติและแสดงผลภายใน 3 วินาทีของการป้อนข้อมูล
  6. คำตอบของคุณจะต้องมาพร้อมกับรหัสที่ไม่ได้เขียนพร้อมคำอธิบายของรหัส (บังคับถ้ารหัสนั้นไม่ชัดเจนในทันทีสำหรับโปรแกรมเมอร์ที่ไม่คุ้นเคยกับภาษาของคุณโดยเฉพาะ GolfScript, J และอื่น ๆ )
  7. โปรดรวมลิงก์ไปยังคอมไพเลอร์ออนไลน์ที่สามารถทดสอบโปรแกรมของคุณได้

เกณฑ์การให้คะแนน:

คำตอบที่มีความยาวรหัสต่ำสุดในตัวละครรวมถึงพื้นที่สีขาวแท็บและอื่น ๆ ชนะ! ผู้ชนะจะประกาศผลในวันที่ 21 พฤษภาคม 2014

แก้ไข : 21/05/14 ผู้ชนะคือผู้aditsu ใช้ภาษา วิ่งขึ้นดังนี้jpjacobs กับ J ภาษาและรองชนะเลิศอันดับที่สองขึ้นมาเป็นพรีโม่ด้วยภาษา Perl ยินดีด้วยทุกคน!


(หมายเหตุ mod: ความคิดเห็น nuked โปรด ping ฉันสำหรับข้อมูลที่หายไปที่คุณอาจต้องการ; ดูเหมือนว่าหลังจากคำเตือนของฉันล่วงหน้าทุกอย่างทำมาเป็นคำถามว่า.)
Doorknob

ในย่อหน้าแรกควรเป็น "ไซน์" ไม่ใช่ "บาป"
ไม่ใช่ว่าชาร์ลส์

คือ"รอบที่ใกล้ที่สุด"ยังคงต้องการหรือเราสามารถใช้ใด ๆ ในตัวสิ่งอำนวยความสะดวกในการปัดเศษ? เช่นปัดเศษเป็นศูนย์?
Digital Trauma

การใช้งานที่เทียบเท่าmod 2piเพื่อให้อินพุตที่มาบรรจบกันเร็วขึ้นจะมีประโยชน์มากกว่า - เป็นหนึ่งในการปรับปรุงหลายอย่างที่โลกแห่งความจริงใช้เมื่อจัดการกับฟังก์ชั่นเหล่านี้ (อันที่จริง mod pi และการรับรู้สัญญาณ)
Floris

1
@ Floris ฉันไม่เคยรู้เรื่องนี้ ทีนี้เราไม่สามารถทำอะไรได้ตอนนี้กฎได้เปลี่ยนแปลงไปมากแล้วและฉันไม่ต้องการเปลี่ยนแปลงพวกมันเพื่อรบกวนคำตอบต่อไป ขอบคุณสำหรับคำแนะนำ!
Gaurang Tandon

คำตอบ:


6

CJam - 42

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

ลองออนไลน์ได้ที่http://cjam.aditsu.net

คำอธิบาย:

rอ่านโทเค็นจากอินพุต
dแปรรูปคู่
:Xกำหนดให้กับตัวแปร x
;ปรากฏค่าจากกอง
1ทำให้ 1 ในกอง (ระยะแรก)
_ซ้ำ 1
rอ่านโทเค็นต่อไป (n) การ
iแปรรูปจำนวนเต็ม
2*,1>{...}/เป็นชนิดของห่วงจาก 1 ถึง 2 * n - 1:
- 2*คูณด้วย 2
- ,สร้างอาร์เรย์จาก 0 ถึง (ค่าสุดท้าย) -1
- 1>ลบรายการแรกของอาร์เรย์ (0)
- {...}/ดำเนินการบล็อกสำหรับแต่ละรายการในอาร์เรย์
_ซ้ำ "ห่วง ตัวแปร "(เรียกมันว่า k)
2%2*(แปลงจากเลขคี่ / คี่เป็น -1/1:
- 2%คือโมดูโล 2 (-> 0/1)
- 2*คูณด้วย 2 (-> 0/2)
-(decrements (-> -1/1)
*ทวีคูณดังนั้นการเปลี่ยนเครื่องหมายทุกครั้งที่สอง
/แบ่งคำในกองโดย k หรือ -k; นี่คือ "/ k!" ส่วนหนึ่งของการคำนวณพร้อมกับการเปลี่ยนเครื่องหมาย
X*คูณด้วย X นี่คือส่วน "X ^ k" ของการคำนวณ เราได้คำต่อไปในชุด
_ซ้ำคำที่จะใช้สำหรับการคำนวณคำต่อไปนี้ในการทำซ้ำถัดไป
;(หลังจากวนรอบ) ปรากฏคำที่ซ้ำกันครั้งสุดท้าย
]รวบรวมคำในกองซ้อนในอาร์เรย์
ณ จุดนี้เรามีอาร์เรย์ [ 1 X -X ^ 2/2! -X ^ 03/03! X ^ 04/04! X ^ 05/05! ... ] มีทุกคำที่เราต้องการสำหรับ cos (x) และ sin (x), interleaved จะ
2/แบ่งอาร์เรย์นี้เป็นคู่
zสลับเมทริกซ์ส่งผลให้อาร์เรย์มีเงื่อนไขสำหรับ cos (x) และอาร์เรย์ที่มีเงื่อนไขสำหรับ sin (x) ในขณะที่ "แถวเมทริกซ์"
{...}/อีกครั้งดำเนินการบล็อกสำหรับแต่ละรายการอาร์เรย์ (แถวเมทริกซ์):
- :+เพิ่มองค์ประกอบ ของแถวเมทริกซ์เข้าด้วยกัน
- 6mOปัดเป็นทศนิยม 6 ตำแหน่ง
ณ จุดนี้เราต้องการ cos (x) และ sin (x) บนสแต็ก
pพิมพ์การแสดงรายการสุดท้ายบนสแต็ก (sin (x)) ตามด้วย newline
ที่ ในตอนท้ายของโปรแกรมเนื้อหาที่เหลืออยู่ของสแต็ก (cos (x)) จะถูกพิมพ์โดยอัตโนมัติ


1
+1 สำหรับแนะนำฉันให้รู้จักภาษาที่ฉันไม่เคยได้ยินและอาจจะไม่เคยใช้
Alex A.

@Alex ขอบคุณ CJam ค่อนข้างคล้ายกับ GolfScript บนสเตียรอยด์
aditsu

ฉันไม่ชอบการเปลี่ยนแปลงกฎหลังจากโพสต์คำถาม แต่ฉันไม่อนุญาตให้ใช้อักขระการบีบอัดโค้ดที่อนุญาตให้ใช้ Unicode เนื่องจากฉันไม่ทราบว่าสามารถใช้อักขระ Unicode เพื่อบีบอัดโค้ดได้ สามารถใช้ได้เฉพาะอักขระ ASCII เท่านั้น โปรดแก้ไขโพสต์ของคุณ ขออภัยในความไม่สะดวก.
Gaurang Tandon

@GaurangTandon ฉันไม่ชอบมันมากเช่นกัน คุณคิดว่ามีอะไรอีกที่ใช้ตัวอักษรจีนในปัญหานี้ได้? อย่างไรก็ตามแก้ไข
aditsu

18

Perl - 72 ไบต์

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

หรือการนับตัวเลือกบรรทัดคำสั่งเป็น 1 ไบต์ใน70 ไบต์ :

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

หรือถ้าคุณจะอนุญาตให้ฉัน Perl 5.8, เป็น63 ไบต์ :

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

แต่ทำไมคุณจะ

แก้ไข : การปฏิบัติตามกฎใหม่ %fรอบถึง 6 แห่งโดยค่าเริ่มต้นสะดวกแค่ไหน!


ขั้นตอนวิธี

ตรวจสอบซีรี่ส์เทย์เลอร์ว่าเป็นบาป (x) :

จะเห็นได้ว่าแต่ละเทอมแบ่งเท่า ๆ กันทุกเทอม ด้วยเหตุนี้จึงสามารถแปลงให้เป็นนิพจน์แบบซ้อนได้อย่างง่ายดาย:

cos (x)แปลงในทำนองเดียวกันโดยไม่มีxนำหน้าและตัวส่วนคำหนึ่งที่เล็กกว่า

นอกจากนี้นิพจน์ที่ซ้อนกันนี้สามารถถูกจัดรูปแบบเป็นนิพจน์แบบเรียกซ้ำแบบย้อนกลับ:

ด้วยs = 0และsin (x) = x · s 1ซึ่งท้ายที่สุดแล้วสิ่งที่ใช้


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

ตัวอย่างการใช้งาน

$ 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

หากคุณต้องการที่จะทดสอบออนไลน์นี้ผมขอแนะนำให้ใช้compileonline.com คัดลอกวางรหัสลงmain.plและใส่ลงในกล่องแล้วSTDINExecute Script


2
ช่างเป็นวิธีที่ใช้ในการแยกวิเคราะห์อินพุต ... ฉันสามารถใช้วิธีนี้ในการแก้ปัญหาของฉันได้อย่างไร :)
Tal

@Tal รู้สึกฟรี
โม่

2
ฉันคิดว่า perl (และโดยเฉพาะอย่างยิ่งรหัสของคุณ) นับเป็น "ไม่ชัดเจนในทันทีสำหรับโปรแกรมเมอร์ที่ไม่คุ้นเคยกับภาษาของคุณ"
aditsu

1
@aditsu เห็นด้วย ฉันจะเพิ่มโค้ดที่สะอาดขึ้นและคำอธิบายของอัลกอริทึม
โม่

2
คำตอบนี้เป็นการศึกษาที่ยอดเยี่ยมจริงๆ!
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)

โดยทั่วไปรหัสเดียวกัน เราบันทึกตัวละครสองตัวจากการไม่ต้อง parens สำหรับแต่แพ้สี่จากต้องprintraw_input

วิ่งตัวอย่าง

คุณสามารถเรียกใช้เหล่านี้ที่นี่

>>>
20 20
-5364.411846
-10898.499385

คำอธิบายรหัส

แนวคิดหลักคือการคำนวณ2*nแง่ของe^(ix)แล้วใช้เวลาส่วนจินตภาพและเป็นจริงที่จะได้รับsinและcosค่าห้วงnเงื่อนไข เราใช้การตัดของซีรี่ส์ Taylor:

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

นี่คือพหุนามใน i * x แต่แทนที่จะคำนวณค่าของมันโดยการรวมแต่ละเทอมเราใช้วิธีของฮอร์เนอร์ที่แก้ไขเพื่อคำนวณลำดับ (นิยามซ้ำในสิ่งที่ตรงกันข้าม)

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

ซึ่งให้t_1เท่ากับค่าที่ต้องการ

การดำเนินการจัดรูปแบบสตริง Python ใช้เพื่อรับค่าเพื่อแสดงผลปัดเศษทศนิยมสูงสุด 6 หลัก

แก้ไข: เปลี่ยนเป็นปัดเศษเป็น 6 หลักตามกฎใหม่ ไม่ต้องการการเปลี่ยนแปลงอื่น ๆ


ลองideoneล่าม py3 ออนไลน์ :)
แฮร์รี่พิธีการ

@BritishColour ขอบคุณ! ฉันได้เพิ่มลงในโพสต์แล้ว
xnor

โปรดอัปเดตคำตอบของคุณ ดูรายละเอียดที่เป็นปัญหา ขอบคุณ
Gaurang Tandon

8

J 98 70 69 58

แม้ว่านี่อาจจะสั้นลงสักหน่อยโดยใช้ฟังก์ชั่นแฟนซีมากกว่านี้ ... ยินดีต้อนรับความคิดเห็น:

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

หมายเหตุ 2: อินพุตสิ้นสุดลงเมื่อรับ EOF (ctrl-D ใน linux) แก้ไข: เข้าร่วมการยกกำลังและปัจจัยเข้ามาดีกว่าที่อื่น ๆ J-ish ($ %&(*/) >:@i.@[ )ทั้งหมด: การทำเช่นนี้จะทำให้อาร์เรย์ของ x ซ้ำของ y และอาร์เรย์ของตัวเลขตั้งแต่ 1 ถึง y ทวีคูณแต่ละครั้งและหารผลลัพธ์ */นี้ได้รับกำจัดของที่ซ้ำกัน

ขอบคุณ algortihmshark และอีก 7 ตัวละคร

ตัดเพื่อกำจัดการขึ้นบรรทัดใหม่

รุ่นที่ยาวกว่าซึ่งการรู้เกี่ยวกับส้อมเป็นสิ่งที่ต้องทำ

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

ไม่มีล่ามออนไลน์ J แต่เป็นโอเพ่นซอร์สมาสองสามปี การติดตั้งง่ายด้วยคำแนะนำเหล่านี้:

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

ใน #jsoftware บน irc.freenode.org มีบอต J ด้วยเช่นกัน

stdin ทำงานได้ก็ต่อเมื่อวิ่งจากไฟล์จาก commandline มิฉะนั้นแทนที่stdin ''ด้วย'a b;'ที่ a และ b เป็นตัวเลขที่จะถูกส่งผ่านบน commandline


5
ฉันชอบที่มันเริ่มต้นด้วยexit
Digital Trauma

โปรดอัปเดตคำตอบของคุณ ดูรายละเอียดที่เป็นปัญหา ขอบคุณ
Gaurang Tandon

อัปเดตสำหรับตำแหน่งทศนิยม 6 ตำแหน่ง หากมีอย่างอื่นโปรดระบุ ขอบคุณ
jpjacobs

คุณสามารถลบออก&จาก0j6&":เพื่อบันทึกตัวอักษร นอกจากนี้ยัง(i.@(,&_2)@{:($%&(*/)>:@i.@[)"0{.)สามารถเขียนใหม่(($%&(*/)1+i.@[)"0~i.@,&_2)/สำหรับอีก 6
อัลกอริทึมที่

งานนี้กรีดร้องสำหรับT.(ฟังก์ชั่นการประมาณโดยชุดเทย์เลอร์ n- เทอม) แต่ฉันคิดว่ามันเป็น verboten เป็นช่องโหว่มาตรฐาน
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

บรรทัดแรกอ่านอินพุตและใช้ regex เพื่อค้นหาช่องว่าง สิ่งนี้จะใส่ค่าก่อนช่องว่างใน $ `และค่าที่อยู่หลังเป็น $ 'โดยอัตโนมัติ

ตอนนี้เราห่วงตั้งแต่ 1 2*n-1ถึง $tคือเทอมของเราซึ่งวนซ้ำทวีคูณด้วยxและหารด้วยดัชนีของลูป ( $_) การวนซ้ำเริ่มต้นที่ 1 แทนที่จะเป็น 0 เพราะโคไซน์นั้นเริ่มต้นที่ 1 ซึ่งช่วยให้ฉันไม่ต้องหารด้วยศูนย์

หลังจากอัพเดต$tตัวดำเนินการ trinary จะส่งคืน$sineหรือ$cosineขึ้นอยู่กับว่าดัชนีนั้นเป็นเลขคี่หรือคู่และเพิ่ม$tมูลค่าของมัน สูตรเวทย์มนตร์$_&2?-$t:$tว่าตัวเลขที่จะเพิ่มหรือลบค่านี้ (โดยทั่วไปใช้บิต - และบนดัชนีและ 2 เพื่อสร้างลำดับการทำซ้ำของ "เพิ่ม, เพิ่ม, ลบ, ลบ")

คุณสามารถทดสอบ-เรียกใช้รหัสนี้ที่compileonline.com


20 20โปรดแก้ไขการส่งออกของคุณสำหรับ
Gaurang Tandon

1
ผมคิดว่าห่วงสำหรับคุณอาจจะต้องไปจากที่แทน1..$n*2-1 1..$nในขณะที่ฉันอยู่ที่นี่ ... $sเป็นสิ่งที่ดีอย่างสมบูรณ์แบบที่ไม่ได้กำหนดundefค่าเริ่มต้นตามที่ประเมิน0ในบริบทที่เป็นตัวเลข ที่ได้รับมอบหมาย ternary $_&1?$s:$c+=$tไม่จำเป็นต้องวงเล็บ: "%.8f\n%.8f"สามารถย่อให้เล็กลง"%.8f\n"x2ซึ่งเป็นผลมาจากการเพิ่มขึ้นบรรทัดใหม่
โม่

@Primo ขอบคุณฉันไม่รู้เกี่ยวกับบางอย่าง และตอนนี้มันยังให้ผลลัพธ์ที่ถูกต้องเช่นกัน
Tal

@Tal ความสุขของฉัน นอกจากนี้ยังมีความมหัศจรรย์ที่ดีกว่าเล็กน้อย: =>$t*(1-($_&2)) $_&2?-$t:$t
โม่

โปรดอัปเดตคำตอบของคุณ ดูรายละเอียดที่เป็นปัญหา ขอบคุณ
Gaurang Tandon

5

Fortran: 89 109 125 102 101 98 ไบต์

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

ฉันละเมิดพิมพ์โดยปริยาย iแต่น่าเสียดายที่ไม่มีเช่นประเภทที่ซับซ้อนโดยปริยายอยู่แล้วเพื่อให้ฉันได้ระบุว่าและมีความซับซ้อน Gfortran ตัดเอาต์พุตที่ 8 ตำแหน่งโดยธรรมชาติดังนั้นเราจึงใช้สเป็กนั้นได้ดี น่าเสียดายที่วิธีดั้งเดิมของการส่งออกของprint*,tฉันไม่ตรงตามข้อกำหนดดังนั้นฉันจึงต้องเพิ่ม 16 ตัวอักษรเพื่อส่งออกส่วนประกอบในจินตนาการและของจริงและกดทศนิยม 8 ตำแหน่งที่ต้องการ

ขอบคุณ Ventero ฉันสามารถบันทึก 23 ไบต์ระหว่างเอาท์พุทและลูป และตัวละครอีกตัวเพื่อรับคำตอบที่ถูกต้อง และอีก 3 ข้อใน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

โปรดอัปเดตคำตอบของคุณ ดูรายละเอียดที่เป็นปัญหา ขอบคุณ!
Gaurang Tandon

1
@GaurangTandon: คุณอาจหยุดการเปลี่ยนรายละเอียดของปัญหา
Kyle Kanos

ฉันรู้และฉันไม่ต้องการ แต่ฉันไม่สามารถช่วยได้ ที่จริงแล้วหลังจากการทดสอบ 5 คำตอบปรากฎว่าเกือบทั้งหมดของพวกเขาให้ผลลัพธ์ที่แตกต่างกัน ฉันสามารถทำตามวิธีการอื่นได้ แต่นั่นจะต้องได้รับการยืนยันการเปลี่ยนแปลงใหม่อย่างสมบูรณ์ของอัลกอริทึมของคำตอบปัจจุบัน อันนี้ดีที่สุดที่ฉันสามารถหาได้
Gaurang Tandon

2
ดีฉันรู้ว่าเหมืองทำงานได้อย่างสมบูรณ์ดังนั้นฉันควรทั้งหมดจะได้รับการตรวจสอบ: D;)
ไคล์ 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);}

เพื่อบันทึกไบต์คำสั่งที่อัพเดตค่า sine จะถูกวางไว้ในfor()คำสั่ง แต่จริง ๆ แล้วจะถูกดำเนินการหลังจากคำสั่งที่ตามหลังวงเล็บปิดที่อัพเดตค่า cosine (ฉันเดาว่าฉันสามารถประหยัดได้อีกสองไบต์โดยการลบอักขระบรรทัดใหม่สุดท้ายในผลลัพธ์ของโปรแกรม)

ตัวแปรระดับโลกs, c, rและxจะเริ่มต้นโดยปริยายให้เป็นศูนย์และiจะมีค่าเป็น 1 ตราบใดที่มีข้อโต้แย้งไม่มีให้บริการในบรรทัดคำสั่ง น่าเสียดายที่printf()ค่าเริ่มต้นเป็นตำแหน่งทศนิยม 6 ตำแหน่งดังนั้นรูปแบบเอาต์พุตจึงค่อนข้างละเอียด

Ungolfed:

นี่คือรหัสที่มีการจัดเรียงใหม่เพื่อให้ลำดับที่สิ่งต่าง ๆ ดำเนินการได้ชัดเจนขึ้น:

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

ตัวอย่างผลลัพธ์:

$ echo 1.23 4 | ./sincos
0.94247129
0.33410995

ลองออนไลน์:

http://ideone.com/URZWwo


3

Python> = 2.7.3 186 184 211 200 182 170 ตัวอักษร

ค่อนข้างง่ายเหมือนนรก ใช้สูตรจากคำถามที่กำหนดพารามิเตอร์สำหรับ sine และ cosine

ล่ามออนไลน์สามารถพบได้ ที่นี่ ที่นี่

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

แก้ไข:รุ่นที่ถูกต้องพร้อมข้อ จำกัด ทั้งหมด

แก้ไข 2:เปลี่ยนล่ามออนไลน์เป็น ideone.com เนื่องจากroundฟังก์ชั่นเอาท์พุทที่ไม่ถูกต้องใน Python 2.7.1

แก้ไข 3:ปรากฎว่าฉันใช้แลมบ์ดาแบบอินไลน์ + เปลี่ยนการปัดเศษเป็นรูปแบบสตริง (ถูกขโมยจาก xnor :)

แก้ไข 4:แทนที่joinด้วยการforวนซ้ำหลักที่ใช้งานไม่ได้


สวัสดีประโยชน์ฉันเพิ่งแก้ไขกฎซึ่งตอนนี้ไม่อนุญาตให้ตัวดำเนินการในตัวสำหรับการยกกำลัง (นั่นคือสิ่งที่**ฉันกำลังทำอยู่) ดังนั้นฉันคิดว่าคุณจะต้องแก้ไขคำตอบของคุณ ขออภัยในความไม่สะดวก. โปรดแก้ไขฉันหากฉันผิด
Gaurang Tandon

1
ฉันเดาว่าการแก้ไขเพิ่มเติมจะไม่ได้ผล XNOR ของคำตอบ :)
Avall

@avail On 20 20ฉันจะได้ผลลัพธ์-5364.4118142500001ฉันได้รับการส่งออกอาจต้องการแก้ไขให้เป็นทศนิยม 8 ตำแหน่ง
Gaurang Tandon

มันเป็นเพราะ repl.it 2.7.1รุ่นหลาม หากคุณใช้งานบน ideone.com (Python 2.7.3) จะทำงานได้อย่างถูกต้อง ideone.com/JsYNNK
avall

มันใช้งานได้ดีตอนนี้! +1
Gaurang Tandon

3

JavaScript - 114 ตัวอักษร

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

ขึ้นอยู่กับคำตอบที่ยอดเยี่ยมของ James อัลกอริทึมเดียวกันขั้นตอนแรกหลีกเลี่ยงด้วยการเริ่มต้นของ c = 1 และ s = x การใช้ 2 vars แทน array เพื่อให้การวนซ้ำง่ายขึ้น

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

ตัวพิมพ์เล็ก: มันจะs += (l *= x / ++d)ไม่s += (l* = x / ++d)อยู่ในโค้ดที่ไม่ได้รับการอวด
Gaurang Tandon

1
@GaurangTandon แก้ไขแล้ว
edc65

2

JavaScript (ฉบับร่าง ECMAScript 6) - 97 96 ตัวอักษร

โซลูชันแบบเรียกซ้ำ:

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

เอาท์พุท:

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

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

ที่ไม่ตรงตามข้อกำหนดเกี่ยวกับการปัดเศษแม้ว่า
Martin Ender

@ m.buettner ได้รับการแก้ไข
MT0

1
ไม่ตรงกับรูปแบบอินพุตและno functionsข้อกำหนด
avall

โปรดอัปเดตคำตอบของคุณ ดูรายละเอียดที่เป็นปัญหา ขอบคุณ
Gaurang Tandon

2

C 114

ชื่อเสียงไม่เพียงพอที่จะแสดงความคิดเห็น แต่เพิ่มเติมจากคำตอบ C ของ Squeamish Offisrage การลดลง 7 ไบต์โดยใช้ float สำหรับการลบแบบสองครั้งและการเว้นวรรครวมการประกาศและ init ของ 'r'

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

ลองที่นี่


ยินดีต้อนรับสู่การเขียนโปรแกรมปริศนาและรหัสกอล์ฟ ทำได้ดีมากสำหรับการยอมรับว่าคำตอบของคุณเป็นการปรับปรุงเล็กน้อยใน @ squeamishossifrage (ฉันยังคงสะกดผิดในการแก้ไขของฉัน) ดีที่สุดที่จะไม่อ้างถึงคำตอบ "ด้านบน" เพราะคำสั่งซื้อจะเปลี่ยนแปลงทุกครั้งที่มีการแก้ไข BTW ฉันสังเกตเห็นการเริ่มต้นของrในการประกาศ ฉันไม่ได้ทดสอบว่าfloatมีความแม่นยำตามที่ต้องการหรือไม่
เลเวลริเวอร์

@ สตีฟเวอร์ริลล์ฉันไม่คิดว่าfloatจะให้ความแม่นยำที่ต้องการ แต่ใช้งานได้ :) และยินดีต้อนรับสู่ PPCG, user2702245!
Gaurang Tandon

เป็นแค่ฉันใช่ไหมที่จะได้คำตอบที่ผิด ๆ เกี่ยวกับfloatตัวแปร? สำหรับx=5และn=3ฉันได้รับsin(x)=10.20833206และcos(x)=14.54166412:-( (Intel Core Duo ในกรณีที่คุณสงสัย)
ossifrage คลื่นไส้

คุณต้องการให้ฉันแปลงเป็นความคิดเห็นในคำตอบที่ได้กล่าวไว้หรือไม่?
Doorknob

@Doorknob พฤษภาคมและปล่อยให้มันตอนนี้ :-)
squeamish ossifrage

2

GNU bc ขับเคลื่อนโดยทุบตี 128 ไบต์

จำนวนไบต์ที่มากเกินไปใช้การตั้งทศนิยมและการปัดเศษที่ใกล้ที่สุด แหมดีนี่มันอยู่ดี:

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"

เอาท์พุท:

$ ./trig.sh 5 3
10.208333
14.541667
$ ./trig.sh 8.555 13
0.765431
-.641092
$ ./trig.sh 9.26 10
-3.154677
-8.404354
$ ./trig.sh 6.54 12
0.253986
0.967147
$ ./trig.sh 5 1
5.000000
1.000000
$ ./trig.sh 20 20
-5,364.411846
-10,898.499385
$ 

เครื่องมือบรรทัดคำสั่ง Linux, 97 อักขระ Unicode

คำตอบแฮ็ก Unicode ถูกลบออกตามคำขอของ OP ดูประวัติการแก้ไขหากคุณสนใจ


ฉันไม่ชอบการเปลี่ยนแปลงกฎหลังจากโพสต์คำถาม แต่ฉันไม่อนุญาตให้ใช้อักขระการบีบอัดโค้ดที่อนุญาตให้ใช้ Unicode เนื่องจากฉันไม่ทราบว่าสามารถใช้อักขระ Unicode เพื่อบีบอัดโค้ดได้ สามารถใช้ได้เฉพาะอักขระ ASCII เท่านั้น โปรดแก้ไขโพสต์ของคุณ ขออภัยในความไม่สะดวก
Gaurang Tandon

@GaurangTandon มันไม่ได้บีบอัดจริง ๆ - รุ่น unicode ใช้เวลาจริงมากขึ้นไบต์ (แต่ตัวอักษรน้อยกว่า) แต่ฉันเห็นด้วยกับความรู้สึกของคุณ - จริง ๆ แล้วฉันชอบให้คะแนนโดยใช้จำนวนไบต์ แต่ไม่สามารถต้านทานบิตของตัวอักษรจีนใน OP ของคุณได้
Digital Trauma

คุณใช้ตัวดำเนินการเอ็กซ์
โปเนน

@all โอ๊ะโอ ค่าใช้จ่ายฉัน 4 ไบต์
Digital Trauma

1

ทับทิม, 336

อาจยาวที่สุดที่นี่ แต่ฉันแน่ใจว่ามันจะสั้นกว่า :(

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 ตัวอักษร

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

ใช้ฟังก์ชั่นqสำหรับปัจจัย, iสำหรับการยกกำลังและpสำหรับการดำเนินการทั้งในและsin cosวิ่งที่ jsbin.com ใช้สูตรอย่างแน่นอนโดยไม่มีการดัดแปลงใด ๆ

แก้ไข : เปลี่ยน8ตำแหน่งทศนิยมเป็น6ตำแหน่งทศนิยม 15 / พ.ค. / 14

รหัส 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 ตัวอักษร

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

อินพุตต้องเป็นจำนวนเต็มสองจำนวนที่คั่นด้วยช่องว่างไม่ใช่ในกล่องโต้ตอบสองกล่องที่แตกต่างกัน กรุณาแก้ไข
Gaurang Tandon

แก้ไขแล้ว @GaurangTandon - ขอบคุณที่ชี้ให้เห็น
James

1

Mathematica, 96 ตัวอักษร

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

รูปแบบอินพุตx,nเป็นอย่างไรสำหรับฉัน
Gaurang Tandon

@GaurangTandon x nมันเป็น
alephalpha

โอเคขอบคุณสำหรับการชี้แจง
Gaurang Tandon

1

ทับทิม - 160 152 140 ตัวอักษร

การใช้การเรียกซ้ำและความจริงที่ว่าสำหรับการดำเนินการแบบเรียกซ้ำบาปนี้ (x, 2n + 1) = 1 + cos (x, 2n - 1) เป็นบาป (x, n) และ cos (x, n) ชุดที่กำหนดไว้ด้านบนสำหรับ cos x และบาป 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]

แก้ไข: เขียนโดยผู้แสดงความคิดเห็น (อ่านด้านล่าง)


1
คุณสามารถบันทึกจำนวนมากของตัวละครโดยใช้ lambdas: p=->x,n{...}, f=->n{...}และอื่น ๆ p[x,n-1]และจากนั้นใช้วงเล็บแทนวงเล็บจะเรียกพวกเขาเช่น นอกจากนี้ฉันคิดว่าcollectเป็นเพียงนามแฝงmapซึ่งสั้นกว่ามากและเนื่องจากคุณทำแผนที่เฉพาะการโทรของสมาชิกคุณจึงสามารถย่อให้สั้นลงgets.split.map &:to_fได้
Martin Ender

@ MartinBüttnerขอบคุณ! จะเพิ่มสิ่งนี้! (หวังว่าความคิดเห็นของคุณที่นี่ระบุว่าโซลูชันนี้ไม่เพียง แต่เป็นของฉัน แต่ร่วมมือกัน) พูดตามตรง: ฉันยังใหม่กับทับทิม (2 เดือนเท่านั้น) :)))
Boriel
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.