Это происходит от http://programmers.blogoverflow.com/2012/08/20-controversial-programming-opinions/
«Учитывая, что число Pi можно оценить с помощью функции 4 * (1 - 1/3 + 1/5 - 1/7 +…) с большим количеством членов, дающих большую точность, напишите функцию, которая вычисляет число Pi с точностью до 5 десятичных знаков. "
- Обратите внимание, что оценка должна быть сделана путем расчета последовательности, приведенной выше.
p=lambda:3.14159
Ответы:
JavaScript
46 58 5645 байтОбновление ES6 : Оказывается, теперь, когда прошло пять лет, нам доступно больше возможностей.
Эта версия ( 45 байт; да,
let
требуется) работает в ES6 строгого режима в теории . На практике вы можете запустить его в V8 (например, с узлом) с помощью--use-strict --harmony-tailcalls
; Функция надлежащего Tailcalls пока не реализована широко, увы. Тем не менее, это определенное поведение, так что должно быть хорошо.Если мы хотим придерживаться того, что широко реализовано и не требует строгого режима, мы можем просто использовать синтаксис жирных стрелок ES6 для функций, но в остальном сохранить ту же реализацию, что и раньше (предложенную Брайаном Х), за стоимость 48 байт.
Выбор имени для одного параметра на самом деле не имеет значения, но мы могли бы также выбрать одно из имен, которые мы используем, чтобы минимизировать загрязнение глобальной области.
Эта версия является выражением функции; добавьте два символа (например, "
f
"), если хотите, чтобы они были названы. Эта версия забивает глобалыa
иi
; это может быть предотвращено, если мы добавим «a,i
» в список параметров.Использует пересмотренную версию алгоритма, чтобы обойти необходимость вычитания.
Вот «простая» версия без этой настройки:
который в часы на
6462 символов.Спасибо @ardnew за предложение избавиться от
4*
доreturn
.история
источник
a+=2/i/-~-~i;return 4*a
наa+=8/i/-~-~i;return a
Python 59 байт
Это печатает 1000 цифр; немного больше, чем требуется 5. Вместо того, чтобы использовать предписанную итерацию, он использует это:
6637
( Самый внутренний знаменатель) может быть сформулирован как:Это подразумевает линейную сходимость. Каждая более глубокая итерация произведет еще один двоичный бит числа пи .
Если , однако, вы настаиваете на использование загара -1 личности, подобная конвергенция может быть достигнута, если вы не возражаете идти о проблеме несколько иначе. Взглянем на частичные суммы:
4.0, 2.66667, 3.46667, 2.89524, 3.33968, 2.97605, 3.28374, ...
очевидно, что каждый член прыгает вперед и назад по обе стороны от точки схождения; ряд имеет переменную сходимость. Кроме того, каждый член ближе к точке схождения, чем предыдущий; оно абсолютно монотонно по отношению к точке сходимости. Сочетание этих двух свойств подразумевает, что среднее арифметическое любых двух соседних слагаемых ближе к точке сходимости, чем любое из самих слагаемых. Чтобы лучше понять, что я имею в виду, рассмотрим следующее изображение:
Внешняя серия является оригинальной, а внутренняя серия определяется по среднему значению каждого из соседних членов. Замечательная разница. Но что действительно примечательно, так это то, что эта новая серия также имеет чередующуюся сходимость и является абсолютно монотонной по отношению к точке схождения. Это означает, что этот процесс может применяться снова и снова, до тошноты.
Ok. Но как?
Некоторые формальные определения. Пусть P 1 (n) - n- й член первой последовательности, P 2 (n) - n- й член второй последовательности, и аналогично P k (n) - n- й член k- й последовательности, как определено выше. ,
P 1 = [P 1 (1), P 1 (2), P 1 (3), P 1 (4), P 1 (5), ...]
P 2 = [(P 1 (1) + P 1 (2)) / 2, (P 1 (2) + P 1 (3)) / 2, (P 1 (3) + P 1 (4)) / 2, (P 1 (4) + P 1 (5)) / 2, ...]
P 3 = [(P 1 (1) + 2P 1 (2) + P 1 (3)) / 4, (P 1 (2) + 2P 1 (3) + P 1 (4)) / 4, (P 1 (3) + 2P 1 (4) + P 1 (5)) / 4, ...]
P 4 = [(P 1 (1) + 3P 1 (2) + 3P 1 (3) + P 1 (4)) / 8, (P 1 (2) + 3P 1 (3) + 3P 1 (4) + P 1 (5)) / 8, ...]
Не удивительно, что эти коэффициенты точно следуют биномиальным коэффициентам и могут быть выражены в виде одной строки треугольника Паскаля. Поскольку произвольная строка треугольника Паскаля тривиальна для вычисления, можно найти произвольно «глубокий» ряд, просто взяв первые n частичных сумм, умножив каждый на соответствующий член в k- й строке треугольника Паскаля и разделив на 2 к-1 .
Таким образом, полная 32-битная точность с плавающей запятой (~ 14 знаков после запятой) может быть достигнута всего за 36 итераций, и в этот момент частичные суммы даже не сходятся во втором знаке после запятой. Это явно не игра в гольф
Если вам нужна произвольная точность, это может быть достигнуто с небольшой модификацией. Здесь еще раз вычисляем 1000 цифр:
Начальное значение p начинается на 2 10 больше, чтобы нейтрализовать эффекты целочисленного деления s / d, когда d становится больше, в результате чего последние несколько цифр не сходятся. Обратите внимание, что здесь
3318
также:То же количество итераций, что и в первом алгоритме (уменьшается вдвое, поскольку t уменьшается на 1 вместо 2 на каждую итерацию). Еще раз, это указывает на линейную сходимость: один двоичный бит числа пи на итерацию. В обоих случаях для расчета 1000 цифр числа пи требуется 3318 итераций , что несколько лучше, чем 1 миллион итераций для расчета 5.
источник
4 * sum(1/(1+i*2) if not i%2 else -1/(1+i*2) for i in xrange(places*10**(places)))
k → ∞
,f(-1,k)
подходит твоя Эйлер-сумма.P_1 = ..., P_2 = ..., P_3 = ..., P_4 = ...
«... умножить каждый на соответствующий термин вkth
строке Треугольника Паскаля и разделить на2^{k-1}
.» Вместоnth
строки и2^{n-1}
?.Mathematica
42 39 34 33 31 2632Архимедов подход 26 символов
Это достигает критерия, когда ввод 822.
Вопрос: Кто-нибудь знает, как он рассчитал грех на 180 градусов? Я не.
Подход Лейбница (серия Григория) 32 символа
Это та же функция, которую задала проблемная задача в качестве примера. Он достигает критерия примерно за полмиллиона итераций.
Мадхава-Лейбниц Подход 37 символов
Этот вариант использует еще несколько символов, но сходится к критерию всего за 9 итераций!
источник
APL (14)
источник
--/4÷1-2×⍳1e6
Ява (67 символов)
Обратите внимание, что это позволяет избежать потери значимости, добавляя числа в правильном порядке.
источник
while(--i>0)
чтобыwhile(i--)
и сохранить 2 символовХаскелл, 32
Считая имя функции это
34
источник
R - 25 символов
источник
C (GCC) (44 знака)
Это 41 символ, но его также нужно скомпилировать,
-O2
чтобы оптимизатор исключил рекурсию хвоста. Это также зависит от неопределенного поведения в отношении порядка, в котором++
они выполняются; спасибо Угорену за указание на это. Я тестировал с gcc 4.4.3 под 64-битным Linux.Обратите внимание, что если оптимизатор также не переупорядочивает сумму, он будет прибавлять к наименьшему числу, поэтому он избегает потери значимости.
Звоните как
p()
.источник
q()
, нетp()
. И я не думаю, что-O2
следует считать (но если вы посчитаете это, это 4 символа из-за необходимого места).p(0)
. 3. Сохраните чарсаreturn++i...
. 4. Два++i
делает неопределенное поведение.q
- это научит меня перепроверить после переименования. Я думаю, что следую обычной практике, считая-O2
3 символа, но мы можем открыть его по мета, если хотите; meta.codegolf.stackexchange.com/questions/19 - единственное соответствующее обсуждение, которое я могу найти. Я добавил версию gcc, которую я использую, и которая позволяет мне называть ее какp()
. Сохранение символа останавливает оптимизатор и дает сбой. Я поясню,p()
- вы уверены, что вызовp()
из любого контекста будет работать? Или это просто то, что оказалось в стеке в вашем тесте?p()
vsp(0)
, но я не знаю, какое поведение он описывает, и я не программист на Си.J, 26 символов
+ / + / _ 2 ((4 _4) &%)>: +: i.100Перенесено из 100 предметов последовательности в 1е6 предметов. Кроме того, теперь этот код помечен и может быть скопирован из браузера в консоль без ошибок.
источник
-/4%>:2*i.1e6
- 13 символов. (Спасибо b_jonas из #jsoftware за то, что я понял, что это-/
работает для вычисления суммы с чередующимся знаком. [Это потому, что все операторы в J имеют одинаковый приоритет и ассоциативную справа, поэтому-/ 1 2 3 4
<=>1 - (2 - (3 - 4))
<=>1 - 2 + 3 - 4
.])Javascript - 33 персонажа
Позвоните,
p
передав положительное нечетное число,x
и он вычислит Пи с(x-1)/2
условиями.источник
Рубин - 82 символа
Попробуйте это: https://repl.it/LQ8w
Подход использует данную серию косвенно, используя подход численного ускорения. В результате получается
pi ≈ 3.14159265161
против
pi = 3.14159265359
Начинается с
И затем, так как это чередуется, мы можем ускорить сходимость, используя
И это неоднократно применяется это:
И для простоты
f(n) = f(n,n)
.Рубин - 50 символов
Если вы не возражаете бежать очень долго, то вы можете просто использовать
или
источник
C 69 символов
a
устанавливается в 1).void main
странно и нестандартно, но заставляет вещи работать. Без этого рекурсия реализуется как реальный вызов, приводящий к переполнению стека. Альтернативой является добавлениеreturn
.4*
могут быть сохранены, если они работают с тремя параметрами командной строки.источник
int main(a)
или дажеmain(a)
, GCC только дает предупреждение. И это всеvoid main
равно будет предупреждением , и, возможно, даже потому, что у вас есть только один аргументmain
.Clojure - 79 символов
Это создает функцию без аргументов, которая будет вычислять число с плавающей запятой, которое правильно приближает число Пи к пяти десятичным разрядам. Обратите внимание, что это не привязывает функцию к имени, такому как
pi
, поэтому этот код должен оцениваться на местеeval
как(<code>)
или привязываться к имени, и в этом случае решениедля 82 символов
Около
источник
PHP -
5655 символовЯ не знаю, что смогу получить его намного меньше, не нарушая правила алгоритма.
источник
<?for(;1e6>$j;)$p+=($i=-$i|4)/~-$j+=2;echo$p;
Perl -
4339 символовне уверен, правила для анонимных подпрограмм, но вот еще одна реализация, использующая конструкцию серии @ FireFly
источник
Ява -
9284 символаЯ не могу превзойти результат Питера Тейлора, но вот мой:
Безголовая версия:
Редактировать: Сохранено несколько символов с помощью троичного оператора.
источник
Питон - 56 символов
Мех, мой питон-фу недостаточно силен. Я не мог видеть больше ярлыков, но, возможно, более опытный игрок в гольф мог найти что-то, чтобы урезать здесь?
источник
4.
->4
). Из других новостей я только что обнаружил случай, когда Python 3 фактически выигрывает у Python 2 в кодовом гольфе!Рубин - 54 символа
Моя первая попытка на консоли
63 символа
источник
def a;
вместоdef a()
.Perl (76 символов)
(Результат: 3.14159052)
Не самое короткое решение, но, возможно, интересное. Это геометрический. Я рассчитываю площадь под кругом.
У меня есть другой забавный подход, но он очень медленный. Он подсчитывает количество дискретных точек в квадрате, которые находятся ниже четверти круга, и вычисляет число пи из него:
Ожидается количество итераций в качестве аргумента командной строки. Здесь вы можете увидеть, как время выполнения относится к точности. ;)
источник
к (25 символов)
4 * + /% (i # 1 -1) '1 + 2 ! I: 1000000Немного короче:
источник
Python (49)
источник
CJam - 21
Довольно простой расчет данной серии.
CJam является http://sf.net/p/cjam
источник
Юлия - 30 персонажей
источник
SQL, 253 байта
Я бы предоставил SQL Fiddle, но в нем слишком много циклов, находим дроби 1/3, 1/5, 1/7 и т. Д., И это дает ошибки. Однако, если вы измените
@B<100000
на,1000
то он запустится (очевидно, не с тем же числом цифр точности).источник
Befunge, 129 байт
Попробуйте онлайн!
Если кому-то интересно, это слон.
источник