Draw a distribution diagram!

Challenge

You are given three integers as input - min_value, max_value, sample_size, that you can pass to your answer as either array or several parameters.

Your task is to output a diagram in any convenient format, that shows the frequency of numbers in the (min_value, max_value) range showing up when a random number in the (min_value, max_value) range is picked sample_size times. The random number sequence should be generated within your answer.

With large ranges and sample sizes, you're free to change the steps your diagram uses, as long as the representation remains accurate.

Example

With [1, 5, 10] as input:

o o o x o
x o x x x
x x x x x
1 2 3 4 5


With [1, 100, 15] as input (in steps of 10, so 00 shows 1-9, 10 shows 10-19, etc.):

xx oo oo xx oo xx oo oo oo oo
xx oo oo xx oo xx xx oo oo oo
xx xx oo xx xx xx xx xx xx oo
00 10 20 30 40 50 60 70 80 90


Scoring

This is , so shortest code in bytes wins.

• I guess we aren't allowed to output tables with a larger height than necessary? For your [1,5,10] example, can the height be 10? So column 4 would look like this (vertically top-to-bottom instead of horizontally left-to-right): oooooooxxx4. Jun 28 '18 at 11:19
• What's to stop me from selecting a bin of width b-a? That's quite a convenient format... Jun 28 '18 at 12:35
• Giuseppe means that for a range a...b, the diagram has a single bin that covers the entire range, resulting in a single bar with height equal to the number of samples. Jun 28 '18 at 15:20
• Are we allowed to draw the histogram horizontally? Also, do the values have to be chosen uniformly in the range, or is any distribution where all outcomes are possible valid?
– user48543
Jun 28 '18 at 15:21
• @Mnemonic about the distribution: The consensus is that it doesn't have to be uniform unless OP has specified it. Jun 28 '18 at 15:24

Octave, 34 32 bytes

@(a,b,n)hist(--a+randi(b-a,n,1))


Doesn't work on TIO, but works on Octave-online.net.

It creates a histogram (bar chart) looking like this:

I'd say that counts as "Any convenient format".

If non-zero bins must be shown, then this can be solved in 38 bytes:

@(a,b,n)hist(--a+randi(b-a,n,1),a+1:b)

• I asked for clarification about zero height bins - this fails to show them if they are strictly less than or strictly greater than all non-zero ones (f(1,5,1) would show the behaviour for example). Jun 28 '18 at 11:31
• I feel obliged to point out that that is most certainly not a histogram, rather it is a bar chart (which aren't the same thing, at all). Jun 28 '18 at 12:51
• @cairdcoinheringaahing skimming through those wiki pages I don't see what this wouldn't be a histogram. Care to explain why you think it's a bar chart instead?
– Imus
Jun 28 '18 at 13:18
• @Imus a histogram is a special kind of bar chart. I reckon the point that caird coinheringaahing wants to make is that it only qualifies as a histogram if the bins are large enough to allow estimating the actual distribution of the random variable (which in this case is actually completely flat). For a sample size of only 10 it's not really possible to create a proper histogram. Jun 28 '18 at 13:23

R, 36 bytes

function(a,b,n)stem(sample(a:b,n,T))


Try it online!

Sigh. A stemplot.

The bane of existence for second year university students taking Introduction to Statistics for [This Specific Area of Study] from some professor who doesn't know what they're talking about but still think stemplots are a good idea because it's still in the 14th edition of the textbook they've been using since the 4th edition was published in 1983.

Charcoal, 25 bytes

≔…·θηθ≔Ｅζ‽θηＥθ№ηι↖←Ｅ⮌θ⮌Ｉι


Try it online! Explanation:

≔…·θηθ


Create an inclusive range of the distribution.

≔Ｅζ‽θη


Sample the range the desired number of times.

Ｅθ№ηι


Count and print the number of each of the range in the sample.

↖←Ｅ⮌θ⮌Ｉι


Print the labels.

Jelly, 13 bytes

Ṫɓr/;"xẊĠ>ʋ¥G


Uses a very convenient format:

• Prints the values on the left axis
• Uses 0 as the distribution pixels (like the xs) and 1 as the background pixels (like the os)
• Uses as many horizontal spaces between "pixels" as there are characters in the maximum length number in the range (e.g. -23 is length 3, while 23 is length 2).

Try it online!

Note: If the input did not have to be an array it would be 11 bytes taking two arguments, [from, to] and sampleSize with just r/;"xẊĠ>ʋ¥G.

I think this may be taking the convenient formatting allowance just a little too far for 4 bytes:

Ṗ;1K

This is using the idea (which should be addressed) put forward by Giuseppe in the comments with a single bin identified with from and to separated by a space, another space representing the axis and and a single 1 representing the height of 100%.

...or even just Ṗ1 for 2 bytes!

Python 2, 115 bytes

from random import*
a,b,n=input()
r=range(a,b+1)
s=sample(r*n,n)
for v in r:print'%%0%dd'%len(b)%v,s.count(v)*'x'


Try it online!

Python 2, 164 bytes

column-based output.

from random import*
a,b,n=input()
r=range(a,b+1)
s=sample(r*n,n)
d=len(b)
while n:n-=1;print' '.join(d*'ox'[s.count(v)>n]for v in r)
for v in r:print'%%0%dd'%d%v,


Try it online!

Java 11, 184 168 bytes

(m,M,s)->{int a[]=new int[M],q=M;for(;s>0;q=M)if((q*=Math.random())>m-2){a[q]++;s--;}for(;m<=M;)System.out.printf("%0"+(M+"").length()+"d%s%n",m,"*".repeat(a[m++-1]));}


Try it online. (NOTE: String.repeat(int) is emulated as repeat(String,int) for the same byte-count, because Java 11 isn't on TIO yet.)

Explanation:

(m,M,s)->{                         // Method with three integer parameters & no return-type
// (m = min_value; M = max_value; s = sample_size)
int a[]=new int[M],              //  Integer-array, filled with M amount of 0s
q=M;                         //  Temp integer for the random value, set to M
for(;s>0;                        //  Loop as long as s isn't 0 yet:
q=M)                         //    Reset q back to M after every iteration
if((q*=Math.random())          //   Pick a random integer in the range [0, M)
>m-2){                      //   If this random integer is larger than m-2:
a[q]++;                      //    Increase the value at that this random index by 1
s--;}                        //    And decrease s by 1
for(;m<=M;)                      //  Loop in the range [m, M]
System.out.printf(             //   Print with trailing new-line
"%0"+(M+"").length()+"d%s%n",//   and leading zeros if necessary:
m,                           //    The number
"*".repeat(a[m++-1]));}      //    appended with "*" repeated the amount of times
//    specified in the random array at index m-1


R, 52 bytes

function(a,b,n)table(cut(sample(a:b,n,T),a:(b+1)-1))


Try it online!

Returns a table of frequencies with names equal to the half-open intervals selected by cut, so (0,1], (1,2], (2,3], and so forth. Makes no effort to select more reasonable binning.

• Wouldn't function(a,b,n)hist(sample(a:b,n,T)) satisfy the requirements of the question?
– ngm
Jun 28 '18 at 13:04
• @ngm I guess...I wanted to do a text output since the challenge seemed to intimate that, but you are more than welcome to post it yourself Jun 28 '18 at 13:05

Ruby, 135 bytes, 117 bytes

d=->(m,n,s){p=(m..n);t=(1..s).map{rand(p)};p.map{|h|g=t.count(h);"#{h}-#{'x'*g}#{'o'*(t.map{|e|t.count(e)}.max-g)}"}}


Ungolfed:

d =-> (m,n,s) {
p = (m..n)
t = (1..s).map{rand(p)}
p.map{ |h|
g = t.count(h)
"#{ h }-#{ 'x' * g }#{ 'o' * (t.map{|e| t.count(e) }.max - g) }"
}
}

puts d.call(1,5,10)

• Try it online! - in case anyone else wanted to test it as I did! Jun 28 '18 at 15:28
• L. Jun 28 '18 at 15:36

Perl 5, 85 bytes

/ \d+/;$d[$+rand$&-$+1]++for 1..$';say$"x(length($&)-length),$_,"-"x$d[$_]for$..$&


Try it online!

Produces similar output to @Neil's Charcoal answer.

JavaScript, 239

I'm sorry about this, but the variables were just named willy-nilly. Anyway, the question said any convenient format, so this function returns a sideways graph

f=>{x=Math;z=Array;q=_=>x.floor(x.random()*(f[1]-f[0]))+f[0];r=z(f[1]-f[0]).fill(0);z(f[2]).fill.forEach(_=>r[q()-1]++);u=${f[1]}.length;return r.map((e,i)=>${${i}.padEnd(u)}${" x".repeat(e)}.padEnd(x.max(...r)*2+u," o")).join\n}


Japt -R, 14 bytes

Takes input in the order max, min, size. Outputs the chart horizontally.

õV
öW
Ë+QpVè¥D


Try it

Explanation

             :Implicit input of integers U=max_value, V=min_value & W=sample_size
õV           :Range [U,V]
\n           :Reassign to U
öW           :Get an array of W random elements from U
\n           :Reassign to V
Ë            :Map each integer D in U
+           :  Append
Q          :  Quotation mark
p         :  Repeat
Vè       :   Count the elements in V
¥D     :    That equal D
:Implicitly join with newlines and output.


Pyth, 19 bytes

JmOK}FPQeQVK,N*/JNd


Try it here

Explanation

JmOK}FPQeQVK,N*/JNd
K}FPQ             Get the inclusive range between the first two inputs as K.
JmO     eQ           Get <last input> random elements as J.
VK         For each value in the range...
,N       ... output a list of the value...
*/JNd  ... and spaces equal to the count in J.
`