Пи код расчета Гольф [закрыт]


17

Соревнование

Вы должны рассчитать пи в кратчайшую длину вы можете. Приглашаем присоединиться к любому языку, и вы можете использовать любую формулу для расчета числа пи. Должно быть в состоянии вычислить число Пи как минимум до 5 десятичных знаков. Короче, будет измеряться в символах. Конкурс длится 48 часов. Начать.


Примечание : этот аналогичный вопрос гласит, что PI должен быть рассчитан с использованием серии 4 * (1 - 1/3 + 1/5 - 1/7 + ...). Этот вопрос не имеет этого ограничения, и на самом деле многие ответы здесь (в том числе наиболее вероятные, чтобы выиграть) были бы неверными в этом другом вопросе. Итак, это не дубликат.


5
@hvd Почему вы думаете, что это должно быть дисквалифицировано? Это соответствует спецификациям ...
Доктор Белизариус

5
@hvd acos (-1). Я выигрываю!
Уровень Река St

4
Это выглядит странно, противоречиво. Вычисление π должно делить круг на его диаметр или какую-то другую операцию, дающую π. Если мы согласны делать 355/113 - что не имеет ничего общего с π, кроме удачи - как @ace, то логически мы должны принять 3.14159 .
Николас Барбулеско

7
Я не понимаю, почему людям нравится этот вопрос. Это один из самых плохо сформулированных и неинтересных вопросов, которые я видел здесь. Единственная разница между этим и привет миром, это то, что это как-то связано с Пи.
Cruncher

8
Чтобы сделать этот вопрос интересным, нужна функция скоринга, которая награждает цифры pi за байт кода.
Бен Джексон

Ответы:


56

Python3, 7

Работает в интерактивной оболочке

355/113

Вывод: с 3.1415929203539825точностью до 6 знаков после запятой

И, наконец, у меня есть решение, которое превосходит APL!

Да, и, если вам интересно, это соотношение называется 密 率 (буквально «точное соотношение») и предложено китайским математиком Цу Чончжи (429-500 гг. Н.э.). Соответствующую статью в Википедии можно найти здесь . Цу также дал соотношение 22/7 как «грубое соотношение», и он, как известно, был первым математиком, предложившим 3.1415926 <= pi <= 3.1415927


12
ммм - это на самом деле ответ полиглота. Работает и в Smalltalk!
blabla999

7
Богохульство! Это всего лишь расчет!
Мниип

3
ну, это деление, и его точность удовлетворяет требованию ... (и даже Библия менее точна; вы бы не назвали это богохульство - не так ли? 3 * ;-)
blabla999

29
Неловкий момент, когда я написал это как серьезный ответ, но все воспринимают это как шутку ...
user12205

20
Голос с наибольшим количеством голосов 355/113. Самый низкий голосовал ответ: 3+.14159. Я не вижу большой разницы, правда.
прима

49

PHP - 132 127 125 124 байта

Базовое моделирование Монте-Карло. Каждые 10 миллионов итераций выводится текущий статус:

for($i=1,$j=$k=0;;$i++){$x=mt_rand(0,1e7)/1e7;$y=mt_rand(0,1e7)/1e7;$j+=$x*$x+$y*$y<=1;$k++;if(!($i%1e7))echo 4*$j/$k."\n";}

Спасибо cloudfeet и zamnuts за предложения!

Образец вывода:

$ php pi.php
3.1410564
3.1414008
3.1413388
3.1412641
3.14132568
3.1413496666667
3.1414522857143
3.1414817
3.1415271111111
3.14155092
...
3.1415901754386
3.1415890482759
3.1415925423731

5
За ответ, который действительно вычисляет!
blabla999

Не знаю насчет PHP, но в JS вы можете сделать что-то вроде: $j+=$x*$x+$y*$y<=1;что сэкономит вам четыре байта.
cloudfeet

1
Также $k+=1/4;и print $j/$kможет быть уменьшен до $k++;и print 4*$j/$kдля другого байта.
Cloudfeet

@cloudfeet - внесены изменения, подтвержденный код работает так же. Спасибо!

2
@MarkC - Концептуально он бросает дротики случайным образом в прямоугольник от 0,0 до 1,1. Те, которые меньше или равны расстоянию 1 от 0,0, считаются внутри, иначе снаружи. Форма этого расстояния 1 бывает четверть круга или π / 4. [Количество дротиков внутри четверти круга] / [общее количество дротиков] будет приблизительно равно π / 4 при увеличении количества образцов.

31

J 6

{:*._1

Пояснение: *.дает длину и угол комплексного числа. Угол -1 равен пи. {:берет хвост списка [длина, угол]

Только для медленно сходящихся фетишистов серии, для 21 байта, серии Лейбница:

      +/(4*_1&^%>:@+:)i.1e6
 3.14159

12
Другими словами, это так atan(0) + pi. Я не думаю, что использование тригонометрических функций и самого пи следует считать «вычислением».
Джейсон С

@JasonC Arg(то есть аргумент комплексного числа) не является тригонометрической функцией, несмотря на то, что он имеет значения, подобные значениям
arctangent

1
@mniip Да, это так. Это просто синоним atan (ну, atan2) в реальной и мнимой частях. Как видите, оно точно по определению равно atan(0) + pi.
Джейсон С


19

Пит, много кодов

Не мой ответ, но это лучшее решение, которое я видел для этой проблемы:

Пи приближение в Пиет

Насколько я понимаю, это складывает пиксели в круг и делит на радиус, а затем еще раз. То есть:

A = πr²  # solve for π
π = A/r²
π = (A/r)/r

На мой взгляд, лучшим подходом является программа, которая генерирует это изображение в произвольном размере и затем запускает его через интерпретатор Piet.

Источник: http://www.dangermouse.net/esoteric/piet/samples.html


Не могли бы вы объяснить, что он на самом деле делает? (Я знаю общую идею Пита, но объяснение того, как эта конкретная программа работает, было бы хорошим дополнением к вашему ответу).
plannapus

Я действительно не знаю Пита, но я думаю, что это буквально измеряет площадь красного круга, а затем делится на радиус дважды, решая для π = A / (r * r)
не то, что Чарльз

Хорошо, область достаточно четкая, так как когда указатель входит в красный круг, он подсчитывает количество кодов в красной области и выводит его в стек при выходе (так как точка выхода темно-красная, следовательно, нет изменения оттенка, но на один шаг темнее ), это "деление на радиус в квадрате", что мне было трудно понять.
plannapus

1
@plannapus Радиус «жестко закодирован» в темно-красной линии, простирающейся от верхнего левого угла до половины вниз по левому краю (это трудно увидеть на изображении). Пайту трудно следовать, но суть в том, что блоки цвета имеют значение, равное их площади (у линии на левом краю есть r пикселей, у круга есть пиксели площади ), а промежуточный материал - это просто набор стековых и арифметических операций. Программы начинаются в левом верхнем углу. Текст в правом верхнем углу по сути является комментарием.
Джейсон С

2
@JasonC ну конечно! Круг касается как верхней, так и нижней стороны, поэтому темно-красная линия, спускающаяся от верхней стороны к точной середине, необходима для радиуса! Умный!
plannapus

18

ТЕХНИЧЕСКИ Я РАСЧЕТА, 9

0+3.14159

ТЕХНИЧЕСКИ Я ВСЕ РАСЧЕТЫ, 10

PI-acos(1)

Я РАСЧЕТ ТАК ЖЕ, 8

acos(-1)

Я СЛУЧАЙНО ПИ, 12

"3.14"+"159"

И технически этот ответ воняет.


31
Так что заголовок, очень большой заголовок, очень больно для моих глаз, вау.
Пьер Арло

1
pluzz wan для большого количества lulz, спасибо
Джонатан Ван Матр

Эй, детка, хочешь расширить мою серию Тейлор?
Джейсон C


@SimonT Вы не ответили на мой вопрос о серии Тейлор. Но пока вы думаете об этом, посмотрите мои комментарии по этому вопросу и большинство других ответов здесь. : P
Джейсон C

14

APL - 6

2ׯ1○1

Выходы 3.141592654. Он вычисляет дважды арксинус 1.

13-символьное решение будет:

--/4÷1-2×⍳1e6

Это вывод 3.141591654для меня, который соответствует запрашиваемой точности.
Это использует простой + 4/1 - 4/3 + 4/5 - 4/7 ...ряд, чтобы вычислить все же.


1
Вау, это одна медленная конвергенция!

Моей первой мыслью было «почему бы и нет ¯2○¯1?» (То есть acos -1). Но это дает комплексное приближение для repl.it ( 3.1415926425236J¯1.1066193467303274e¯8). Есть идеи почему? Все реализации делают это?
Джеймс Вуд

+1 за ваше второе решение. 2 * asin(1)это немного обмануть, хотя.
Джейсон С

@JamesWood Я не знаю APL, но если бы мне пришлось угадывать, я бы сказал, что sqrt(1-theta^2)в какой-то момент он пытался выполнить (который появляется во многих идентификаторах триггеров) и где-то потерял некоторую точность, получая слегка отрицательный результат 1-theta^2.
Джейсон С

1
Что странно, так это то, что есть еще крошечная мнимая часть acos -0.75. Там нет никакого способа, которым это могло бы рассчитывать, 1 - 0.75 ^ 2чтобы быть отрицательным.
Джеймс Вуд

14

J - 5 байт

|^._1

Это значит |log(-1)|.


Умное использование идентичности Эйлера.
Примо

1
Круто, еще один алгебраический тождественный ответ. Примерно такой же умный, как ln(e^(42*pi))/42или pi*113/113.
Джейсон C

Также работает в TI-BASIC
Timtech

1
(Совершенно не связано, я хотел бы, чтобы мы могли использовать LaTeX на Codegolf.)
Jason C

1
(Ответ на совершенно не связанный с этим вопрос, я получаю с помощью диаграмм Google, например, здесь .) По теме это самый верный ответ, и, следовательно, его следовало принять.
Примо

14

Google Calculator, 48

stick of butter*(26557.4489*10^-9)/millimeters^3

Берет кусочек сливочного масла, делает сложные вычисления, делает из него пи. Я подумал, так как все остальные делали простые математические ответы, я бы добавил немного более уникальный.

пример


3
Это stick of butterмило и забавно, но это, по сути, еще одна pi*x/x+y-yалгебраическая идентичность.
Джейсон С

10
Есть так много лучших способов сделать пи с помощью куска масла
не то, что Чарльз

Вы пробовали делать масло с палочкой пи?
mbomb007

12

Октава, 31

quad(inline("sqrt(4-x^2)"),0,2)

Вычисляет площадь одной четверти круга с радиусом 2 путем численного интегрирования.

octave:1> quad(inline("sqrt(4-x^2)"),0,2)
ans =     3.14159265358979

1
Ницца! +1, когда мои голоса пополняются.
Джейсон С


10

Python, 88

Решение :

l=q=d=0;t,s,n,r=3.,3,1,24
while s!=l:l,n,q,d,r=s,n+q,q+8,d+r,r+32;t=(t*n)/d;s+=t
print s

Пример вывода в оболочке Python:

>>> print s
3.14159265359

Удается избежать любого импорта. Может быть легко заменен на использование десятичной библиотеки произвольной точности; просто заменить 3.наDecimal('3') , установите точность до и после, затем унарный плюс результат для преобразования точности.

И в отличие от всего много ответов здесь, на самом деле вычисляет π вместо того , чтобы полагаться на встроенные константы или математике, то есть подделки math.acos(-1), math.radians(180)и т.д.


9

ассемблер x86 (5 символов)

fldpi

Загружает ли это постоянную из ПЗУ или фактически вычисляет ответ, зависит от процессора (но, по крайней мере, для некоторых, он фактически выполняет вычисления, а не просто загружает число из ПЗУ). Для сравнения, в списке 387 указано 40 тактов, что гораздо больше, чем кажется, имеет смысл, если бы оно просто загружало значение из ПЗУ.

Если вы действительно хотите обеспечить расчет, вы можете сделать что-то вроде:

fld1
fld1
fpatan
fimul f

f dd 4

[для 27 символов]


1
Вы можете объяснить, пожалуйста ?
Николас Барбулеско

И на некоторых процессорах, что будет fldpiделать вычисление ?
Николас Барбулеско

1
Я не думаю, что использование команды, которая загружает число pi (или даже вычисляет его на основе чьей-либо реализации asin или каких-либо существующих реализаций функций trig вообще), действительно имеет значение в духе «вычисления» чего-либо (фактор «сборщик omg не» это реально изменить) Возможно, перенести это на самую короткую из возможных реализаций ассемблера, и это можно назвать «вычислением».
Джейсон C

2
@JasonC: Для меня это звучит как совершенно произвольное понятие, и нет более реального смысла, чем мое решение о том, что люди должны самостоятельно выполнять сложение, вычитание, умножение и деление, если они хотят их использовать.
Джерри Коффин

3
@JerryCoffin Вместо того, чтобы спорить о технических деталях, достаточно сказать, что они asin(-1)не fldpiявляются ни особенно интересными, ни творческими. Нет смысла конкурировать, чтобы увидеть, чей любимый язык имеет самое короткое имя для предопределенных функций триггера и констант пи.
Джейсон C

8

bc -l, 37 байт

for(p=n=2;n<7^7;n+=2)p*=n*n/(n*n-1);p

Я не вижу других ответов, используя продукт Wallis , так как он назван в честь моего тезки (моя история математики лектор по получил большой удар от этого), я не смог устоять.

Оказывается, это довольно хороший алгоритм с точки зрения игры в гольф, но скорость его сходимости ужасна - приближается к 1 миллиону итераций, чтобы получить 5 десятичных знаков:

$ time bc -l<<<'for(p=n=2;n<7^7;n+=2)p*=n*n/(n*n-1);p'
3.14159074622629555058

real    0m3.145s
user    0m1.548s
sys 0m0.000s
$ 

bc -l, 15 байт

В качестве альтернативы мы можем использовать Ньютона-Рафсона для решения sin(x)=0с начальным приближением 3. Поскольку это сходится за очень небольшое количество итераций, мы просто жестко кодируем 2 итерации, что дает 10 десятичных знаков:

x=3+s(3);x+s(x)

Итерационная формула по Ньютон-Рафсону:

x[n+1] = x[n] - ( sin(x[n]) / sin'(x[n]) )

sin'=== cosи cos(pi)=== -1, поэтому мы просто приближаем cosтермин, чтобы получить:

x[n+1] = x[n] + sin(x[n])

Выход:

$ bc -l<<<'x=3+s(3);x+s(x)'
3.14159265357219555873
$ 

+1 теперь это больше нравится!
Джейсон С

@JasonC Каково ваше мнение о применении Ньютона-Рафсона для решения sin (x) = 0 (см. Редактирование)?
Цифровая травма

6

питон - 47 45

Пи на самом деле рассчитывается без триггерных функций или констант.

a=4
for i in range(9**6):a-=(-1)**i*4/(2*i+3)

результат:

>>> a
3.1415907719167966

Должен быть в состоянии сохранить байт, опустив ноль после десятичного знака для принудительной интерпретации с плавающей точкой. :) Бонусные баллы за краткость, но мне нравятся мои за произвольную точность и меньшее использование памяти. (Отредактировано, чтобы вычеркнуть идею в скобках; я вижу, что там происходит, и мой изолированный тест не уловил проблему.)
amcgregor

Э-э ... нет. После вашей модификации это больше не дает действительный вывод. (265723 ≭ π) Вам все еще нужен период, но не конечный ноль.
amcgregor

@amcgregor использовать Python 3?
Qwr

Я делаю, хотя я в основном разрабатываю под 2.7 и заставляю мой код работать в обоих. Однако на стандартной установке Mac 10.9 python3 ваш код вызывает ошибку сегментации.
amcgregor

@amcgregor Я только что проверил это, у меня это работает (python 3.3.4)
qwr

6

С, 99

Непосредственно вычисляет площадь / г ^ 2 круга.

double p(n,x,y,r){r=10000;for(n=x=0;x<r;++x)for(y=1;y<r;++y)n+=x*x+y*y<=r*r;return(double)n*4/r/r;}

Эта функция будет вычислять число пи путем подсчета количества пикселей в круге радиуса, а rзатем деления на r*r(фактически она просто рассчитывает один квадрант). С r10000, это с точностью до 5 знаков после запятой (3.1415904800). Параметры функции игнорируются, я просто объявил их там для экономии места.


6

Javascript, 43 36

x=0;for(i=1;i<1e6;i++){x+=1/i/i};Math.sqrt(6*x)

xстановится zeta(2)=pi^2/6так sqrt(6*x)=pi. (47 символов)

После использования свойства дистрибутива и удаления фигурных скобок из forцикла вы получите:

x=0;for(i=1;i<1e6;i++)x+=6/i/i;Math.sqrt(x)

(43 символа)

Возвращает:

3.14159169865946

Редактировать:

Я нашел еще более короткий путь, используя продукт Wallis:

x=i=2;for(;i<1e6;i+=2)x*=i*i/(i*i-1)

(36 символов)

Возвращает:

3.141591082792245

6

Питон, Риман Зета (58 41 символ)

(6*sum(n**-2for n in range(1,9**9)))**0.5

Или сэкономить два символа, но использовать scipy

import scipy.special as s
(6*s.zeta(2,1))**0.5

Редактировать : 16 символов (!) Благодаря amcgregor


1
Потенциально можно избежать mathимпорта и sqrtвызова, поворачиваясь к возведению в степень:(6*sum(n**-2 for n in range(1,9**9)))**0.5
amcgregor

5

Javascript: 99 символов

Используя формулу, приведенную Симоном Плуффом в 1996 году, это работает с точностью до 6 знаков после запятой:

function f(k){return k<2?1:f(k-1)*k}for(y=-3,n=1;n<91;n++)y+=n*(2<<(n-1))*f(n)*f(n)/f(2*n);alert(y)

Этот более длинный вариант (130 символов) имеет лучшую точность, 15 цифр после десятичной точки:

function e(x){return x<1?1:2*e(x-1)}function f(k){return k<2?1:f(k-1)*k}for(y=-3,n=1;n<91;n++)y+=n*e(n)*f(n)*f(n)/f(2*n);alert(y)

Я сделал это на основе моих двух ответов на этот вопрос .


5

Рубин, 54 50 49

p (0..9**6).map{|e|(-1.0)**e/(2*e+1)*4}.reduce :+

Онлайн версия для тестирования.

Другая версия без создания массива (50 символов):

x=0;(0..9**6).each{|e|x+=(-1.0)**e/(2*e+1)*4}; p x

Онлайн версия для тестирования.


Интересно увидеть языковые различия, которые могут дать такие компактные решения. Например, приведенный выше перевод Python состоит из 105 символов (после использования некоторых тривиальных приемов сжатия кода): a=__import__;reduce(a('operator').__add__,a('itertools').imap(lambda e:(-1.0)**e/(2*e+1)*4,xrange(9**6)))- обратите внимание на использование xrange / imap; в Python 3 вы можете избежать этого; по сути, я не хочу, чтобы вся ваша оперативная память использовалась при создании списка с таким количеством записей.
amcgregor

1
Ты абсолютно прав. Часто очень удобно использовать функции (особенно в Ruby) Array и Enumerable, хотя это может быть не самой лучшей идеей с точки зрения производительности и скорости ... Что ж, подумав об этом, можно сделать вычисления с Метод Range.each вместо создания карты.
Дэвид Херрманн

Да, это возможно - только один символ больше ...
Дэвид Херрманн

Ваш первый ответ не так точен, как ваш второй.
Джош

Не могли бы вы уточнить, пожалуйста? Тот же алгоритм, тот же вывод для меня?
Дэвид Херрманн

5

TI CAS, 35

lim(x*(1/(tan((180-360/x)/2))),x,∞)

1
Я оглянулся на это и совершенно забыл, как это работает: P
TheDoctor

5

Perl - 35 байт

$\=$\/(2*$_-1)*$_+2for-46..-1;print

Производит полную точность с плавающей точкой. Вывод использованной формулы можно увидеть в другом месте .

Пример использования:

$ perl pi.pl
3.14159265358979

Произвольная Точность Версия

use bignum a,99;$\=$\/(2*$_-1)*$_+2for-329..-1;print

Расширьте по мере необходимости. Длина итерации (например -329..-1) должна быть отрегулирована так, чтобы она была приблизительно равна log 2 (10)3,342 от количества цифр.

3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211707

Или, используя bigintвместо этого:

use bigint;$\=$\/(2*$_-1)*$_+2e99for-329..-1;print

Это работает заметно быстрее, но не включает десятичную точку.

3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067

5

C # 192

class P{static void Main(){var s=(new System.Net.WebClient()).DownloadString("http://www.ctan.org/pkg/tex");System.Console.WriteLine(s.Substring(s.IndexOf("Ver&shy;sion")+21).Split(' ')[0]);}}

Выходы:

3.14159265

Нет математики. Просто просматривает текущую версию TeX и выполняет примитивный разбор получившегося html. В конечном счете это станет π согласно Википедии .


Я опоздал на 5 лет, но это стандартная лазейка , созданная за 4 дня до ответа.
Бенджамин Уркхарт

5

Питон 3 Монте-Карло (103 знака)

from random import random as r
sum(1 for x,y in ((r(),r()) for i in range(2**99)) if x**2+y**2<1)/2**97

5

Game Maker Language, 34

Предполагает, что все неинициализированные переменные равны 0. Это значение по умолчанию в некоторых версиях Game Maker.

for(i=1;i<1e8;i++)x+=6/i/i;sqrt(x)

Результат:

3.14159169865946

очень хорошо. Кроме того, в C float k(){double x=0,i=0;for(;i++<999999;)x+=6/i/i;return sqrt(x);}короче, чем этот
izabera

еще короче с 1e8вместо 999999
изабера

Не могли бы вы использовать for(i=1;i<1e8;)x+=6/i/i++;sqrt(x)для сохранения байта (или в качестве альтернативы for(i=1;i++<1e8;))?
mbomb007

@ mbomb007 К сожалению, нет, для GML требуются все 3 параметра.
Timtech

4

Джава - 83 55

Укороченная версия благодаря Navin.

class P{static{System.out.print(Math.toRadians(180));}}

Старая версия:

class P{public static void main(String[]a){System.out.print(Math.toRadians(180));}}

Это не делает никаких расчетов.
Hosch250

Я не понимаю понижающий голос, хотя - я ответил "Math.toRadians (180)". Также сомнительно, кто вычисляет pi: компилятор или программу. Но это не было частью вопроса.
blabla999

2
@ user2509848 Это, безусловно, делает: он умножается 180на pi/180.
AJMansfield

Вы имеете в виду, что он умножает пи на 1? Это по сути то же самое. Я не отрицал это, но я не думаю, что это действительно имеет значение.
Hosch250

1
Может быть короче: codegolf.stackexchange.com/a/22057/14610
Navin


3

Руби, 82

q=1.0
i=0
(0.0..72).step(8){|k|i+=1/q*(4/(k+1)-2/(k+4)-1/(k+5)-1/(k+6))
q*=16}
p i

Использует формулу, которую я не очень понимаю, и просто скопировал. :П

Выход: 3.1415926535897913


3

Руби, 12

p 1.570796*2

Я имею технически «вычисление» PI приближение пи.


Нет, вы технически не рассчитываете пи. Вы технически рассчитываете 3.141592, которая оказывается близкой к пи, но никогда не будет точно сходиться acos(-1).
wchargin

@Wchar Хорошо, отредактировано
дверная ручка

3
Я не думаю, что жесткое кодирование pi / 2, тогда умножение его на 2 действительно имеет значение; Дело в том, чтобы вычислить число Пи, а не запутывать числовой литерал.
Джейсон С

3

JavaScript - 19 байт

Math.pow(29809,1/9)

Вычисляет 9- й корень из 29809 .

3.1415914903890925
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.