Пусть тригонометрия начинается!

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. Ввод должен быть через стандартный ввод или диалоговое окно (если ваш язык не поддерживает стандартный ввод)

Выход:

[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 и т. Д.), Факториала и возведения в степень не могут быть использованы. Вы можете использовать встроенную функцию округления для оценки результата вычислений sin(x)и cos(x)до 6-го знака после запятой.
  3. Нет необходимости обрабатывать неправильные данные.
  4. В программе можно использовать только символы ASCII, а не китайские символы Юникода, которые допускают сжатие кода.
  5. Ваша программа должна завершиться и отобразить вывод в течение 3 секунд после ввода.
  6. Ваш ответ должен сопровождать незакрашенный код вместе с объяснением кода (обязательно, если код не сразу очевиден для программистов, незнакомых с вашим языком, особенно GolfScript, J и т. Д.).
  7. Пожалуйста, включите ссылку на онлайн-компилятор, где ваша программа может быть протестирована.

Подсчет очков:

Ответ с наименьшей длиной кода в символах, включая пробелы, символы табуляции и т. Д., Выигрывает! Победитель будет объявлен 21 мая 2014 года.

РЕДАКТИРОВАТЬ : 21/05/14 Победитель Aditsu с использованием языка CJam . Занявший второе место следует за jpjacobs с языком J , а второй занял первое место с языком Perl . Поздравляю всех!

Гауранг Тандон
источник
(Примечание к моду: комментарии обнажены. Пожалуйста, пропишите мне любую потерянную информацию, которая может вам понадобиться; похоже, после моего предупреждения все
встало
В первом абзаце должно быть «синус», а не «грех»
не то, чтобы Чарльз
Требуется ли « округление до ближайшего» или мы можем использовать какие-либо встроенные средства округления? например, к нулю?
Цифровая травма
Требование эквивалента mod 2piоперации для ускорения сходимости входных данных было бы весьма полезно - это одно из многих улучшений, которые реальный мир использует при работе с этими функциями. (на самом деле мод пи и знак осведомленности).
Флорис,
1
@ Флорис, я никогда этого не знал. Что ж, сейчас мы ничего не можем сделать, правила уже сильно изменились, и я не хочу их менять, чтобы еще больше раздражать ответчиков. Спасибо за предложение, хотя!
Гауранг Тандон

Ответы:

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)
-(приращения (-> -1/1)
*умножаются, таким образом, изменяя знак каждую секунду,
/делит член в стеке на k или -k; это "/ к!" часть расчета вместе с изменением знака
X*умножается на X; это «X ^ k» часть расчета; мы получили следующее слагаемое в серии,
_дублирующее слагаемое, которое будет использоваться для вычисления следующего слагаемого в следующей итерации
;(после цикла). выскакивает последний дублируемый слагаемый,
]собирающий слагаемые в стеке в массив.
В этот момент у нас есть массив [ 1 Х-Х ^ 2/2! -X ^ 3/3! X ^ 4/4! X ^ 5/5! ...] содержащий ровно все необходимые нам слова для cos (x) и sin (x), чередующийся
2/разбивает этот массив на пары
zтранспонирует матрицу, получая массив с терминами для cos (x) и массив с терминами для sin (x), так как «строки матрицы»
{...}/снова выполняет блок для каждого элемента массива (строки матрицы):
- :+добавляет элементы строки матрицы вместе
- 6mOокругляет до 6 знаков после запятой.
В этот момент у нас есть желаемые cos (x) и sin (x) в стеке, которые
pвыводят представление последнего элемента в стеке (sin (x)), за которым следует новая строка
At В конце программы оставшееся содержимое стека (cos (x)) печатается автоматически.

aditsu
источник
1
+1 за знакомство с языком, о котором я никогда не слышал и, вероятно, никогда не буду использовать.
Алекс А.
@ Алекс, спасибо, CJam чем-то похож на GolfScript на стероидах
aditsu
Мне не нравится менять правила после публикации вопроса, но я запретил символы Unicode, разрешающие сжатие кода, поскольку я не знал, что символы Unicode можно использовать для сжатия кода. Теперь можно использовать только символы ASCII. Пожалуйста, отредактируйте свой пост. Приносим извинения за неудобства.
Гауранг Тандон
@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 мест по умолчанию, как удобно!


Алгоритм

Изучение ряда Тейлора для греха (х) :

можно видеть, что каждый член равномерно делит каждый последующий член. Из-за этого его можно довольно легко преобразовать во вложенное выражение:

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поле ввода STDIN, затем Execute Script.

Примо
источник
2
Какой хитрый способ разобрать входные данные ... могу ли я использовать это в своем решении? :)
Тал
@ Тал Не стесняйтесь.
Примо
2
Я думаю, что Perl (и особенно ваш код) считается "не сразу очевидным для программистов, не знакомых с вашим языком"
aditsu
1
@aditsu Согласен. Я добавлю немного более чистого кода и объяснение алгоритма.
Примо
2
Этот ответ действительно был чрезвычайно познавательным!
Тал
10

Питон 3 (102) / Питон 2 (104)

Питон 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)

В основном тот же код. Мы спасаем двух персонажей от ненужных паренов, printно теряем четверых от необходимости raw_input.

Пробный прогон

Вы можете запустить их здесь .

>>>
20 20
-5364.411846
-10898.499385

Объяснение кода

Основная идея состоит в том, чтобы вычислить 2*nусловия e^(ix), а затем принять мнимую и реальную часть, чтобы получить sinи cosзначения, приближенные к nтерминам. Мы используем усечение ряда Тейлора:

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 цифр согласно новым правилам. Никаких других изменений не было.

XNOR
источник
Попробуйте ideone для онлайн-переводчика py3 :)
Гарри Бидл
@BritishColour Спасибо! Я добавил это к посту.
xnor
Пожалуйста, обновите свой ответ. Смотрите детали в вопросе. Благодарю.
Гауранг Тандон
8

J 98 70 69 58

Хотя это, вероятно, может быть сокращено с помощью более причудливых функций ... комментарии приветствуются:

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

примечание 2: ввод заканчивается при получении EOF (ctrl-D в linux). Edit: присоединиться и возведение в степень факториала в лучше, более J-иш целом: ($ %&(*/) >:@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 работает только при запуске из файла из командной строки, в противном случае замените stdin ''на 'a b;'где a и b числа, которые были бы переданы в командной строке.

jpjacobs
источник
5
Мне нравится, что это начинается сexit
Digital Trauma
Пожалуйста, обновите свой ответ. Смотрите детали в вопросе. Благодарю.
Гауранг Тандон
Обновлено для 6 знаков после запятой. Если есть что-то еще, пожалуйста, уточните. Спасибо
jpjacobs
Вы можете удалить &из, 0j6&":чтобы сохранить символ. Также (i.@(,&_2)@{:($%&(*/)>:@i.@[)"0{.)можно переписать (($%&(*/)1+i.@[)"0~i.@,&_2)/еще на 6
Алгоритм_шарк
Эта задача требует T.(приблизительная функция по 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

Ungolfed:

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

Первая строка читает входные данные и использует регулярные выражения для поиска пробела; это автоматически помещает значение перед пробелом в $ `и значение после него в $ '.

Теперь мы переходим от 1 к 2*n-1. $tнаш термин, на который цикл многократно умножается xи делится на индекс цикла ( $_). Цикл начинается с 1, а не с 0, потому что косинус инициализируется на 1, что избавило меня от необходимости деления на ноль.

После обновления $tтроичный оператор возвращает либо, $sineлибо $cosine, в зависимости от того, является ли индекс нечетным или четным, и добавляет $tк нему значение. Магическая формула $_&2?-$t:$tпоказывает, следует ли добавить или вычесть это значение (в основном, используя побитовые и в индексе и 2, чтобы сгенерировать повторяющуюся последовательность «сложение, сложение, вычитание, вычитание»).

Вы можете протестировать этот код на compileonline.com .

Tal
источник
Пожалуйста, исправьте ваш вывод для 20 20.
Гауранг Тандон
1
Я думаю, что ваш цикл может потребоваться 1..$n*2-1, вместо 1..$n. В то время как я здесь ... $sпрекрасно неинициализирован, как undefоценивается 0в числовом контексте. Троичное назначение не нуждается в скобках: $_&1?$s:$c+=$t. "%.8f\n%.8f"может быть сокращено до "%.8f\n"x2, в результате добавления завершающего перевода строки.
Примо
@Primo Спасибо, я не знал о некоторых из них. И теперь он даже дает правильный результат.
Таль
@ Tal С удовольствием. Также чуть лучше волшебство: $t*(1-($_&2))=> $_&2?-$t:$t.
Примо
Пожалуйста, обновите свой ответ. Смотрите детали в вопросе. Благодарю.
Гауранг Тандон
5

Фортран: 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
Кайл Канос
источник
Пожалуйста, обновите свой ответ. Смотрите детали в вопросе. Благодарность!
Гауранг Тандон
1
@GaurangTandon: Вам, вероятно, следует прекратить изменять детали проблемы.
Кайл Канос
Я знаю, и не хочу, но я ничего не могу поделать. На самом деле, после тестирования 5 ответов, оказалось, что почти все они давали разные результаты (это было действительно совершенно неожиданно). Я мог бы следовать некоторому другому подходу, но это потребовало бы полной смены алгоритмов текущих ответов. Это лучшее, что я мог понять.
Гауранг Тандон
2
Ну, я знаю, что мой работает отлично, поэтому я должен полностью получить чек: D;)
Kyle Kanos
4

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

Чтобы сохранить байт, операторы, которые обновляют значение синуса, помещаются внутри for()оператора, но фактически выполняются после операторов после закрывающей скобки, которые обновляют значение косинуса. (Думаю, я мог бы также сохранить еще пару байтов, удалив последний символ новой строки в выходных данных программы.)

Глобальные переменные 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 символов

Вроде просто как ад. Использует формулу из вопроса, параметризованного для синуса и косинуса.

Онлайн переводчик можно найти Вот Вот

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

Изменить: Действительная версия со всеми ограничениями

Edit2: изменен онлайн-переводчик на ideone.com из-за неверного roundвывода функции в Python 2.7.1

Edit3: оказалось, что я использовал ненужную встроенную лямбду + изменил округление в формат строки (украдено из xnor :))

Edit4: заменен joinне функциональным основным forциклом

Avall
источник
Здравствуйте, я недавно отредактировал правила, которые теперь не позволяют встроенным операторам возвести в степень (это то, **что я делаю, я полагаю). Итак, я думаю, вам придется редактировать свой ответ. Приносим извинения за неудобства. Пожалуйста, поправьте меня, если я ошибаюсь.
Гауранг Тандон
1
Я думаю, что дальнейшие модификации бесполезны с ответом xnor :)
апреля
@avail On 20 20, я получаю вывод -5364.4118142500001. Могу хотеть исправить это до 8 десятичных знаков.
Гауранг Тандон
Это из-за repl.it Python версии 2.7.1. Если вы запустите его на ideone.com (Python 2.7.3), он будет работать правильно. ideone.com/JsYNNK
августа
Теперь это работает хорошо! +1
Гауранг Тандон
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))

На основании отличного ответа Джеймса. Тот же алгоритм, первый шаг избегается при инициализации c = 1 и s = x. Использование 2 переменных вместо массива для вывода упрощает цикл.

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))     
edc65
источник
Незначительная опечатка: это было бы, s += (l *= x / ++d)а не s += (l* = x / ++d)в некоголенном коде.
Гауранг Тандон
1
@GaurangTandon исправлено
edc65
2

JavaScript (ECMAScript 6 Draft) - 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"]
mt0
источник
Это не соответствует спецификации относительно округления.
Мартин Эндер
@ m.buettner исправлено
MT0
1
Он не соответствует формату ввода и no functionsтребованиям.
до
Пожалуйста, обновите свой ответ. Смотрите детали в вопросе. Благодарю.
Гауранг Тандон
2

С, 114

Недостаточная репутация для комментариев, но в дальнейшем C брезгует Offisrage в ответ , 7 сокращение байт с помощью поплавка для двойных и удаления пробелов и объединения декларации и инициализацией из «г» дает

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

попробуйте здесь .

tpb261
источник
Добро пожаловать в программирование головоломок и кода для гольфа. Хорошо сделано для того, чтобы признать, что ваш ответ - небольшое улучшение в @ squeamishossifrage's (мне все же удалось написать его неправильно в моем редактировании.) Лучше не ссылаться на ответ «выше», потому что порядок меняется каждый раз, когда происходит редактирование. Кстати, я заметил инициализацию rв декларации. Я не проверял, чтобы увидеть, если floatдает необходимую точность.
Уровень Река St
@steveverrill Я тоже не думаю, floatчто даст необходимую точность, но это работает :) И добро пожаловать в PPCG, user2702245!
Гауранг Тандон
Это только я получаю неправильные ответы с floatпеременными тогда? За x=5и n=3получаю sin(x)=10.20833206и cos(x)=14.54166412:-( (Intel Core Duo, если вам интересно)
брезгливый оссифраж
Вы хотите, чтобы я преобразовал это в комментарий к указанному ответу?
Дверная ручка
@ Doorknob Можно и оставить его сейчас :-)
брезгливое оссифраж
2

GNU bc, управляемый bash, 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
-5364,411846
-10898,499385
$ 

Инструменты командной строки Linux, 97 символов Юникода

Unicode взломанный ответ удален по запросу OP. Посмотрите историю изменений, если вам интересно.

Цифровая травма
источник
Мне не нравится менять правила после публикации вопроса, но я запретил символы Unicode, разрешающие сжатие кода, поскольку я не знал, что символы Unicode можно использовать для сжатия кода. Теперь можно использовать только символы ASCII. Пожалуйста, отредактируйте свой пост. Приносим извинения за неудобства
Гауранг Тандон
@GaurangTandon Это не совсем сжатие - версия Unicode на самом деле занимает больше байтов (но меньше символов). Но я согласен с вашим мнением - я на самом деле предпочитаю, чтобы оценка была строго выполнена с использованием счетчика байтов, но я не мог удержаться от биты с китайскими символами в вашем ОП.
Цифровая травма
Вы используете незаконный экспоненциальный оператор
avall
@avall Упс. Это стоило мне 4 байта.
Цифровая травма
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)
Mhmd
источник
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));
Джеймс
источник
Ввод должен быть двумя целыми числами, разделенными пробелами, а не в двух разных диалоговых окнах. Пожалуйста, исправьте это.
Гауранг Тандон
@ GaurangTandon исправлено - спасибо за указание на это
Джеймс
1

Mathematica, 96 символов

{{x,n}}=ImportString[InputString[],"Table"];Column@{Im@#,Re@#}&@Fold[1+I#x/#2&,1,2n-Range[2n-1]]
alephalpha
источник
Как выглядит формат ввода, x,nмне кажется ?
Гауранг Тандон
@GaurangTandon Это так x n.
алефальфа
Хорошо, спасибо за разъяснения.
Гауранг Тандон
1

Рубин - 160 152 140 символов

Используя рекурсию и тот факт, что для этой рекурсивной реализации sin (x, 2n + 1) = 1 + cos (x, 2n - 1), будучи sin (x, n) и cos (x, n), ряд, определенный выше для cos х и грех х.

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]

Редактировать: предоставлено комментаторами (см. Ниже).

Boriel
источник
1
Вы можете сэкономить много символов с помощью лямбды: p=->x,n{...}, f=->n{...}и так далее, а затем использовать квадратные скобки вместо круглых скобок называть их, как p[x,n-1]. Кроме того, я думаю, что collectэто просто псевдоним для map, который намного короче, и, поскольку вы только отображаете вызов участника, вы можете сократить его до gets.split.map &:to_f.
Мартин Эндер
@ MartinBüttner Спасибо! Добавлю это! (надеюсь, что ваш комментарий здесь заявил, что это решение не только мое, но и коллаборация) Если честно: я также новичок в ruby ​​(только 2 месяца) :)))
Boriel