Given a random number generator, (rng), generating numbers in the range 0.0 .. 1.0 called rgen, for example; and a function modifier(x)
taking an number in the same range and generating the probability that the input should be generated, in the same range 0..1; then implement the following algorithm for generating random numbers to the probability given by function modifier:

while True:
    random1 = rgen()
    random2 = rgen()
    if random2 < modifier(random1):
        answer = random1
        break
    endif
endwhile
Task

 Create a modifier function that generates a 'V' shaped probability of number generation using something like, for example:
                      modifier(x)  =  2*(0.5 - x)  if x < 0.5  else 2*(x - 0.5) 

 Create a generator of random numbers with probabilities modified by the above function.
 Generate >= 10,000 random numbers subject to the probability modification.
 Output a textual histogram with from 11 to 21 bins showing the distribution of the random numbers generated.


Show your output here, on this page.




import "random" for Random
import "/fmt" for Fmt
 
var rgen = Random.new()
 
var rng = Fn.new { |modifier|
    while (true) {
        var r1 = rgen.float()
        var r2 = rgen.float()
        if (r2 < modifier.call(r1)) {
            return r1
        }
    }
}
 
var modifier = Fn.new { |x| (x < 0.5) ? 2 * (0.5 - x) : 2 * (x - 0.5) }
 
var N = 100000
var NUM_BINS = 20
var HIST_CHAR = "■"
var HIST_CHAR_SIZE = 125
var bins = List.filled(NUM_BINS, 0)
var binSize = 1 / NUM_BINS
for (i in 0...N) {
    var rn = rng.call(modifier)
    var bn = (rn / binSize).floor
    bins[bn] = bins[bn] + 1
}
 
Fmt.print("Modified random distribution with $,d samples in range [0, 1):\n", N)
System.print("    Range           Number of samples within that range")
for (i in 0...NUM_BINS) {
    var hist = HIST_CHAR * (bins[i] / HIST_CHAR_SIZE).round
    Fmt.print("$4.2f ..< $4.2f  $s $,d", binSize * i, binSize * (i + 1), hist, bins[i])
}