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, strformat, strutils, sugar
 
type ValRange = range[0.0..1.0]
 
func modifier(x: ValRange): ValRange =
  if x < 0.5: 2 * (0.5 - x) else: 2 * (x - 0.5)
 
proc rand(modifier: (float) -> float): ValRange =
  while true:
    let r1 = rand(1.0)
    let r2 = rand(1.0)
    if r2 < modifier(r1):
      return r1
 
const
  N = 100_000
  NumBins = 20
  HistChar = "■"
  HistCharSize = 125
  BinSize = 1 / NumBins
 
randomize()
 
var bins: array[NumBins, int]
for i in 0..<N:
  let rn = rand(modifier)
  let bn = int(rn / BinSize)
  inc bins[bn]
 
echo &"Modified random distribution with {N} samples in range [0, 1):"
echo "    Range           Number of samples within that range"
for i in 0..<NumBins:
  let hist = repeat(HistChar, (bins[i] / HistCharSize).toInt)
  echo &"{BinSize * float(i):4.2f} ..< {BinSize * float(i + 1):4.2f}  {hist} {bins[i]}"