Случайный Гольф Дня № 7: отчетливо случайный персонаж


47

О серии

Это гостевая запись для серии Random Golf of the Day.

Во-первых, вы можете относиться к этому, как к любому другому вызову для игры в гольф, и отвечать на него, не беспокоясь о серии вообще. Тем не менее, существует таблица лидеров по всем задачам. Вы можете найти таблицу лидеров вместе с дополнительной информацией о серии в первом посте .

вход

Вход не принимается.

Выход

Одна буква алфавита (регистр не имеет значения), с дополнительным завершающим переводом строки. Каждая буква должна иметь ненулевую вероятность быть выбранной, и все 26 вероятностей должны быть различны . Устранить всю двусмысленность: Различия означает, что не должно быть двух вероятностей, которые равны друг другу.

счет

Это код гольф. Самый короткий код в байтах побеждает.

Допустимая запись - это полная программа или функция с нулевой вероятностью не завершиться.

Алфавит

Чтобы избежать путаницы, конкретным алфавитом, который нужно использовать, является латинский алфавит:

Или

ABCDEFGHIJKLMNOPQRSTUVWXYZ

или же

abcdefghijklmnopqrstuvwxyz

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

объяснение

Поскольку это не будет очевидно из результатов, пожалуйста, включите четкое объяснение того, как вы достигли 26 различных вероятностей.

Leaderboard

( отсюда )

Первый пост серии также генерирует общую таблицу лидеров.

Чтобы убедиться, что ваши ответы отображаются, начните каждый ответ с заголовка, используя следующий шаблон уценки:

## Language Name, N bytes

где Nразмер вашего представления. Если вы улучшите свой счет, вы можете сохранить старые результаты в заголовке, вычеркнув их. Например:

## Ruby, <s>104</s> <s>101</s> 96 bytes

(Язык в настоящее время не отображается, но фрагмент требует и анализирует его, и я могу добавить таблицу лидеров по языкам в будущем.)


Как бы вы измерили 26 различных вероятностей? запустив программу 26 раз?
ВЫ

1
@YOU взгляните на решения - есть несколько разных подходов с отличными объяснениями
trichoplax

Если это функция, нужно ли ее печатать или она просто возвращает значение символа?
Джефф Риди

@Geoff В соответствии с нашими настройками по умолчанию для ввода и вывода , можно либо печатать в STDOUT, либо возвращать символ.
Трихоплакс

@ Обратите внимание, что это должен быть символ, а не просто числовое значение, представляющее его. Например, Aа не 65.
трихоплакс

Ответы:


13

Пиф, 5

Os._G

Попробуй здесь

Вычисляет префиксы алфавита, так: ["a", "ab", "abc", ..., "abcdefghijklmnopqrstuvwxyz"]. Затем сглаживает список и равномерно выбирает из него случайный элемент. Это означает, что, поскольку aпоявляется 26 раз, а bпоявляется 25 раз, вплоть до zвсего лишь 1 появления, каждая буква имеет различную вероятность появления. Общая строка имеет 351 символов.


1
Мне нравится этот ответ. Очень умно.
Аллен Фишер

24

MATL, 6 персонажей

1Y2Xr)

Объяснение:

XrВозьмите нормально распределенное случайное число. )Используйте это для индексации в ... 1Y2Алфавит

Распределение симметрично около 0, а преобразование числа в символ симметрично около 0,5. Как таковые вероятности должны быть четкими.


2
О, очень хорошая идея использовать распределение Гаусса!
Луис Мендо

1
«лучший» язык для работы, все еще избитый желе. Отличное решение, хотя.
Сократов Феникс

19

05AB1E , 6 байтов

Код

A.pJ.R

объяснение

A        # Pushes the alphabet
 .p      # Computes all prefixes
   J     # Join them together

Теперь у нас есть следующая строка:

aababcabcdabcdeabcdefabcdefgabcdefghabcdefghiabcdefghijabcdefghijkabcdefghijklabcdefghijklmabcdefghijklmnabcdefghijklmnoabcdefghijklmnopabcdefghijklmnopqabcdefghijklmnopqrabcdefghijklmnopqrsabcdefghijklmnopqrstabcdefghijklmnopqrstuabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvwabcdefghijklmnopqrstuvwxabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz

После этого мы выбираем случайный элемент, используя .R.

Вероятности

a > 7.4074074074074066%
b > 7.122507122507122%
c > 6.837606837606838%
d > 6.552706552706553%
e > 6.267806267806268%
f > 5.982905982905983%
g > 5.698005698005698%
h > 5.413105413105414%
i > 5.128205128205128%
j > 4.843304843304843%
k > 4.5584045584045585%
l > 4.273504273504274%
m > 3.988603988603989%
n > 3.7037037037037033%
o > 3.418803418803419%
p > 3.133903133903134%
q > 2.849002849002849%
r > 2.564102564102564%
s > 2.2792022792022792%
t > 1.9943019943019944%
u > 1.7094017094017095%
v > 1.4245014245014245%
w > 1.1396011396011396%
x > 0.8547008547008548%
y > 0.5698005698005698%
z > 0.2849002849002849%

Попробуйте онлайн! ,


18

Желе , 5 байт

ØA»ẊX

Попробуйте онлайн!

Как это устроено

ØA«ẊX  Main link. No arguments.

ØA     Set argument and return value to the alphabet.
   Ẋ   Shuffle it.
  »    Yield the maximum of each letter in the sorted alphabet, and the
       corresponding character in the shuffled one.
    X  Pseudo-randomly select a letter of the resulting array.

Фон

Пусть L 0 , ..., L 25 обозначает буквы алфавита в их естественном порядке, и S 0 , ..., S 25 равномерно произвольно выбранная , перестановка L . Определим конечную последовательность M как M n = max (L n , S n ) .

Зафиксируем n в 0,… 25 и определим k как индекс, такой что L n = S k .

С вероятностью 1/26 , L п = S п и п = к , так что М н = л н и л н occurrs один раз в М .

С вероятностью 25/26 , L п ≠ S п и п ≠ к . В этом случае происходит следующее.

  • С вероятностью Н / 25 , S п является одним из L 0 , ..., L п - 1 , так что л п > S п и М п = л н .

  • Независимо, также с вероятностью n / 25 , k является одним из 0,… n - 1 , поэтому S k > L k и M k = S k = L n .

Таким образом, ожидаемое количество вхождений L n в M составляет 1/26 + 25/26 · (n / 25 + n / 25) = (2n + 1) / 26 .

Наконец, если мы теперь выберем член m из M случайным образом, букву L n мы выберем с вероятностью (2n + 1) / 26/26 = (2n + 1) / 676 .

Это дает следующее распределение вероятностей.

p(m = A) =  1/676 ≈ 0.00148
p(m = B) =  3/676 ≈ 0.00444
p(m = C) =  5/676 ≈ 0.00740
p(m = D) =  7/676 ≈ 0.01036
p(m = E) =  9/676 ≈ 0.01331
p(m = F) = 11/676 ≈ 0.01627
p(m = G) = 13/676 ≈ 0.01923
p(m = H) = 15/676 ≈ 0.02219
p(m = I) = 17/676 ≈ 0.02515
p(m = J) = 19/676 ≈ 0.02811
p(m = K) = 21/676 ≈ 0.03107
p(m = L) = 23/676 ≈ 0.03402
p(m = M) = 25/676 ≈ 0.03698
p(m = N) = 27/676 ≈ 0.03994
p(m = O) = 29/676 ≈ 0.04290
p(m = P) = 31/676 ≈ 0.04586
p(m = Q) = 33/676 ≈ 0.04882
p(m = R) = 35/676 ≈ 0.05178
p(m = S) = 37/676 ≈ 0.05473
p(m = T) = 39/676 ≈ 0.05769
p(m = U) = 41/676 ≈ 0.06065
p(m = V) = 43/676 ≈ 0.06361
p(m = W) = 45/676 ≈ 0.06657
p(m = X) = 47/676 ≈ 0.06953
p(m = Y) = 49/676 ≈ 0.07249
p(m = Z) = 51/676 ≈ 0.07544

Вы можете эмпирически проверить распределение, позвонив по ссылке 100 000 раз (это займет несколько секунд).


1
@RobertFraser шаг shuffle-and-yield создает список с A где угодно, где A появляется в любом списке, B, где B появляется в любом списке, и с чем угодно, кроме A в другом списке, ... Z где угодно, что Z появился в обоих списках. Таким образом, в результате получается примерно в 52 раза больше А, чем Z.
Спарр

1
@RobertFraser Я добавил объяснение.
Деннис

2
@DennisJaheruddin В UTF-8, да. Однако Jelly использует пользовательскую кодовую страницу, которая кодирует все символы, которые она понимает, как один байт каждый. В байтах ссылаются в точках заголовка к нему.
Деннис

2
Я вижу, когда я читал объяснение, не сразу было ясно, что вы не можете также использовать преимущества обычного диапазона UTF-8. Итак, прав ли я, что, изменив интерпретатор и отобразив все символы на отдельные символы UTF-8, вы получите полностью идентичный код (просто менее читаемый / типизируемый)? - Если это так, рассмотрите возможность расширения объяснения, чтобы упомянуть, что для целей игры в гольф должен учитываться символ.
Деннис Джаэруддин

2
@DennisJaheruddin Как объяснено в README (первая ссылка в заголовке), интерпретатор имеет два режима (кодовая страница Jelly и UTF-8), поэтому вы можете сохранить эту программу в фактическом 5-байтовом файле. Я мог бы добавить всю эту информацию к каждому написанному мной ответу, но их сотни, поэтому я выбрал ссылку.
Денис

14

MATL , 10 байт

1Y2rU26*k)

Попробуйте онлайн!

Код генерирует равномерную случайную величину на интервале (0,1) ( r) и вычисляет ее квадрат ( U). Это приводит к неравномерному уменьшению плотности вероятности. Умножение на 26 ( 26*) гарантирует, что результат находится на интервале (0,26), а округление вниз ( k) дает значения 0,1, ..., 25 с уменьшением вероятностей. Значение используется в качестве индекса ( )) в верхнем регистре алфавита ( 1Y2). Поскольку MATL использует модульную индексацию на основе 1, 0 соответствует Z, 1 - A, 2 - B и т. Д.

В качестве иллюстрации того, что вероятности различны, вот дискретная гистограмма, полученная из 1000000 случайных реализаций. График получается при запуске этого в Matlab:

bar(0:25, histc(floor(26*rand(1,1e6).^2), 0:25))

введите описание изображения здесь


1
Приятно! Лучшее решение, которое я мог придумать, - это 16 байтов
DJMcMayhem

1
@DJMcMayhem Хороший подход!
Луис Мендо

Возможно, но намного дольше. : P
DJMcMayhem

Еще одна забавная альтернатива: matl.suever.net/…
Suever

На самом деле вам не нужно k! Заметил, что во время попытки codegolf.stackexchange.com/a/89648/11159
Деннис Джаэруддин

13

Java 7, 62 57 56 байт

5 байтов благодаря Poke.

1 байт благодаря трихоплаксу.

char r(){return(char)(65+(int)Math.sqrt(Math.random()*676));}
char r(){return(char)(65+Math.sqrt(Math.random()*676));}
char r(){return(char)(65+Math.sqrt(Math.random())*26);}

Идео это!

Частотная диаграмма (1e6 работает, коэффициент масштабирования 1/1000)

A: *
B: ****
C: *******
D: **********
E: *************
F: ****************
G: *******************
H: **********************
I: *************************
J: ***************************
K: ******************************
L: **********************************
M: ************************************
N: ***************************************
O: *******************************************
P: *********************************************
Q: ************************************************
R: ***************************************************
S: ******************************************************
T: *********************************************************
U: ************************************************************
V: ***************************************************************
W: ******************************************************************
X: *********************************************************************
Y: ************************************************************************
Z: ***************************************************************************

1
Я не думаю, что вам нужно типизировать int
Poke

@Poke Спасибо, игра в гольф.
Утренняя монахиня

Можете ли вы сохранить байт, переместив 676 за скобки?
трихоплакс

@trichoplax Что ты имеешь в виду?
Утренняя монахиня

2
sqrt(x*y*y) = sqrt(x)*y
Трихоплакс

10

Perl, 24 байта

-4 байта благодаря @Martin Ender
-1 байт благодаря @Dom Hastings

say+(A..Z)[rand rand 26]

Необходимо -M5.010или -Eзапустить:

perl -E 'say+(A..Z)[rand rand 26]'

Выполнение следующего кода покажет вхождение каждой буквы:

perl -MData::Printer -E '$h{(A..Z)[rand rand 26]}++ for 1 .. 1_000_000;$h{$_} = int($h{$_} / 100) / 100 for A .. Z;p %h;'
A 16.4
B 11.02
C 8.99
...
Z 0.07


Как это работает : Я полагаю, код довольно явный, но все же: он выбирает случайное число между 0и rand 26. Таким образом, вероятность выбора чисел, близких к 0(букве A), намного выше .


Объяснение имеет смысл для меня :)
trichoplax

Отличное решение! Вы можете сохранить 1 байт, используя пустой список и +:say+(A..Z)[rand rand 26]
Dom Hastings

@DomHastings аарф, я тупой. Я попытался, (A..Z)[...]и это не сработало, поэтому я подумал, что смогу использовать анонимный массив, но это только из-за say... спасибо! :)
Дада

10

PHP, 44 36 29 27 байт

Вычеркнуто 44 все еще регулярно 44; (

Спасибо insertusername здесь, Petah и Crypto за всю помощь

<?=chr(65+rand(0,675)**.5);

Он выбирает случайное число от 0 до 675 (= 26 2 -1), берет его квадратный корень и вычитает его ( chrфункция преобразует свой аргумент в целое число). Поскольку квадраты имеют разные интервалы между ними, вероятность каждого выбранного числа различна. Каждый n выбран с вероятностью (2n + 1) / 676.

Добавление 65 к этому числу дает вам случайный символ от Aдо Z.

Идея кода работает 1000000 раз


Вы можете играть в гольф от 4 байта : range(A,Z).
insertusername здесь

@insertusernamehere: Спасибо за подсказку, но я смог сыграть 8 байт, вообще не используя диапазон и просто используя chr().
Деловая кошка


1
@insertusernamehere Вы слишком легко <s>&nbsp;44&nbsp;</s>
сдаётесь

<?=chr(65+sqrt(rand(0,675)));
Петах

8

R, 40 27 байт

LETTERS[sample(26,1,,1:26)]

Это будет принимать 1число из 26чисел, сгенерированных с растущей вероятностью к Z, без замены, и отображать букву, индекс которой является этим числом, из списка заглавных букв LETTERS.

Аргументы sampleфункции:

sample(
       26, #How many numbers to generate
        1, #How many numbers to sample
         , #Replacing ? Here, no by default
     1:26, #Weight of probabilities
       )

Да, это не сработает. Там может быть мне самый умный путь!
Фредерик

Ну, где-то всегда будет подкладка! Должен думать, о ...
Фредерик

1
Исправлено и короче - впечатляет :)
trichoplax

1
@trichoplax Спасибо! Хороший вызов, кстати!
Фредерик

1
@AlbertMasclans: Это действительно так, но это уже было сделано в ответе кого-то другого, поэтому я не хочу «копировать»! Но все равно спасибо ! ;)
Фредерик

8

> <> , 14 байт

lx
;>dd+%'A'+o

> <> - это тороидальный двумерный язык, и определенная часть вероятностей просто естественным образом происходит из-за единственного источника случайности языка. Попробуйте онлайн!

Соответствующие команды:

[Row 1]
l          Push length of stack
x          Change the instruction pointer direction to one of up/down/left/right
           This gives a 50/50 chance of continuing on the first row (moving
           left/right) or going to the next row (moving up/down, wrapping if up)

[Row 2]
>          Change IP direction to right
dd+%       Take top of stack mod 26 (dd+ = 13+13 = 26)
'A'+       Add 65
o          Output as character
;          Halt

Таким образом, вероятности выхода:

A:  1/2^1  + 1/2^27 + 1/2^53 + ... = 33554432 / 67108863 ~ 0.50000000745
B:  1/2^2  + 1/2^28 + 1/2^54 + ... = half of chance for A
C:  1/2^3  + 1/2^29 + 1/2^55 + ... = half of chance for B
...
Z:  1/2^26 + 1/2^52 + 1/2^78 + ... = half of chance for Y

7

Python 2, 58 57 байт

from random import*
print chr(int(65+(random()*676)**.5))

Объяснение: это генерирует случайное число с плавающей запятой в интервале [0, 676), берет квадратный корень и затем помещает его в пол. Затем он добавляет 65 (значение ascii «A»), преобразует его в символ и печатает его.

Это дает каждому числу от 0 до 25 определенную вероятность. Чтобы понять почему, подумайте об этом так. Сколько чисел, игнорируя нецелые числа, когда вы берете квадратный корень и пол, даете 0? Только одно число будет (ноль). Это означает, что ноль имеет вероятность 1/676. Сколько чисел даст 1? 3 будут, 1, 2 и 3. Это означает, что у каждого есть вероятность 3/676. Двойка может быть получена с 4, 5, 6, 7 или 8, что дает ей вероятность 5, тройка имеет вероятность 7 и т.д. до 25 (Z).

1 байт сохранен благодаря дырявой монахине!


chr(int(65+randint(676)**.5))
Утренняя монахиня

1
Вы могли бы сделать chr(int(65+random()**.5*26)). То же самое алгебраически, потому что 26 == √676. и теперь порядок действий на вашей стороне
Wheat Wizard

3
@EamonOlive Для другого байта **2*26может быть использовано обратное распределение.
user81655

1
1/random()%26также должен работать.
xnor

1
@xnor, который иногда дает 1/0% 26
трихоплакс

5

PowerShell v2 +, 33 31 байт

[char](65..90|%{,$_*$_}|Random)

Принимает диапазон от 65до 90(то есть, от ASCII Aдо Z), передает его через цикл. На каждой итерации мы используем оператор запятой для создания массива этого элемента, умноженного на это число. Например, это составит 65 65с, 66 66с, 67 67с и т. Д. Этот большой массив передается по трубопроводу, Get-Randomкоторый (равномерно PRNG) выберет один элемент. Поскольку количество элементов каждого элемента различно, у каждого персонажа есть немного отличающийся процентный шанс быть выбранным. Затем мы инкапсулируем это в параны и используем его как char. Это осталось на конвейере и вывод неявный.

(Спасибо @LeakyNun за несколько байтов в гольф еще до того, как они были опубликованы.: D)


Вероятности

(небольшое округление, чтобы я мог продемонстрировать Pопцию -fоператора ormat)

PS C:\Tools\Scripts\golfing> 65..90|%{"$([char]$_): {0:P}"-f($_/2015)}
A: 3.23 %
B: 3.28 %
C: 3.33 %
D: 3.37 %
E: 3.42 %
F: 3.47 %
G: 3.52 %
H: 3.57 %
I: 3.62 %
J: 3.67 %
K: 3.72 %
L: 3.77 %
M: 3.82 %
N: 3.87 %
O: 3.92 %
P: 3.97 %
Q: 4.02 %
R: 4.07 %
S: 4.12 %
T: 4.17 %
U: 4.22 %
V: 4.27 %
W: 4.32 %
X: 4.37 %
Y: 4.42 %
Z: 4.47 %

1
Я начал, не глядя ни на один из ответов; попытался построить на galoutput ( [char[]]"uz$(gal|out-string)"-cmatch'[a-z]'|random) получил 50 символов, затем 48, переключился на цифры и получил 42, затем 31 и остановился там; посмотрел в таблице лидеров, чтобы увидеть, где это меня поставит. Прямо здесь. Символ для персонажа идентичен. Welp, я, вероятно, не могу победить это.
TessellatingHeckler

5

CJam, 21 17 12 байт

Спасибо Мартину Эндеру за то, что он спас мне 5 байтов!

Новая версия

'\,:,s_el-mR

Это формирует массив строк следующий шаблон A, AB, ABCи так далее. Это выравнивает его и выбирает случайный символ. Поскольку эта строка содержит 26 A, 25 B, 24 C и т. Д., Каждая буква имеет определенную вероятность выбора.

Попробуйте онлайн!

объяснение

'\,          e# Push the range of all characters up to 'Z'
   :,        e# For each one, take the range of all characters up to it
     s       e# Convert the array of ranges to one string
      _el-   e# Subtract the lower case version of the string from itself
             e# This leaves only capital letters in the string
          mR e# Take a random character from it

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

26,:)'[,'A,- .*M*mr0=

Получает различные вероятности, создавая строку, в которой каждая буква появляется количество раз, равное ее позиции в алфавите.

26,:)                 e# Push 1, 2, ... 26
     '[,'A,-          e# Push 'A', 'B', ... 'Z'
             .*       e# Vectorize: repeat each letter the corresponding number of times
               M*     e# Join with no separator
                 mr   e# Shuffle the string
                   0= e# Get the first character

5

R, 23 байта

sample(LETTERS,1,,1:26)

Просто «пробует» письмо от встроенного. 1:26вектор весов , дающих каждой буквы другую вероятность.


1
1:26является вектором весов для каждой буквы
user5957401

Это делает это правильным ответом. Стоит отредактировать объяснение, чтобы люди, не знакомые с R, могли понять, как оно работает.
трихоплакс

1
Я собирался, и затем я понял, что парень выше меня сделал то же самое в своем коде и дал подробное объяснение.
user5957401

Хорошо, что вы добавили объяснение - порядок, в котором решения появляются на странице, может меняться в зависимости от количества голосов, поэтому те, которые «выше», могут быть не выше позже.
трихоплакс

5

C 35 байт

Эта программа предполагает, RAND_MAXчто (2 ^ 32/2) - 1, так как она по умолчанию на gcc. Скомпилируйте с -lmфлагом, чтобы связать sqrtфункцию. Вывод записывается в стандартный вывод заглавными буквами без завершающих строк.

f(){putchar(sqrt(rand())/1783+65);}

При желании, если RAND_MAX(2 ^ 16/2) - 1, можно использовать более короткую 32-байтовую версию:

f(){putchar(sqrt(rand())/7+65);}

Просто для забавы, я также сделал версию, в которой не используется эта sqrtфункция и не требуется наличие математической библиотеки (эта должна иметь значение RAND_MAX(2 ^ 32/2) - 1), но она оказалась длиннее, хотя я и думал, что это довольно круто:

f(){float r=rand()/64+1;putchar((*(int*)&r>>23)-62);}

объяснение

[Первая программа]

Для первых двух использований sqrtфункция просто отображает диапазон [0, RAND_MAX)на [0, 25]сквозное деление, а затем добавляет 65 (ASCII A) к значению, чтобы переместить его в алфавит ASCII перед его выводом.

[Вторая программа]

Вторая программа немного сложнее, так как выполняет аналогичную стратегию, но без sqrtоператора. Поскольку биты экспоненты с плавающей запятой автоматически вычисляются при назначении целого числа, они могут эффективно использоваться в качестве грубого способа получения логарифма числа 2 с основанием 2.

Так как мы хотим, чтобы диапазон RAND_MAXтолько достигал закодированного значения показателя степени 25, вычисление (2 ^ 32/2 - 1) / (2 ^ 25) дает нам только около 64, что используется при делении randдля его отображения к этому новому ассортименту. Я также добавил 1 к значению, поскольку представление с плавающей запятой 0 довольно странно и нарушило бы этот алгоритм.

Затем с плавающей точкой вводится тип с целым числом, чтобы разрешить сдвиг битов и другие подобные операции. Поскольку в числах с плавающей запятой IEEE 754 показательные биты являются битами 30-23, число затем сдвигается вправо на 23 бита, обрезая мантиссу и позволяя считать необработанное значение показателя в виде целого числа. Обратите внимание, что знаковый бит также находится за пределами экспонентных битов, но, поскольку никогда не бывает отрицательных значений, его не нужно маскировать.

Вместо добавления 65 к этому результату, как мы делали ранее, показатели с плавающей запятой представляются в виде 8-разрядного целого числа без знака от 0 до 255, где значение показателя 0 равно 127 (просто вычтите 127, чтобы получить фактическое значение показателя со «знаком»). ). Поскольку 127 - 65 - это 62, мы вместо этого просто вычитаем 62, чтобы сдвинуть его из этого диапазона показателей с плавающей запятой и в диапазон алфавита ASCII - все за одну операцию.

распределение

Я не эксперт по математике, поэтому я не могу точно сказать точную формулу для этих распределений, но я могу (и сделал) проверить каждое значение в диапазоне, [0, RAND_MAX)чтобы показать, что расстояние между тем, где заканчивается диапазон одной буквы, и началом другой никогда не будет такой же. (Обратите внимание, что эти тесты предполагают случайный максимум (2 ^ 32/2) - 1)

[Первая программа]

Letter - Starting Location
A - 0
B - 3179089
C - 12716356
D - 28611801
E - 50865424
F - 79477225
G - 114447204
H - 155775361
I - 203461696
J - 257506209
K - 317908900
L - 384669769
M - 457788816
N - 537266041
O - 623101444
P - 715295025
Q - 813846784
R - 918756721
S - 1030024836
T - 1147651129
U - 1271635600
V - 1401978249
W - 1538679076
X - 1681738081
Y - 1831155264
Z - 1986930625

[Вторая программа]

Letter - Starting Location
A - 0
B - 64
C - 192
D - 448
E - 960
F - 1984
G - 4032
H - 8128
I - 16320
J - 32704
K - 65472
L - 131008
M - 262080
N - 524224
O - 1048512
P - 2097088
Q - 4194240
R - 8388544
S - 16777152
T - 33554368
U - 67108800
V - 134217664
W - 268435392
X - 536870848
Y - 1073741760
Z - 2147483520

Разве не проще просто вернуть порядковый номер, чем напечатать его? Поскольку charэто целочисленный тип в C, это должно быть приемлемым.
Mego

@Mego Ну да, если ты сможешь это сделать, я просто новичок в гольфе, поэтому я не слишком знаком с тем, что считается приемлемым результатом.
Лимонная капля

4

Python 2, 72 байта

from random import*
print choice(''.join(i*chr(i)for i in range(65,91)))

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

Вот вероятности для каждой выбранной буквы, в процентах:

A 3.23
B 3.28
C 3.33
D 3.37
E 3.42
F 3.47
G 3.52
H 3.57
I 3.62
J 3.67
K 3.72
L 3.77
M 3.82
N 3.87
O 3.92
P 3.97
Q 4.02
R 4.07
S 4.12
T 4.17
U 4.22
V 4.27
W 4.32
X 4.37
Y 4.42
Z 4.47

Попробуйте это: https://repl.it/Cm0x


4

Желе , 5 байт

ØAxJX

(Равный счет, но другой метод , к существующему решению Jelly от Dennis.)

Вероятность получения каждой буквы - это основанный на 1 индекс в алфавите, разделенный на 351 - 26-е треугольное число:

  • P ( A) = 1/351, P ( B) = 2/351, ..., P ( Z) = 26/351.

Так как 1 + 2 + ... + 26 = 351, P (буква) = 1.

Реализация:

ØAxJX    - no input taken
ØA       - yield the alphabet: 'ABC...Z'
   J     - yield [1,...,len(Left)]: [1,2,3,...26]
  x      - Left times Right: 'abbccc...zzzzzzzzzzzzzzzzzzzzzzzzzz'
    X    - choose random element from Left

Протестируйте его на TryItOnline или получите раздачу в 100 тысяч пробежек (кредит Денниса)


Где ты научился быть таким хорошим в желе? Мне трудно поверить, что желе будет общеизвестно за пределами PPCG.
Эддисон Крамп,

1
@Syxer Я только что посмотрел на вики и ударил - все еще не понимаю всего этого
Джонатан Аллан

1
Ну тогда. Добро пожаловать в PPCG, имейте право голоса.
Аддисон Крамп,

3

q, 38 байт

Не особенно коротко, но ...

.Q.A(reverse 0.9 xexp til 26)binr 1?1f

Дискретная кумулятивная функция распределения - это последовательность

0.9 ^ 26, 0.9 ^ 25, ..., 0.9 ^ 0

И мы просто пример из распределения.


3

JavaScript (ES6), 45 байт

_=>(n=Math.random(),10+n*n*26|0).toString(36)

Достигает неравномерного распределения путем возведения в квадрат случайного значения. Math.random()возвращает плавающий диапазон, [0,1)поэтому результат возведения в квадрат это стремится к 0(или a).

Контрольная работа


42 B,(n=Math.random(),10+26*n+n|0).toString(36)
Эфеллон Данцлер

3

Oracle SQL 11.2, 212 байт

Использование позиции символа в алфавите в качестве вероятности

SELECT c FROM(SELECT dbms_random.value(0,351)v FROM DUAL),(SELECT c,e,LAG(e,1,0)OVER(ORDER BY c)s FROM(SELECT CHR(LEVEL+64)c,SUM(LEVEL)OVER(ORDER BY LEVEL)e FROM DUAL CONNECT BY LEVEL<27))WHERE v BETWEEN s AND e;

Un-golfed

SELECT c FROM
  (SELECT dbms_random.value(0,351)v FROM DUAL), -- random value
  (
    SELECT c,e,LAG(e,1,0)OVER(ORDER BY c)s -- Mapping each character to its interval 
    FROM   (
             -- Each char has it's position in the alphabet as probability
             SELECT CHR(LEVEL+64)c,SUM(LEVEL)OVER(ORDER BY LEVEL)e 
             FROM   DUAL 
             CONNECT BY LEVEL<27
           )  
  )
WHERE v BETWEEN s AND e -- match the random value to an interval

3

TI-Basic, 39 байт

sub("ABCDEFGHIJKLMNOPQRSTUVWXYZ",int(26^rand),1

rand генерирует равномерное значение в (0,1]. Это дает 26 ^ rand разную вероятность равняться целым числам от 1 до 26.

Старая версия, 45 байт

sub("ABCDEFGHIJKLMNOPQRSTUVWXYZAAA",1+int(4abs(invNorm(rand))),1

Ограниченная точность целых чисел TI-Basic ограничивает нормальные распределения генерацией чисел в пределах µ ± 7.02σ (см. randNorm(). Таким образом, мы получаем абсолютное значение случайного числа с µ 0 и σ 1, умноженное на четыре, чтобы увеличить практический диапазон, упомянутый ранее, до µ ± 28.08σ. Затем мы определяем значение и добавляем 1, поскольку sub(он индексируется 1, давая нам диапазон от 1-29 с различными вероятностями каждого.


1
@trichoplax Это была моя ошибка, у меня осталось 30 от старой версии [0,29]. Я исправил это сейчас.
Timtech

Интервал (0,1) предполагается равным [0,1).
kamoroso94

@ kamoroso94 Вы проверили? «Примечание: из-за особенностей алгоритма генерации случайных чисел наименьшее возможное число генерируется немного больше 0. На самом деле наибольшее возможное число - 1», - цитирует tibasicdev.wikidot.com/rand
Timtech

3

PHP, 92 84 байта

for($i=65,$x=0;$i<91;$a.=str_repeat(chr($i++),$x))$x++;echo substr($a,rand(0,$x),1);

Создает строку из всех букв, повторяет количество раз, которое мы делаем в цикле, а затем случайным образом выбирает букву из этой строки. Буквы позже в алфавите имеют более высокую вероятность в результате

Спасибо insertusername здесь за сбривание байтов

вероятности исхода (упорядочены по%)

A => 0,29%
B => 0,62%
C => 0,82%
D => 1,15%
E => 1,50%
F => 1,65%
G => 2,00%
H => 2,27%
I => 2,52%
J => 2,80%
K => 3,13%
L => 3,47%
M => 3,72%
N => 3,93%
O => 4,15%
P => 4,59%
Q => 4,81%
R => 5,17%
S => 5,44%
T => 5,68%
U => 6,06%
V => 6,13%
W => 6,60%
X => 6,95%
Y => 7,17%
Z => 7,38%


1
изменил, чтобы фактически придерживаться правил. Моя ошибка
gabe3886

@insertusernamehere, когда я запускаю это, я получаю неопределенные уведомления о переменных и не
выводим

Ой, простите. Я думаю, что я увлекся и удален, $x=0что, очевидно, необходимо. Вот 84-байтовая версия: for($i=65,$x=0;$i<91;$a.=str_repeat(chr($i++),$x))$x++;echo substr($a,rand(0,$x),1);вам когда-нибудь удавалось получить значение больше, чем Gпри запуске кода? В любом случае, вы всегда можете игнорировать notices при игре в гольф.
insertusername здесь

1
Я сделал, но требуется время, чтобы всплыть. Я проверил около 100
000

strlenИз $a351, но вы только собирание случайного характера из первых $x(26) символов. Вы можете это исправить и сохранить ваши шансы с изменением конечного $xTo 350на +1 байта. Вот 77-байтовая версия, которая решает проблему, но также сближает вероятности:for($i=65;$i<91;$a.=str_repeat(chr($i),$i++));echo substr($a,rand(0,2014),1);
Джо.

3

Befunge, 168 164 байта

Более компактный, чем первый, с немного отличающимися вероятностями: у первого ?есть 1/4 шанса напечатать A при «первой попытке», 2/4 шанса вернуться к тому же ?, и 1/4, чтобы перейти к следующий. Все остальные ?имеют 1/4 шанса напечатать букву под ними, 1/4, чтобы повторить попытку, 1/4 перейти к следующей букве, 1/4 перейти к предыдущей. Опять же, вероятность печати А намного выше, чем печать Z.

??????????????????????????>
""""""""""""""""""""""""""
ABCDEFGHIJKLMNOPQRSTUVWXYZ
""""""""""""""""""""""""""
>>>>>>>>>>>>>>>>>>>>>>>>>>,@
##########################

Befunge, 186 байт

Очевидно, что не выиграет с этим, но я думаю, что это интересный ответ, тем не менее :)

vи >направляет курсор соответственно вниз и вправо. ?Оператор посылает курсор выключен в одном из четырех направлений в случайном порядке. Первый ?«заблокирован» vи >в двух направлениях, поэтому у него есть только два пути: либо распечатать букву А, либо перейти к следующему ?. Таким образом, с ?одной только стороны есть 50% -ый шанс напечатать A.

У следующего ?есть 1/3 шанса напечатать B, 1/3 при движении назад и 1/3 при движении вниз. И т. Д.

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

Некоторая помощь с точной математикой была бы оценена :)

По крайней мере, есть вероятность 1/2 * 1/3 ^ 25, что курсор перемещается полностью вниз к Z с первой попытки, но я не уверен, как шансы перемещения курсора вверх и вниз влияют на каждую букву.

,@ печатает и выходит.

 v
>?"A"v
>?"B"v
>?"C"v
>?"D"v
>?"E"v
>?"F"v
>?"G"v
>?"H"v
>?"I"v
>?"J"v
>?"K"v
>?"L"v
>?"M"v
>?"N"v
>?"O"v
>?"P"v
>?"Q"v
>?"R"v
>?"S"v
>?"T"v
>?"U"v
>?"V"v
>?"W"v
>?"X"v
>?"Y"v
>?"Z">,@


2

зш, 63 байта

for i in {A..Z};for j in {1..$[#i]};s+=$i;echo $s[RANDOM%$#s+1]

это работает путем создания этой строки:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ

ака 65 раз A, 66 раз B, 67 раз C ...

а затем он выбирает случайный символ в нем


Почему ты начал в 65?
gcampbell

1
@gcampbell 65 находится Aв ascii. Вы можете начать с 1, но тогда внутренний цикл становится на {65..$[#i]}1 символ длиннее
izabera


2

Пакет, 116 байт

@set/ar=%random%%%676,s=r/26,r%%=26,s-=(r-s)*(r-s^>^>31)
@set a=ABCDEFGHIJKLMNOPQRSTUVWXYZ
@call echo %%a:~%s%,1%%

Работает, выбирая большую или меньшую (я забыл, какую) из двух случайных величин.


2

Матлаб, 22

Часто будут возвращать ранние буквы, но теоретически могут коснуться их всех!

Делает одно деленное на случайное число, ограничивает его до 26 и превращает его в персонажа.

['' 96+min(1/rand,26)]

Не очень кратко, конечно, но, возможно, концепция может вдохновить другие ответы.


Есть ли randвозвращать значение в [0, 1)? То есть, включая ноль, но не включая один. Если это иногда приводит к 1/0, все min(1/0,26)еще вернется 26, или ошибка?
Трихоплакс,

Насколько я знаю, randвозвращает значение в (0,1), поэтому проблем не должно быть
paul.oderso

1
@trichoplax Даже если вы не увидите rand0 на практике, на min(1/0,26)самом деле возвращается 26.
Деннис Джаэруддин

В таком случае, хорошее решение :)
trichoplax

2

CJam, 10 байтов

CJam подход № 3 ...

26mr)mr'A+

Попробуйте онлайн!

Это создает равномерно случайное число xот 1 до 26, а затем использует его для создания равномерно случайного числа между 0и к x-1которому добавляется A. Это смещение приводит к меньшим символам.


2

Лабиринт , 19 байт

__v6%_65+.@
" )
"^2

Попробуйте онлайн!

Это цикл, который на каждой итерации либо a) увеличивает счетчик, который начинается с нуля, либо b) заканчивается, оба с вероятностью 50%. В конце цикла счетчик берется по модулю 26 и добавляется к 65, чтобы дать букву между Aи Z.

Это дает вероятность Aчуть более 50%, Bчуть более 25% и т. Д. До Zчуть более 1/2 26 . Теоретически, существует вероятность того, что это будет продолжаться вечно, но вероятность этого события равна нулю, как того требует задача (на практике это, вероятно, в любом случае невозможно, поскольку PRNG будет возвращать оба возможных результата в определенный момент в течение своего периода).

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