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


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.