Эта задача довольно проста:
вам дан массив положительных (не включая 0) целых чисел, и вам нужно выбрать случайный элемент из этого массива.
Но вот поворот:
вероятность выбора элемента зависит от значения целого числа, то есть, когда целое число становится больше, вероятность того, что его выберут, тоже увеличивается!
пример
Вам дан массив [4, 1, 5]
.
Вероятность выбора 4 равно 4 , деленной на сумму всех элементов в массиве , в данном случае 4 / ( 4 + 1 + 5 ) = 4 / 10 =
40%
.
Вероятность выбора 1 равна 1 / 10
или 10%
.
вход
Массив натуральных чисел.
Выход
Вернуть выбранное целое число, если используется метод, или напрямую напечатать его stdout
.
правила
- Это код-гольф, поэтому выигрывает самый короткий код в байтах на любом языке.
- Стандартные лазейки запрещены.
R , 25 байт
Попробуйте онлайн!
Объяснение:
Взятие образца от
s
размера1
без замены, с весамиs
; они пересчитаны, чтобы быть вероятностями.Чтобы проверить распространение, используйте эту ссылку .
источник
Pyth , 4 байта
Попробуй это здесь.
Благодаря @Jakube сохранил один байт с довольно необычным подходом.
Pyth , 5 байт
Попробуй это здесь!
Как?
# 1
# 2
источник
OsmL
илиOsmR
d
, затем картыd
в диапазоне ... гений!CJam (9 байт)
Демо онлайн . Это полная программа, которая принимает входные данные в формате массива CJam на стандартный ввод и печатает выбранный элемент на стандартный вывод.
рассечение
источник
Perl 6 , 20 байт
Сохранено 1 байт благодаря @Brad Gilbert b2gills.
Попробуйте онлайн!
Это занимает 1 аргумент списка. Мы заархивировали 2 копии этого списка, используя
xx
оператора. Таким образом@_ Zxx@_
, мы получаем список, в котором элементx
представленx
раз. Затем выполняется преобразование вBag
коллекцию, в которой хранятся объекты и сколько раз они появляются в коллекции. Наконец, мы выбираем случайный элемент из этой коллекцииpick
, который учитывает счет и делает The Right Thing ™.источник
{bag(@_ Z=>@_).pick}
{bag(@_ Zxx@_).pick}
Python 3.6 , 44 байта
Yay для встроенных модулей. Другие
A
вchoices(A, A)
этом необязательныйweights
аргумент.Попробуйте онлайн!
источник
MATL ,
86 байтПопробуйте это в MATL Online!
объяснение
источник
Mathematica, 19 байт
источник
Рубин , 32 байта
Попробуйте онлайн!
источник
Python 3 , 62 байта
Попробуйте онлайн!
источник
Java (OpenJDK 8) ,
88878683 байтаПопробуйте онлайн!
источник
for(r*=Math.random();;)
это нужно, или все, что тебе нужноr*=Math.random()
.for(;;)
цикла это потребовало бы второго (никогда не достигнутого) оператора возврата после,for(int i:a)...
чтобы удовлетворить компилятор - который был бы на 3 байта длиннее.for(int i:a)
какforeach
в C #. У меня была та же самая проблема, но я просто использовал тот,for
который постоянно зацикливается. Ваш новый ответ меня заинтриговал, я мог бы попытаться украсть некоторые ваши идеи.J,
878 байт7 байт недействителен; Я вернусь к предыдущему редактированию, когда вернусь к своему компьютеру через день или два.
Попробуйте онлайн!
:( выбор случайных элементов из массива стоит дорого.
8 байт
9 байт
объяснение
источник
?@+/
есть(?@+)/
; Боюсь, вам придется снова увеличить его до 8 ...JavaScript (ES6), 50 байт
Надеюсь, очевидно, как это работает, но я все равно объясню здесь. Он сортирует целые числа в порядке убывания, а затем выбирает случайное число с бета-распределением (1 / 2,1) .
источник
a=[4,1,5]
, вы получите около 18%1
, 24%4
и 58%5
, что говорит о том, что вы получите это распределение при любом входе длины 3.05AB1E , 9 байтов
Попробуйте онлайн!
источник
PowerShell , 27 байт
Попробуйте онлайн!
Принимает ввод
$args[0]
как буквенный массив. Перебирает каждый элемент|%{...}
и каждую итерацию формирует новый массив,$_
из$_
элементов - например, для4
этого будет создан массив@(4,4,4,4)
. Затем эти элементы массива передаются по трубопроводу, в результатеGet-Random
чего один из элементов вынимает (псевдо) равную вероятность. Так как, например,@(4,1,5)
это дает нам@(4,4,4,4,1,5,5,5,5,5)
это удовлетворяет требованиям вероятности.источник
C # (.NET Core) ,
93898776 + 18 = 94 байтаПопробуйте онлайн!
Дополнительные 18 байт для
using System.Linq;
Подтверждения
11 байтов сохранено благодаря Nevay, чья реализация случайных чисел была намного более краткой (а также
int
вместо adouble
).Degolfed
объяснение
Получить случайное число,
r
между 0 и суммой элементов. Затем на каждой итерации вычитайте текущий элемент изr
. Еслиr
меньше чем0
, то вернуть этот элемент. Идея состоит в том, что в массиве есть большие части случайного числа для больших чисел.источник
a=>{int i=-1,r=new Random().Next(a.Sum());for(;r>=0;)r-=a[++i];return a[i];}
Japt , 7 байт
Проверьте это здесь
объяснение
Неявный ввод массива
U
.Отобразить массив, передавая каждый элемент через функцию, где
D
находится текущий элемент.Создайте массив длины
D
и заполните егоD
.Свести.
Получить случайный элемент.
источник
CJam , 5 байтов
Попробуйте онлайн! Примечание: отдельные числа через пробел
источник
Perl, 31 байт
Это предполагает, что входные данные являются аргументами командной строки. Обратите внимание, что это может не хватить памяти, если числа большие.
источник
Perl 5 , 31 + 1 (-a) = 32 байта
Попробуйте онлайн!
источник
GolfScript , 17 байт
Попробуйте онлайн!
источник
Древесный уголь , 12 байт
Попробуйте онлайн! Ссылка на подробную версию кода. Так как Charcoal пытается быть слишком умным, я должен использовать разделенный точкой с запятой ввод для массива. Объяснение:
источник
Haskell , 87 байт
Попробуйте онлайн!
источник
Javascript (ES6),
6154 байта-7 байт благодаря @Justin Mariner
Пример кода
источник
eval(a.join`+`)
вместоreduce
.[].find(m=>(n-=m)<0,n=Math.random()*eval(a.join
+))
и звонить сinput::[].find(...)
Haskell ,
7877 байтовПопробуйте онлайн! Пример использования:
f [1,99]
вероятно, дает99
.Объяснение:
f
принимает список целых чиселl
и возвращает произвольно выбранное целое число какIO Int
.l>>= \n->n<$[1..n]
создает список с каждым элементомn
повторяетсяn
раз.randomRIO(0,sum l-1)
возвращает целое число в диапазоне от 0 до длины списка повторяющихся элементов, которое является в точности суммой всех элементов, за вычетом единицы, чтобы исключить исключение вне границы.Бонус: 85-байтовая бессмысленная версия
Попробуйте онлайн!
источник
Баш , 51 байт
Принимает разделенный пробелами или символом новой строки ввод в один аргумент или несколько аргументов.
Попробуйте онлайн!
Проверьте случайные частоты с помощью более сложного контрольного примера.
источник
Java 8,
127122121 байт-1 байт благодаря @Nevay .
Использует тот же подход, что и @ErikTheOutgolfer 's Jelly answer , добавляя
n
элемент разn
в список, а затем выбирая один случайным образом из этого списка.Объяснение:
Попробуй это здесь.
источник
#shuffle
вызов в цикл for, чтобы сохранить 1 байтfor(int j=i;j-->0;Collections.shuffle(l))l.add(i);
.Dyalog APL , 8 байт
Попробуйте онлайн!
Как?
/⍨
,n
Копииn
для каждогоn
в аргументе.⌷⍨
по индексу1?
, случайное значение между1
и+/
сумма аргументаисточник
GNU APL 1.2,
2623 байта; 1,72119 байтПодход, вдохновленный ответом желе Эрика Аутгольфера . Полагается,
⎕IO
что 0 вместо 1, что является значением по умолчанию для GNU APL (вроде +5 байт⎕IO←0
).-3, -2 байта благодаря @ Zacharý
∇
функциональная формаАнонимная лямбда-форма
Для объяснения я буду использовать
⍵
для представления аргумента, переданного функции, но он эквивалентенR
в∇
форме.⍵∘.⍴⍵
вычисляет внешний продукт в списке с помощью⍴
оператора reshape ( ). По сути, это создает таблицу (например, таблицу умножения), но вместо умножения повторяет элемент в столбце количество раз, равное элементу в строке. Для примера, приведенного в вопросе, это:0 0⍉⍵∘.⍴⍵
транспонирует матрицу и возвращает только основную диагональ. Это дает нам только те части, где строка и столбец⍵∘.⍴⍵
были одинаковыми, то есть мы повторяли число несколько раз, равное его значению. Для примера это:∊
превращает свой аргумент в список. Используя⍉
оператор transpose ( ), мы получили вектор, содержащий 3 вектора. Enlist (∊
) превращает его в один вектор, содержащий все элементы.S←...
назначает этот новый вектор на векторS
.⍴S
дает нам длину этого списка.?
является случайным оператором, поэтому?⍴S
дает нам случайное число между 0 и длиной списка (исключая) (вот почему он полагается⎕IO
равным 0; в противном случае он находится между 1 и длиной, включительно).S[...]
возвращает элемент по указанному индексу.источник
Q
, так как вы никогда не используете его. И IIRC вы можете удалить символ новой строки перед del (маленький треугольник, отмечающий конец функции.)<IO> <IO>⍉
чтобы главная диагональ была даже вещь!MATLAB, 30 байтов
Это предполагает наличие MATLAB R2015a или более новой версии с установленным набором инструментов «Статистика и машинное обучение».
Смотрите объяснение ниже, как
repelem
это используется. Разница между этим более коротким и приведенным ниже состоит в том, что набор инструментов S & ML включает в себя функцию,datasample
которая может использоваться для случайного выбора одного или нескольких элементов из массива (с одинаковой вероятностью), что позволяет использовать анонимную функцию, удаляяinput/disp
звонки.MATLAB, 49 байтов
В этом коде предполагается, что используется MATLAB R2015a или новее, как тогда, когда
repelem
была введена функция.repelem
это функция, которая принимает два параметра, первый - это массив чисел, подлежащих репликации, а второй - массив того, сколько раз должен быть реплицирован соответствующий элемент. По сути, функция выполняет декодирование длин серий, предоставляя номер и длину серий.Предоставляя одинаковые входные данные обоим входам,
repelem
мы получаем массив, который состоит из n раз больше элемента n, если это имеет смысл. Если бы вы предоставили,[1 2 3]
вы получите[1 2 2 3 3 3]
. Если бы вы предоставили,[1 2 4 2]
вы получите[1 2 2 4 4 4 4 2 2]
. Это означает, что если мы выберем элемент с равномерной вероятностью (randi(m)
дает случайное целое число от 1 до m с равномерной вероятностью), то каждый элемент n имеет вероятность выбора в n раз выше. В первом примере[1 2 3]
,1
будет иметь 1/6 шанс,2
будет иметь 2/6 шанс , и3
будет иметь 3/6 шанс.В качестве примечания, поскольку
repelem
для Octave пока нет, я не могу дать ссылку на TIO. Кроме того , поскольку Октав не может быть использован там большой штраф характер , какinput()
иdisp()
нужно использовать в качестве анонимной функции не представляется возможным. Если Octave поддерживаетсяrepelem
, можно использовать следующее:Это позволило бы сэкономить 16 байтов, но этого не произошло.
источник