Я где-то читал о кругах, и только сейчас узнал о дисках ( это на самом деле довольно распространенная концепция ) и подумал о Codegolf.
Ваша задача - рандомизировать точку / несколько точек на диске с радиусом 1.
Правила:
- Все точки должны иметь одинаковую вероятность, чтобы быть сгенерированным
- Должны использоваться координаты с плавающей точкой; минимальное требование - два десятичных знака (например, точки
(0.12, -0.45)
или(0.00, -1.00)
действительны) - Вы получите -20 байт, если ваша программа на самом деле отображает ограничивающий круг и точки, сгенерированные в нем. Координаты по-прежнему должны быть действительными, но не отображаться, а размер сгенерированного изображения должен быть не менее 201 на 201 пикселей.
- Вы получите -5 байт, если ваша программа берет количество точек, которые будут сгенерированы как ввод на стандартном вводе
- Если вы решили не наносить ограничивающий круг и точки, ваша программа должна вывести точки, сгенерированные в формате
(x, y)
или(x,y)
на стандартном выводе. - Если вы решили взять количество сгенерированных точек в качестве входных данных, но не строить их на графике - ваша программа должна вывести все рандомизированные точки в указанном выше формате с одним пробелом или без него между
Кратчайшая подача в байтах побеждает!
code-golf
math
graphical-output
random
sweerpotato
источник
источник
0.3503082505747327+0.13499221288682994j
.Ответы:
Pyth, 26 - 5 = 21 байт
Принимает количество координат для генерации на stdin и выводит их на stdout следующим образом:
Использует стратегию, аналогичную @ MartinBüttner, для генерации полярных координат и радиусов, за исключением того, что она использует сложное возведение в степень.
источник
p
, не так ли? Он просто меняет вывод на отдельные строки.CJam,
2827 байтовЭто решение не основано на отклонении. Я генерирую точки в полярных координатах, но с неравномерным распределением радиусов для достижения равномерной плотности точек.
Проверьте это здесь.
объяснение
Почему это работает? Рассмотрим узкое кольцо радиуса
r
и (малой) шириныdr
. Площадь приблизительно равна2π*r*dr
(если кольцо узкое, внутренняя и внешняя окружность почти идентичны, и кривизну можно игнорировать, так что площадь можно рассматривать как площадь прямоугольника с длинами сторон окружности и шириной окружности). кольцевое пространство). Таким образом, площадь увеличивается линейно с радиусом. Это означает, что мы также хотим линейное распределение случайных радиусов, чтобы достичь постоянной плотности (при удвоенном радиусе площадь заполнения должна быть в два раза больше, поэтому нам нужно в два раза больше точек).Как мы генерируем линейное случайное распределение от 0 до 1? Давайте сначала посмотрим на дискретный случай. Скажем, у нас есть желаемое распределение в 4 значения, например
{0.1, 0.4, 0.2, 0.3}
(т.е. мы хотим1
быть в 4 раза чаще0
и вдвое чаще2
; мы хотим в3
три раза чаще0
):Как выбрать одно из четырех значений с желаемым распределением? Мы можем сложить их, выбрать равномерно случайное значение между 0 и 1 по оси Y и выбрать сегмент в этой точке:
Хотя есть и другой способ визуализации этого выбора. Вместо этого мы могли бы заменить каждое значение распределения на накопление значений до этого момента:
А теперь мы рассматриваем верхнюю строку этой диаграммы как функцию
f(x) = y
и инвертируем ее, чтобы получить функцию , которую мы можем применить к равномерно случайному значению в :g(y) = f-1(y) = x
y ∈ [0,1]
Круто, так как можно использовать это для генерации линейного распределения радиусов? Это дистрибутив, который мы хотим:
Первым шагом является накопление значений распределения. Но распределение непрерывно, поэтому вместо суммирования по всем предыдущим значениям мы берем интеграл от
0
доr
. Мы можем легко решить это аналитически . Тем не менее, мы хотим, чтобы это было нормализовано, то есть умножило это на константу так, чтобы это дало максимальное значение , так что мы действительно хотим :∫0r r dr = 1/2 r2
1
r
r2
И, наконец, мы инвертируем это, чтобы получить функцию, к которой мы можем применить единообразное значение
[0,1]
, что мы снова можем сделать аналитически: простоr = √y
, гдеy
случайное значение:Это довольно полезный метод, который часто можно использовать для точной генерации простых дистрибутивов (он работает для любого дистрибутива, но для сложных двух последних шагов, возможно, придется решать численно). Однако я бы не стал использовать его в данном конкретном случае в производственном коде, потому что квадратный корень, синус и косинус чрезмерно дороги: использование алгоритма на основе отклонения в среднем намного быстрее, потому что оно требует только сложения и умножения.
источник
Mathematica,
6844 - 20 = 24 байтаБольшое спасибо Дэвиду Каррахеру за сообщение о том
RandomPoint
, что сэкономило 24 (!) Байта. Mathematica имеет имеет встроенный для всего.Это показывает точку и ограничивающий круг, чтобы претендовать на бонус:
В результате получается векторное изображение, поэтому указание размера в 201x201 пикселей не имеет особого смысла, но по умолчанию оно отображается больше, чем это.
источник
Graphics[{Circle[], Point@RandomPoint@Disk[]}]
?Graphics@{Circle[], Point@RandomPoint@Disk[]}
,
?CJam,
3126 байтЭто работает путем многократного генерирования случайных точек в квадрате с длиной стороны 2 и сохранения первой, которая попадает внутрь диска устройства.
Спасибо @ MartinBüttner за 3 байта!
Попробуйте онлайн в интерпретаторе CJam .
Как это устроено
источник
iKe ,
5351 байтНичего особенного, но я полагаю, у нас должно быть хотя бы одно графическое решение:
Попробуйте это в вашем браузере .
Изменить: я могу сбрить два байта, применяя подход @ MartinBüttner для изменения распределения полярных координат. Я думаю, что это также немного более прямо:
источник
Perl, 59 байт
Это просто простое решение: генерировать точки в квадрате и отбрасывать их слишком далеко. Моя особенная игра в гольф состоит в том, чтобы включить в условие домашние задания.
Изменить: В процессе игры в гольф, я нашел интересный способ печати случайных точек на круге .
источник
Октава,
2453 - 20 = 33 байтаГенерирует 501 тэта-значения с равным интервалом плюс одно случайное число и масштабирует их все до [0..2π]. Затем генерирует 501 1 для радиуса круга плюс случайный радиус для точки и принимает квадратный корень, чтобы обеспечить равномерное распределение по диску. Затем строит все точки как полярные координаты.
Вот быстрая демонстрация распределения (без единичного круга):
источник
Октава / Матлаб,
7464 байтаМетод отклонения , 64 байта:
Прямой метод , 74 байта (спасибо Martin Büttner за помощь в исправлении двух ошибок):
источник
R,
999581-20 =797561 байтИспользуйте построение комплексного числа, чтобы построить x / y's из полярных координат. Взятие входных данных было немного дороже, и, вероятно, есть лучший способ сделать это.
ylim
Изаключается в обеспечении весь круг строится иxlim
asp
обеспечивает точки показаны под символом окружности.Спасибо @jbaums и @flodel за экономию
Попробуй здесь
источник
runif(9,0,1)
можно упростить доrunif(9)
symbols(0,0,1,i=F,asp=1,ylim=c(-1,1));points(complex(,,,runif(9),runif(9,-1)*pi))
yli
работает вместоylim
.Обработка / Java 141 байт-20 = 121
требование минимального размера 201 * 201 требует, чтобы я включил
setup
метод, поскольку Processing.org по умолчанию имеет значение 200x200 :(источник
QBasic, 138 байтов - 20 - 5 = 113
Принимает пользовательский ввод и рисует диск и очки. Протестировано на QB64 .
Это довольно простая стратегия «бросай в дартс». Суть в том, что «то, что прилипает», определяется не математически, а графически: белый диск наносится на черный фон, а затем случайно сгенерированные точки отклоняются до тех пор, пока они не станут черными. Сами точки нарисованы синим цветом (хотя трудно сказать, когда они единичные пиксели - нажмите на изображение, чтобы увеличить).
источник
awk - 95 - 5 = 90
Так как я не был полностью уверен в части rand () <. 5, я провел некоторое тестирование дистрибутива с помощью этого сценария:
который для входа 1e7 дает мне этот результат после того, как я выпил один или два раза за своим кофе:
что я думаю вполне нормально.
Небольшое объяснение:
после того, как я немного поцарапал, оказалось, что если вы хотите разделить диск на четыре кольца с равной площадью, то радиусы, по которым вам придется разрезать, будут sqrt (1/4), sqrt (1/2 ) и sqrt (3/4). Поскольку фактический радиус точки, которую я проверяю, будет sqrt (x ^ 2 + y ^ 2), я могу пропустить квадратный корень все вместе. «Совпадение» 1/4, 2/4, 3/4 может быть связано с тем, что ранее указывал М. Бюттнер.
источник
HPPPL , 146 (171-20-5) байтов
Пример для 10000 баллов (включая время в секундах для реального устройства):
Сама функция вызывается
r(n)
. Остальное на изображении выше только для целей синхронизации.Результат (диаметр диска 236 пикселей):
Версия выше не хранит координаты точки, поэтому я написал версию, которая принимает два параметра
r(n,p)
.n
количество баллов иp=0
возвращает баллы в терминал,p=1
наносит на карту точки и диск), если сохранение координат является обязательным. Эта версия имеет длину 283 (308-20-5) байтов:Негольфированная версия:
Терминальный выход для
r(10,0)
:r(10,1)
показывает диск с точками, как показано выше.источник
JavaScript, 75 байт
Отторжение на основе:
Прямой метод (80 байт):
источник
Python,
135130 байтУдалено
**0.5
спасибо предложению @ jimmy23013 (поскольку это единичный круг, я сейчас проверяю, равно ли квадрат в квадрате между (x, y) и (0, 0) равен 1 2. Это то же самое).Это также освободило меня, чтобы убрать скобки.
источник
**0.5
.