Вступление:
Синусоидальной из 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
----
Примечания:
- Стандартные лазейки запрещены.
- Встроенные математические функции и операторы тригонометрии (sin, cos, tan и т. Д.), Факториала и возведения в степень не могут быть использованы. Вы можете использовать встроенную функцию округления для оценки результата вычислений
sin(x)
иcos(x)
до 6-го знака после запятой. - Нет необходимости обрабатывать неправильные данные.
- В программе можно использовать только символы ASCII, а не китайские символы Юникода, которые допускают сжатие кода.
- Ваша программа должна завершиться и отобразить вывод в течение 3 секунд после ввода.
- Ваш ответ должен сопровождать незакрашенный код вместе с объяснением кода (обязательно, если код не сразу очевиден для программистов, незнакомых с вашим языком, особенно GolfScript, J и т. Д.).
- Пожалуйста, включите ссылку на онлайн-компилятор, где ваша программа может быть протестирована.
Подсчет очков:
Ответ с наименьшей длиной кода в символах, включая пробелы, символы табуляции и т. Д., Выигрывает! Победитель будет объявлен 21 мая 2014 года.
РЕДАКТИРОВАТЬ : 21/05/14 Победитель Aditsu с использованием языка CJam . Занявший второе место следует за jpjacobs с языком J , а второй занял первое место с языком Perl . Поздравляю всех!
mod 2pi
операции для ускорения сходимости входных данных было бы весьма полезно - это одно из многих улучшений, которые реальный мир использует при работе с этими функциями. (на самом деле мод пи и знак осведомленности).Ответы:
CJam - 42
Попробуйте это онлайн на 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)) печатается автоматически.
источник
Perl - 72 байта
Или, считая параметры командной строки как 1 байт каждый, в 70 байтов :
Или, если вы позволите мне Perl 5.8, в 63 байта :
но почему бы тебе
Изменить : соблюдение новых правил.
%f
раундов до 6 мест по умолчанию, как удобно!Алгоритм
Изучение ряда Тейлора для греха (х) :
можно видеть, что каждый член равномерно делит каждый последующий член. Из-за этого его можно довольно легко преобразовать во вложенное выражение:
cos (x) преобразуется аналогично, без начального x , а знаменатель слагаемых на единицу меньше.
Кроме того, это вложенное выражение может быть переформулировано как обратное рекурсивное выражение:
с s ∞ = 0 и sin (x) = x · s 1 , что в конечном итоге и используется.
Ungolfed
Образец использования
Если вы хотите проверить это онлайн, я рекомендую использовать compileonline.com . Скопируйте и вставьте код в
main.pl
поле вводаSTDIN
, затем Execute Script.источник
Питон 3 (102) / Питон 2 (104)
Питон 3 (102)
Python 2,7 (104)
В основном тот же код. Мы спасаем двух персонажей от ненужных паренов,
print
но теряем четверых от необходимостиraw_input
.Пробный прогон
Вы можете запустить их здесь .
Объяснение кода
Основная идея состоит в том, чтобы вычислить
2*n
условияe^(ix)
, а затем принять мнимую и реальную часть, чтобы получитьsin
иcos
значения, приближенные кn
терминам. Мы используем усечение ряда Тейлора:Это полином в i * x, но вместо того, чтобы вычислять его значение суммированием каждого члена, мы используем модифицированный метод Хорнера для вычисления последовательности (рекурсивно определенной в обратном порядке)
что дает
t_1
равное искомое значение.Операции форматирования строки Python используются для получения значений для отображения округленных до 6 десятичных цифр.
Изменить: изменено на округление до 6 цифр согласно новым правилам. Никаких других изменений не было.
источник
J
98 70 6958Хотя это, вероятно, может быть сокращено с помощью более причудливых функций ... комментарии приветствуются:
примечание 2: ввод заканчивается при получении EOF (ctrl-D в linux). Edit: присоединиться и возведение в степень факториала в лучше, более J-иш целом:
($ %&(*/) >:@i.@[ )
. Это сводится к тому, чтобы взять массив x-копий y и массив чисел от 1 до y. Умножьте каждый и разделите результат. Это избавляет от дубликата*/
.Спасибо algortihmshark, еще 7 символов отключены.
Исключен срез для избавления от завершающего перевода строки.
Более длинная версия, для которой знание о вилках является обязательным.
Онлайн-переводчика J нет, но он с открытым исходным кодом уже несколько лет; установка проста с этими инструкциями:
http://www.jsoftware.com/jwiki/System/Installation/J801
На #jsoftware на irc.freenode.org также есть бот J.
stdin работает только при запуске из файла из командной строки, в противном случае замените
stdin ''
на'a b;'
где a и b числа, которые были бы переданы в командной строке.источник
exit
&
из,0j6&":
чтобы сохранить символ. Также(i.@(,&_2)@{:($%&(*/)>:@i.@[)"0{.)
можно переписать(($%&(*/)1+i.@[)"0~i.@,&_2)/
еще на 6T.
(приблизительная функция по n-членным рядам Тейлора), но я думаю, что это верботен как стандартная лазейка.Perl,
1201081048985Ungolfed:
Первая строка читает входные данные и использует регулярные выражения для поиска пробела; это автоматически помещает значение перед пробелом в $ `и значение после него в $ '.
Теперь мы переходим от 1 к
2*n-1
.$t
наш термин, на который цикл многократно умножаетсяx
и делится на индекс цикла ($_
). Цикл начинается с 1, а не с 0, потому что косинус инициализируется на 1, что избавило меня от необходимости деления на ноль.После обновления
$t
троичный оператор возвращает либо,$sine
либо$cosine
, в зависимости от того, является ли индекс нечетным или четным, и добавляет$t
к нему значение. Магическая формула$_&2?-$t:$t
показывает, следует ли добавить или вычесть это значение (в основном, используя побитовые и в индексе и 2, чтобы сгенерировать повторяющуюся последовательность «сложение, сложение, вычитание, вычитание»).Вы можете протестировать этот код на compileonline.com .
источник
20 20
.1..$n*2-1
, вместо1..$n
. В то время как я здесь ...$s
прекрасно неинициализирован, какundef
оценивается0
в числовом контексте. Троичное назначение не нуждается в скобках:$_&1?$s:$c+=$t
."%.8f\n%.8f"
может быть сокращено до"%.8f\n"x2
, в результате добавления завершающего перевода строки.$t*(1-($_&2))
=>$_&2?-$t:$t
.Фортран:
8910912510210198 байтЯ злоупотребляю неявной типизацией, но, к сожалению, такого неявного сложного типа не существует, поэтому мне пришлось указать это и комплекс
i
.Gfortran естественным образом сокращает вывод на 8 знаков после запятой, поэтому мы хорошо справляемся с этой задачей.К сожалению, мой оригинальный метод выводаprint*,t
не соответствовал спецификациям, поэтому мне пришлось добавить 16 символов для вывода мнимых и реальных компонентов и указать требуемые 8 десятичных знаков.Благодаря Ventero мне удалось сохранить 23 байта между выводом и циклом. И еще один персонаж для получения правильных ответов и форматированного вывода. И еще 3 на
read
заявлении.Ungolfed,
источник
С 120
Чтобы сохранить байт, операторы, которые обновляют значение синуса, помещаются внутри
for()
оператора, но фактически выполняются после операторов после закрывающей скобки, которые обновляют значение косинуса. (Думаю, я мог бы также сохранить еще пару байтов, удалив последний символ новой строки в выходных данных программы.)Глобальные переменные
s
,c
,r
иx
неявно инициализируется нуль, иi
будет иметь значение 1 до тех пор, пока нет аргументов , предусмотренных в командной строке. К сожалению, поprintf()
умолчанию используется 6 знаков после запятой, поэтому формат вывода немного подробный.Ungolfed:
Вот код с небольшой перестановкой, чтобы сделать порядок, в котором все делается немного яснее:
Образец вывода:
Попробуйте онлайн:
http://ideone.com/URZWwo
источник
Python> = 2.7.3,
186184211200182170 символовВроде просто как ад. Использует формулу из вопроса, параметризованного для синуса и косинуса.
Онлайн переводчик можно найти
ВотВотИзменить: Действительная версия со всеми ограничениями
Edit2: изменен онлайн-переводчик на ideone.com из-за неверного
round
вывода функции в Python 2.7.1Edit3: оказалось, что я использовал ненужную встроенную лямбду + изменил округление в формат строки (украдено из xnor :))
Edit4: заменен
join
не функциональным основнымfor
цикломисточник
**
что я делаю, я полагаю). Итак, я думаю, вам придется редактировать свой ответ. Приносим извинения за неудобства. Пожалуйста, поправьте меня, если я ошибаюсь.20 20
, я получаю вывод-5364.4118142500001
. Могу хотеть исправить это до 8 десятичных знаков.2.7.1
. Если вы запустите его на ideone.com (Python 2.7.3), он будет работать правильно. ideone.com/JsYNNKJavaScript - 114 символов
На основании отличного ответа Джеймса. Тот же алгоритм, первый шаг избегается при инициализации c = 1 и s = x. Использование 2 переменных вместо массива для вывода упрощает цикл.
Ungolfed
источник
s += (l *= x / ++d)
а неs += (l* = x / ++d)
в некоголенном коде.JavaScript (ECMAScript 6 Draft) -
9796 символовРекурсивное решение:
Выход:
источник
no functions
требованиям.С, 114
Недостаточная репутация для комментариев, но в дальнейшем C брезгует Offisrage в ответ , 7 сокращение байт с помощью поплавка для двойных и удаления пробелов и объединения декларации и инициализацией из «г» дает
попробуйте здесь .
источник
r
в декларации. Я не проверял, чтобы увидеть, еслиfloat
дает необходимую точность.float
что даст необходимую точность, но это работает :) И добро пожаловать в PPCG, user2702245!float
переменными тогда? Заx=5
иn=3
получаюsin(x)=10.20833206
иcos(x)=14.54166412
:-( (Intel Core Duo, если вам интересно)GNU bc, управляемый bash, 128 байтов
Слишком много байтов потрачено на установку десятичных разрядов и округление до ближайшего. Ну да ладно, вот оно все равно
Выход:
Инструменты командной строки Linux, 97 символов Юникода
Unicode взломанный ответ удален по запросу OP. Посмотрите историю изменений, если вам интересно.
источник
Рубин, 336
Вероятно, самый длинный здесь, но я уверен, что это можно сделать короче :(
источник
JavaScript (ES6) - 185 символов
Использует функцию
q
для факториала,i
для возведения в степень иp
для выполнения обоихsin
иcos
. Запустите на jsbin.com. Использует именно формулу без каких-либо изменений.РЕДАКТИРОВАТЬ : Изменено
8
десятичные разряды на6
десятичные разряды. 15 / Май / 14Код Ungolfed :
источник
JavaScript - 133 символа
Ungolfed
источник
Mathematica, 96 символов
источник
x,n
мне кажется ?x n
.Рубин -
160152140 символовИспользуя рекурсию и тот факт, что для этой рекурсивной реализации sin (x, 2n + 1) = 1 + cos (x, 2n - 1), будучи sin (x, n) и cos (x, n), ряд, определенный выше для cos х и грех х.
Редактировать: предоставлено комментаторами (см. Ниже).
источник
p=->x,n{...}
,f=->n{...}
и так далее, а затем использовать квадратные скобки вместо круглых скобок называть их, какp[x,n-1]
. Кроме того, я думаю, чтоcollect
это просто псевдоним дляmap
, который намного короче, и, поскольку вы только отображаете вызов участника, вы можете сократить его доgets.split.map &:to_f
.