Счастливого Пи Дня всем! Без всякой причины я пытаюсь построить оценку Пи по методу Монте-Карло, которая будет максимально короткой. Можем ли мы построить тот, который может вписаться в твит?
Чтобы уточнить, что я имею в виду, это типичный подход вытягивания случайных точек из единичного квадрата и вычисления отношения, попадающего в единичный круг. Количество образцов может быть жестко закодировано или нет. Если вы жестко закодировали их, вы должны использовать не менее 1000 образцов. Результат может быть возвращен или напечатан как число с плавающей запятой, фиксированная точка или рациональное число.
Никакие функции триггера или константы Пи не должны быть подходом Монте-Карло.
Это код гольф, поэтому выигрывает самое короткое представление (в байтах).
источник
((0..4e9).map{rand**2+rand**2<1}.to_s.sub(/./,"$1.")
map
дает вам массивtrue
иfalse
?.filter{...}.size
должно работать, хотя.Ответы:
80386 машинный код,
4038 байтHexdump кода:
Как получить этот код (с языка ассемблера):
Это функция, использующая
fastcall
соглашение о вызовах MS (количество итераций передается в регистреecx
). Возвращает результат вst
регистр.Забавные вещи об этом коде:
rdrand
- всего 3 байта для генерации случайного числа!D
) с квадратом радиуса (2^32
) выполняется автоматически - флаг переноса содержит результат.источник
eax
; тоmul
команда умножает его само по себе и ставит высокую долю вedx
; нижняя часть вeax
отбрасывается.Matlab / Octave, 27 байт
Я знаю, что уже есть ответ Matlab / Octave, но я попробовал свой собственный подход. Я использовал тот факт, что интеграл от
4/(1+x^2)
0 до 1 является пи.источник
R, 40 (или 28 или 24 с использованием других методов)
Python 2, 56
Еще один Python, если NumPy разрешен, но очень похож на Matlab / Octave:
источник
Mathematica,
424039 байт (или 31/29?)У меня есть три решения по 42 байта:
Все они являются неназванными функциями, которые берут количество выборок
n
и возвращают рациональное приближение π. Сначала все они генерируютn
точки в единичном квадрате в положительном квадранте. Затем они определяют количество тех выборок, которые лежат в единичном круге, а затем делят их на количество выборок и умножают на4
. Разница лишь в том, как они определяют количество образцов в круге единицы:Count
с условием, чтоNorm[p] < 1
.1
а затем округляет. Это превращает числа внутри круга устройства в1
и те, что снаружи0
. После этого я просто подвожу их всехTr
.1.5
, так что я могу использоватьRound
вместоCeiling
.Во время написания этой статьи мне пришло в голову, что действительно есть более короткое решение, если я просто вычту
2
и затем используюFloor
:или сохранение другого байта с использованием операторов Unicode для настилов или потолков:
Обратите внимание, что три решения на основе округления также могут быть записаны с использованием
Mean
вместоTr
и без/#
, опять же для тех же байтов.Если другие подходы, основанные на Монте-Карло, хороши (в частности, тот, который выбрал Питер), я могу сделать 31 байт, оценивая интеграл или 29, используя интеграл , на этот раз в виде числа с плавающей запятой:
√(1-x2)
1/(1+x2)
источник
CJam,
27 2322 или 20 байтов2 байта сохранены благодаря Runner112, 1 байт сохранен благодаря Sp3000
Он принимает количество итераций из STDIN в качестве входных данных.
Это так же просто, как и получается. Это основные этапы:
Расширение кода :
Попробуйте онлайн здесь
Если среднее значение
1/(1+x^2)
также считается Монте-Карло, то это можно сделать в 20 байтах:Попробуй здесь
источник
1dmr
вместоKmrK/
, и проверить, больше ли сумма квадратов с 1 сi
вместо1>
(я думал, что это было особенно умным) ,i
трюк действительно аккуратный! И, черт побери, отсутствие документации для1dmr
Python 2,
7775 байтИспользует 4000 образцов для сохранения байтов
1e3
.источник
...*8000;print a/2e3
.Commodore 64 Basic, 45 байт
PETSCII замены:
─
=SHIFT+E
,/
=SHIFT+N
,┌
=SHIFT+O
Создает 1000 очков в первом квадранте; для каждого добавляет правдивость «x ^ 2 + y ^ 2 <1» к текущему счету, а затем делит счет на 250, чтобы получить
pi
. (Наличие знака минус объясняется тем, что на C64 "true" = -1.)источник
(1)
?/
это не символ деления, это символ, полученный при наборе текстаSHIFT+N
на клавиатуре Commodore 64.R/(1)
это сокращенная форма дляRND(1)
, т.е. msgstr "произвести случайное число от 0 до 1, используя текущий начальный уровень ГСЧ".J, 17 байт
Вычисляет среднее значение
40000
значений выборки функции4*sqrt(1-sqr(x))
в диапазоне[0,1]
.Легко
0 o.x
возвращаетсяsqrt(1-sqr(x))
.источник
> <> (Рыба) , 114 байт
Теперь> <> не имеет встроенного генератора случайных чисел. Однако у него есть функция, которая отправляет указатель в случайном направлении. Генератор случайных чисел в моем коде:
Он в основном генерирует случайные биты, которые составляют двоичное число, а затем преобразует это случайное двоичное число в десятичное.
Все остальное - просто правильные точки в квадрате.
Использование: когда вы запускаете код, вы должны предварительно заполнить стек (-v в интерпретаторе Python), например, количеством выборок.
возвращается
источник
Matlab или Octave 29 байт (благодаря flawr!)
(Я не совсем уверен, что <1 в порядке. Я прочитал, что должно быть <= 1. Но насколько велика вероятность нарисовать ровно 1 ...)
Matlab или Octave 31 байт
источник
mean(sum(rand(2,4e6).^2)<1)*4
.Java, 108 байт
Четыре тысячи итераций, добавляя 0,001 каждый раз, когда точка находится внутри единичного круга. Довольно простые вещи.
Примечание. Да, я знаю, что могу сбросить четыре байта, изменив
π
однобайтовый символ. Мне нравится это так.источник
Javascript: 62 байта
Я использовал предыдущий (теперь удаленный) ответ javascript и побрил 5 байтов.
источник
GolfScript (34 символа)
Онлайн демо
При этом используется фиксированная точка, потому что GS на самом деле не имеет плавающей точки. Это немного злоупотребляет использованием фиксированной точки, поэтому, если вы хотите изменить количество итераций, убедитесь, что оно в два раза больше десяти.
Кредит XNOR для конкретного метода Монте - Карло , используемого.
источник
Python 2,
908581 байтвозвращается
3.14120037157
к примеру. Количество образцов составляет 4782969 (9 ^ 7). Вы можете получить лучший пи с 9 ^ 9, но вам придется набраться терпения.источник
range(9**7)
с[0]*9**7
или что - то, так как вы не используетеi
. И список не слишком длинный, чтобы столкнуться с проблемами с памятью.range()
но я полностью забыл этот трюк.[0]9**7
что синтаксис недействителенРубин, 39 байт
Одним из основных моментов является то, что этот может использовать
8e5
нотацию, что делает его расширяемым до ~ 8e9 выборок при одном и том же количестве байтов программы.источник
Perl 6 , 33 байта
Попробуйте онлайн!
Это функция, которая принимает количество выборок в качестве аргумента.
источник
Scala,
877766 байтисточник
1000
на8000
и250d
с2e4
вами оба, сохраните байт и увеличите количество семплов в 8 раз.Чистый Баш, 65 байт
Принимает один параметр командной строки, который умножается на 4, чтобы получить количество выборок. Арифметика Bash только целочисленная, поэтому рациональным является вывод. Это может быть передано
bc -l
для окончательного разделения:источник
Джо ,
2019 байтПримечание: этот ответ не является конкурирующим, потому что версия 0.1.2, которая добавила случайность, была выпущена после этого испытания.
Именованная функция F:
Безымянная функция:
Они оба принимают количество отсчетов в качестве аргумента и возвращают результат. Как они работают?
Пример работы:
источник
постоянный ток, 59 символов (пробел игнорируется)
Я проверил это на Plan 9 и OpenBSD, поэтому я думаю, что он будет работать на Linux (GNU?)
dc
.Пояснения к строке:
i
если 1 больше, чем сумма их квадратов] в регистреu
.x
на 1] в регистреi
.u
, увеличить регистрm
, а затем выполнить регистр,z
если регистрm
больше регистраn
] в регистреz
.Установите масштаб до 5 десятичных знаков.
z
.x
(количество попаданий) на регистрn
(количество баллов), умножьте результат на 4 и напечатайте.Однако я обманул
Программе нужен набор случайных чисел от 0 до 1.
Использование:
Тестовый забег:
Теперь с меньшим количеством читов (100 байт)
Кто-то указал, что я мог бы включить простой prng.
http://en.wikipedia.org/wiki/RANDU
Ungolfed
Тестовый забег:
источник
Пиф, 19
Введите желаемое количество итераций в качестве входных данных.
демонстрация
Поскольку у Пита нет функции «Случайное число с плавающей точкой», мне пришлось импровизировать. Программа выбирает два случайных натуральных числа меньше входных, квадратов, сумм и сравнивает их с квадратом ввода. Это выполняется количество раз, равное входному значению, затем результат умножается на 4 и делится на входное значение.
В связанных новостях я скоро добавлю случайную операцию с плавающей запятой в Pyth. Однако эта программа не использует эту функцию.
Если мы интерпретируем «Результат может быть возвращен или напечатан как число с плавающей запятой, фиксированная точка или рациональное число». Обильно, тогда печати числителя и знаменателя полученной дроби должно быть достаточно. В таком случае:
Пиф, 18
Это идентичная программа, с
c
удаленной операцией деления с плавающей запятой ( ).источник
Юлия, 37 байт
Количество образцов составляет 65536 (= 4 ^ 8).
Немного более длинный вариант: функция с числом выборок
s
в качестве единственного аргумента:источник
C, 130 байтов
Ungolfed:
источник
f()
. Какой компилятор вы использовали? См. Tio.run/##Pc49C4JAHIDx3U9xGMG9ZdYgwWkgtNbQ1BZ6L/UHO8M07hA/…На самом деле , 14 байтов (не конкурирующих)
Попробуйте онлайн!
Это решение неконкурентное, потому что язык ставит после проблемы. Количество выборок дается как ввод (а не жестко запрограммировано).
Объяснение:
источник
Ракетка 63 байта
Используя метод ответа языка R @Matt:
Ungolfed:
Тестирование:
Выход (дробь):
В десятичном виде:
источник
Фортран (GFortran) ,
8483 байтаПопробуйте онлайн!
Этот код очень плохо написал. Он потерпит неудачу, если gfortran решит инициализировать переменную
A
с другим значением, отличным от 0 (что происходит примерно в 50% сборок ), и, еслиA
инициализируется как 0, он всегда будет генерировать одну и ту же случайную последовательность для данного начального числа. Затем всегда выводится одно и то же значение для Pi.Это намного лучшая программа:
Фортран (GFortran) ,
10099 байтПопробуйте онлайн!
(Один байт сохранен в каждой версии; спасибо Penguino).
источник
Japt , 26 или 18 байт
Попробуйте онлайн!
Аналогично ответу Оптимизатора , в основном просто пытаюсь выучить Джапта.
Принимает количество итераций для неявного ввода
U
.Если
1/(1+x^2)
разрешено (вместо двух отдельных случайностей), то мы можем получить 18 байтов с той же логикой.источник
Mh
вычислять гипотенузу, а не делать это самостоятельно ;-) Кроме того, вы можете использовать,x
чтобы взять сумму массива, а не уменьшать путем сложения:o x@MhMr Mr)<1Ã*4/U
Mh
это, спасибо! Ваш случайный ответ почти такой же короткий, как мой ответ только с одним случайным ответом, это довольно круто. Я буду иметьx
в виду, я склонен часто использовать сокращение, когда пытаюсь играть в гольф, так что это очень пригодится.F #, 149 байт
Попробуйте онлайн!
Насколько я могу понять, для выполнения такого рода промежуточного итога в F # создать массив чисел и использовать
Seq.sumBy
метод короче, чем использоватьfor..to..do
блок.Что делает этот код, так это то, что он создает коллекцию чисел с плавающей запятой от 1 до
s
, выполняет функциюfun x->...
для количества элементов в коллекции и суммирует результат. Вs
коллекции есть элементы, поэтому случайный тест проводитсяs
раз. Фактические числа в коллекции игнорируются (fun x->
ноx
не используются).Это также означает, что приложение должно сначала создать и заполнить массив, а затем выполнить итерацию по нему. Так что, вероятно, в два раза медленнее, чем
for..to..do
цикл. А при использовании массива создание памяти находится в области O (f ** k)!Для самого теста вместо использования
if then else
оператора он вычисляет расстояние (q()+q()|>Math.Sqrt
) и округляет егоMath.Floor
. Если расстояние находится внутри круга, оно будет округлено до 0. Если расстояние находится за пределами круга, оно будет округлено до 1.Seq.sumBy
метод суммирует эти результаты.Обратите внимание, что
Seq.sumBy
в итоге мы имеем не точки внутри круга, а точки за его пределами . Так что для результата требуетсяs
(наш размер выборки) и вычитает из него сумму.Также представляется, что выбор размера выборки в качестве параметра короче, чем жесткое кодирование значения. Так что я немного изменяю ...
источник
Хаскелл,
11611411096 байтПотому что иметь дело с
import System.Random; r=randoms(mkStdGen 2)
заняла бы слишком много драгоценных байтов, я генерирую бесконечный список случайных чисел с линейным конгруэнтным генератором, который, по мнению некоторых, почти криптографически силен:x↦x*9+1 mod 8^9
по теореме Халла-Добелла полный период равен8^9
.g
дает,4
если точка случайного числа находится внутри круга для пар случайных чисел в[0..8^9-1]
потому что это исключает умножение в используемой формуле.Использование:
Попробуйте онлайн!
источник
Perl 5, 34 байта
Количество образцов берется из стандартного ввода. Требуется
-p
.Работает потому что:
Попробуйте онлайн!
источник