| Bytes | Lang | Time | Link |
|---|---|---|---|
| 006 | Japt | 170914T190456Z | Shaggy |
| 116 | Go 1.22+ only | 240311T153736Z | bigyihsu |
| 008 | Uiua SBCS | 240311T145142Z | chunes |
| 003 | Vyxal | 240311T020329Z | emanresu |
| 006 | MATL | 170914T171128Z | Luis Men |
| 005 | CJam | 171009T171347Z | lolad |
| 020 | TIBASIC | 170918T153539Z | kamoroso |
| 050 | JavaScript ES6 | 170918T145244Z | kamoroso |
| 008 | J | 170914T172223Z | cole |
| 030 | MATLAB | 170916T192418Z | Tom Carp |
| 004 | Pyth | 170914T171118Z | Mr. Xcod |
| nan | C# .NET Core | 170915T112716Z | Ayb4btu |
| 019 | GNU APL 1.2 | 170915T155055Z | Arc676 |
| 008 | Dyalog APL | 170915T211556Z | Adalynn |
| 083 | Java OpenJDK 8 | 170915T144307Z | Nevay |
| 046 | Clojure | 170915T183350Z | MattPutn |
| 020 | Perl 6 | 170914T174515Z | Ramillie |
| 121 | Java 8 | 170915T083917Z | Kevin Cr |
| 021 | 05AB1E | 170915T144551Z | Magic Oc |
| 064 | Clojure | 170915T123637Z | Joshua |
| 021 | Perl 6 | 170914T214124Z | Sean |
| 051 | Bash | 170914T204859Z | Justin M |
| 077 | Haskell | 170914T192823Z | Laikoni |
| 044 | Python 3.6 | 170914T194332Z | shooqie |
| 054 | Javascript ES6 | 170914T191140Z | Endenite |
| 087 | Haskell | 170914T191614Z | jferard |
| 012 | Charcoal | 170914T191037Z | Neil |
| 032 | Ruby | 170914T181805Z | daniero |
| 017 | GolfScript | 170914T181432Z | Erik the |
| nan | Perl 5 | 170914T181320Z | Xcali |
| 031 | Perl | 170914T180934Z | user7392 |
| 027 | PowerShell | 170914T180708Z | AdmBorkB |
| 009 | CJam | 170914T180303Z | Peter Ta |
| 003 | Jelly | 170914T171431Z | Erik the |
| 009 | 05AB1E | 170914T172241Z | Erik the |
| 025 | R | 170914T171547Z | Giuseppe |
| 019 | Mathematica | 170914T171929Z | ZaMoC |
| 062 | Python 3 | 170914T171555Z | Mr. Xcod |
Japt, 7 6 bytes
cÈÇX
ö
cÈÇX\nö :Implicit input of array U
c :Flat map by
È :Passing each X through the following function
ÇX : Map the range [0,X) to X
\n :Reassign to U
ö :Random element
Go (1.22+ only), 116 bytes
import."math/rand"
func f(s[]int)int{A:=[]int{}
for _,e:=range s{for range e{A=append(A,e)}}
return A[Intn(len(A))]}
Go (all versions), 121 bytes
import."math/rand"
func f(s[]int)int{A:=[]int{}
for _,e:=range s{for i:=0;i<e;i++{A=append(A,e)}}
return A[Intn(len(A))]}
Explanation
import."math/rand"
func f(s[]int)int{
// construct a slice with each element `n` repeated `n` times
A:=[]int{}
for _,e:=range s{for i:=0;i<e;i++{A=append(A,e)}}
// actually select the element
return A[Intn(len(A))]
}
Uiua SBCS, 8 bytes
⊡⌊×⚂⧻.▽.
⊡⌊×⚂⧻.▽.
▽. # repeat each array item <itself> times
⧻. # length
×⚂ # times random unit
⌊ # floor
⊡ # pick
Vyxal, 3 bytes
ẋf℅
℅ # Choose a random element of
ẋ # Each element n in the array repeated n times
f # Flattened
MATL, 8 6 bytes
tY"1Zr
Try it at MATL Online!
Explanation
t % Implicit input. Duplicate
Y" % Run-length decoding
1Zr % Randomly take one value with uniform distribution. Implicitly display
TI-BASIC, 20 bytes
Ans→L₁
SortD(L₁
L₁(1+int(rand²dim(L₁
Input and output are stored in Ans. If you see a box, L₁ is L1. Same algorithm as my JavaScript answer.
JavaScript (ES6), 50 bytes
a=>a.sort((a,b)=>b-a)[Math.random()**2*a.length|0]
Hopefully it's apparent how this works, but I'll explain it here anyway. It sorts the integers in descending order, then chooses one at random with a beta distrubution (1/2,1).
J, 8 7 8 bytes
The 7 byter is invalid; I'll revert this to a previous edit when I get back to my computer in a day or two.
?@+/{#~
:( selecting random elements from an array is costly.
8 bytes
#~{~1?+/
9 bytes
(1?+/){#~
Explanation
?@+/{#~
? Choose random number in range
+/ Sum of the array
{ Select that element from
#~ The elements duplicated as many times as their value
MATLAB, 30 bytes
@(a)datasample(repelem(n,n),1)
This assumes MATLAB R2015a or newer and with the Statistics & Machine Learning toolbox installed.
See the explanation below for how repelem is used. The difference between this shorter one and the one below is that the S&ML toolbox includes the function datasample which can be used to take one or more elements from an array at random (with uniform probability) which allows an anonymous function to be used, stripping away the input/disp calls.
MATLAB, 49 bytes
n=input('');a=repelem(n,n);disp(a(randi(nnz(a))))
This code assumes that MATLAB R2015a or newer is used as that is when the repelem function was introduced. repelem is a function which takes two parameters, the first is an array of numbers to be replicated, and the second is an array of how many times the corresponding element should be replicated. Essentially the function performs run-length decoding by providing the number and the run-length.
By providing the same input to both inputs of repelem we end up with an array which consists of n times more of element n if that makes sense. If you provided [1 2 3] you would get [1 2 2 3 3 3]. If you provided [1 2 4 2] you would get [1 2 2 4 4 4 4 2 2]. By doing this it means that if we select an element with uniform probability (randi(m) gives a random integer from 1 to m with uniform probability), each element n has an n times higher probability of being selected. In the first example of [1 2 3], 1 would have a 1/6 chance, 2 would have a 2/6 chance and 3 would have a 3/6 chance.
As a side note, because repelem is not available yet for Octave, I can't give a TIO link. Additionally because Octave can't be used there is a big character penalty as input() and disp() need to be used as an anonymous function is not possible. If Octave supported repelem, the following could be used:
@(n)a(randi(nnz(a=repelem(n,n))))
That would have saved 16 bytes, but it was not to be.
Pyth, 4 bytes
OsmR
Saved one byte, thanks to @Jakube, with a rather unusual approach.
Pyth, 5 bytes
Osm*]
How?
#1
OsmR - Full program.
R - Right Map...
m - ... Using Map. This essentially creates the list [[4,4,4,4], [1], [5,5,5,5,5]].
- ... Credit goes to Jakube for this!
s - Flatten.
O - Random element of ^. Display implicitly.
#2
Osm*] - Full program.
m - Map over the input.
] - The current element, d, wrapped; [d].
* - Repeated d times.
s - Flatten.
O - Random Element. Implicitly print the result.
C# (.NET Core), 93 89 87 76+18 = 94 bytes
a=>{int i=-1,r=new Random().Next(a.Sum());while(r>=0)r-=a[++i];return a[i];}
An extra 18 bytes for using System.Linq;
Acknowledgements
11 bytes saved thanks to Nevay, whose random number implementation was a lot more concise (as well as being an int instead of a double).
Degolfed
a=>{
int i=-1,
r=new Random().Next(a.Sum());
while(r>=0)
r-=a[++i];
return a[i];
}
Explanation
Get a random number, r, between 0 and sum of elements. Then at each iteration subtract the current element from r. If r is less than 0, then return this element. The idea is that there are bigger portions of the random number for the larger numbers in the array.
GNU APL 1.2, 26 23 bytes; 1.7 21 19 bytes
Approach inspired by Erik the Outgolfer's Jelly answer. Relies on ⎕IO being 0 instead of 1, which is the default for GNU APL (sort of +5 bytes for ⎕IO←0).
-3, -2 bytes thanks to @Zacharý
∇ function form
∇f R
S[?⍴S←∊0 0⍉R∘.⍴R]∇
Anonymous lambda form
{S[?⍴S←∊0 0⍉⍵∘.⍴⍵]}
For the explanation, I will use ⍵ to represent the argument passed to the function, but it is equivalent to R in the ∇ form.
⍵∘.⍴⍵ computes the outer product on the list using the reshape (⍴) operator. Effectively, this creates a table (like a multiplication table) but instead of multiplying, it repeats the element in the column a number of times equal to the element in the row. For the example given in the question, this is:
4 4 4 4 1 1 1 1 5 5 5 5
4 1 5
4 4 4 4 4 1 1 1 1 1 5 5 5 5 5
0 0⍉⍵∘.⍴⍵ transposes the matrix and returns just the main diagonal. This gives us just the parts where the row and column in ⍵∘.⍴⍵ were the same i.e. we repeated the number a number of times equal to its value. For the example, this is:
4 4 4 4 1 5 5 5 5 5
∊ turns its argument into a list. Using the transpose (⍉) operator, we got a vector containing 3 vectors. Enlist (∊) turns it into a single vector containing all the elements.
S←... assigns this new vector to vector S. ⍴S gives us the length of that list. ? is the random operator, so ?⍴S gives us a random number between 0 and the length of the list (exclusive) (this is why it relies on ⎕IO being 0; otherwise it's between 1 and the length, inclusive). S[...] returns the element at the given index.
Dyalog APL, 8 bytes
/⍨⌷⍨1?+/
How?
/⍨,ncopies ofnfor eachnin the argument.⌷⍨, at the index of1?, a random value between1and+/, the sum of the argument
Java (OpenJDK 8), 88 87 86 83 bytes
a->{int r=0,x=-1;for(int i:a)r-=i;for(r*=Math.random();r<1;)r+=a[++x];return a[x];}
Clojure, 46 bytes
(fn[s](rand-nth(flatten(map #(repeat % %)s))))
The usual Clojure pain: simple idea, long-ass (for golfing) function names.
Perl 6, 20 bytes
Saved 1 byte thanks to @Brad Gilbert b2gills.
{bag(@_ Zxx@_).pick}
This takes 1 list argument. We zip 2 copies of this list using the xx operator. So with @_ Zxx@_, we get a list in which element x is presented x times. It is then coerced to Bag, which is a collection that stores objects along with how many times they appear in the collection. Finally, we pick a random element from this collection with pick, which takes the counts into the account and does The Right Thing™.
Java 8, 127 122 121 bytes
import java.util.*;a->{List l=new Stack();for(int i:a)for(int j=i;j-->0;Collections.shuffle(l))l.add(i);return l.get(0);}
-1 byte thanks to @Nevay.
Uses a similar approach as @ErikTheOutgolfer's Jelly answer, by adding n times the item n to the list, and then select one randomly from that list.
Explanation:
import java.util.*; // Required import for List, Stack and Collections
a->{ // Method with integer-array parameter and integer return-type
List l=new Stack(); // Create a List
for(int i:a) // Loop (1) over the input array
for(int j=i;j-->0; // Inner loop (2) from `i` down to 0
Collections.shuffle(l))
// and shuffle the List randomly after every iteration
l.add(i); // Add `i` that many times to List `l`
// End of inner loop (2) (implicit / single-line body)
// End of loop (1) (implicit / single-line body)
return l.get(0); // And then return the first item of the list
} // End of method
05AB1E, 21 bytes
O/ždT6m/svy-D0‹s})1kè
Here's a weird implementation for you, uses microseconds on the system's CPU for the randomized seed.
O/ # [.4,.1,.5] | Push prob distribution.
ždT6m/ # ?????????? | 0 < x < 100000 divided by 100000.
s # [.4,.1,.5] | Swap...
v # For each prob in distribution...
y- # Remove from random number b/w 0 and 1.
D0‹ # Dupe each, find if this number made the random number less than 0.
s}) # Continue loop, swapping current random diff to the front of the stack.
1kè # First instance of the random number going negative is our random return.
Clojure, 64 bytes
(defn a[i](rand-nth(reduce #(concat %(take %2(repeat %2)))[]i)))
Appends each item item number of times to a new list, then takes a random element.
Finally a clojure answer that's not incredibly much longer than other answers :D
Perl 6, 21 bytes
{flat($_ Zxx$_).pick}
$_ Zxx $_ zips the input list with itself using the xx replication operator, turning (for example) (1, 2, 3) into ((1), (2, 2), (3, 3, 3)). flat flattens that into a list of integers, and finally pick picks one at random.
Bash, 51 bytes
for n in $@;{ printf $n\\n%.s `seq $n`;}|shuf|sed q
Takes space-separated or newline-separated input in one argument or multiple arguments.
Validate the random frequencies with a more complicated test case.
Haskell, 78 77 bytes
import System.Random
f l=randomRIO(0,sum l-1)>>=pure.((l>>= \n->n<$[1..n])!!)
Try it online! Usage example: f [1,99] probably yields 99.
Explanation:
ftakes a list of integersland returns the randomly selected integer asIO Int.l>>= \n->n<$[1..n]constructs a list with each elementnrepeatedntimes.randomRIO(0,sum l-1)yields an integer in the range from 0 to the length of the list of repeated elements, which is exactly the sum of all elements, minus one to avoid a out of bound exception.
Bonus: 85 byte point-free version
import System.Random
(>>=).randomRIO.(,)0.pred.sum<*>(pure.).(!!).(>>= \n->n<$[1..n])
Python 3.6, 44 bytes
lambda A:choices(A,A)[0]
from random import*
Yay for built-ins. The other A in choices(A, A) is an optional weights argument.
Javascript (ES6), 61 54 bytes
-7 bytes thanks to @Justin Mariner
a=>a.find(m=>(n-=m)<0,n=Math.random()*eval(a.join`+`))
Example code snippet
f=
a=>a.find(m=>(n-=m)<0,n=Math.random()*eval(a.join`+`))
console.log(f([4,1,5]))
Haskell, 87 bytes
import System.Random
f l|m<-[x<$[1..x]|x<-l]>>=id=randomRIO(0,length m-1)>>=print.(m!!)
Charcoal, 12 bytes
F⪪θ;FIι⊞υι‽υ
Try it online! Link is to verbose version of code. Since Charcoal tries to be too clever, I'm having to use semicolon-delimited input for the array. Explanation:
θ Input variable as string
⪪ ; Split on semicolons
F Loop i over each string
Iι Cast i to integer
F Repeat that many times
⊞υι Push i to (originally empty) list
‽υ Random selection from list
Implicitly print
Perl, 31 bytes
@a=map{($_)x$_}@ARGV;$a[rand@a]
This assumes the input to be command line arguments. Note that it may run out of memory if the numbers are large.
PowerShell, 27 bytes
($args[0]|%{,$_*$_})|Random
Takes input $args[0] as a literal array. Loops through each element |%{...} and each iteration constructs a new array ,$_ of $_ elements -- e.g., for 4 this will create an array @(4,4,4,4). Those array elements are then piped into Get-Random which will pluck out one of the elements with (pseudo) equal probability. Since, e.g., for @(4,1,5) this gives us @(4,4,4,4,1,5,5,5,5,5) this satisfies the probability requirements.
CJam (9 bytes)
q~_]ze~mR
Online demo. This is a full program which takes input in CJam array format on stdin and prints the selected element to stdout.
Dissection
q~ e# Read and parse input
_]z e# Copy and transpose
e~ e# Run-length decode
mR e# Select random element uniformly
Jelly, 3 bytes
x`X
Look 'ma, no Unicode!
Explanation:
x`X
` Make monad from dyad and use same left and right arguments
x Repeat each element of the left argument (implicit) list its respective number of times in the right argument list
X Random element
R, 25 bytes
function(s)sample(s,1,,s)
Explanation:
function(s){
sample(x = s, size = 1, replace = FALSE, prob = s)
}
Takes a sample from s of size 1 without replacement, with weights s; these are rescaled to be probabilities.
To verify the distribution, use this link.
Mathematica, 19 bytes
RandomChoice[#->#]&