4

I was recently given a task to accomplish which i failed. I don't usually ask for logic but today i am compalled to ask.Here is the task.

I am not allowed to use rand() function of php. instead i can use this function.

function getRandom()
{
     return rand(1,5);
}

OK i tried this function but it is bound to return value from 3 to 7.

function getMoreRandom()
{
    $value = getRandom();
    return $value + 2;

}

Now i have to define a php function which can return me random number with the range 1 to 7. How can i do this?

7
  • Is this a homework assignment or something? Can the getRandom function not be altered to just use rand(1, 7) instead? Commented Jan 25, 2013 at 13:16
  • Strange task, but maybe you need something like this: $value = getRandom(); $shouldAdd = getRandom(); if($shouldAdd >= 3) { return $value + 2; } else { return $value; } Commented Jan 25, 2013 at 13:19
  • @FAngel: strange task, indeed. But your solution is strange, too. And it's not uniformly distributed, it will return values between 3 and 5 more often than 1, 2, 6 and 7. Commented Jan 25, 2013 at 13:26
  • 2
    You should probably check this out: stackoverflow.com/questions/137783/… Commented Jan 25, 2013 at 13:31
  • this is not a home work recently i gave an interview and they tested my logic by asking this question Commented Jan 25, 2013 at 13:43

6 Answers 6

5
function getMoreRandom()
{
    do {
        $temp = 5 * (getRandom() - 1) + getRandom();
    } while ($temp > 21);

    return $temp % 7 + 1;
}
Sign up to request clarification or add additional context in comments.

1 Comment

i am accepting this after testing it's what i think is desired. Thanks @flov
4

flov's Answer is correct:

function getMoreRandom()
{
    do {
        $temp = 5 * (getRandom() - 1) + getRandom();
    } while ($temp > 21);

    return $temp % 7 + 1;
}

Testing it with:

$aryResults = array_pad(array(),8,0);
foreach(range(0,100000) as $i) $aryResults[getMoreRandom()]++;
$intSum = array_sum($aryResults);
foreach($aryResults as $intValue => $intCount) printf("Value %d Count %d (%.2f)\n",$intValue,$intCount,$intCount/$intSum);

Produces rectangular distribution

Value 0 Count 0 (0,00)
Value 1 Count 14328 (0,14)
Value 2 Count 14316 (0,14)
Value 3 Count 14185 (0,14)
Value 4 Count 14197 (0,14)
Value 5 Count 14322 (0,14)
Value 6 Count 14361 (0,14)
Value 7 Count 14292 (0,14)

Sorry I did not comment on the answer. Obviously I can't due to my lack of reputation (I'm new here).

Comments

2

It's not going to be a uniform distribution (and you don't specify that it needs to be).

For the most simple solution, you don't need to do scaling or loops, you can take your random 1 to 5, and then add on a random 0 to 2;

function getMoreRandom()
{
    return getRandom() + getRandom() % 3;
}

A quick test to see what the distribution looks like:

$results = array_fill(1, 7, 0);

for ($i = 0; $i < 1000000; $i++) {
    $results[rand(1,5) + rand(1,5) % 3]++;
}

var_dump($results);

As stated, not designed to be uniformly random.

array(7) {
  [1]=>
  int(39550) // 4%
  [2]=>
  int(120277) // 12%
  [3]=>
  int(200098) // 20%
  [4]=>
  int(199700) // 20%
  [5]=>
  int(200195) // 20% 
  [6]=>
  int(160200) // 16%
  [7]=>
  int(79980) // 8%
}

Slightly more complicated, and a different method to @flovs (I don't like the way his loop could last forever - hey, such is randomness)

function getMoreRandom()
{
    for (
        $i = 0, $v = 0;
        $i < 7;
        $i++, $v += getRandom()
    );

    return $v % 7 + 1;
}

This produces a uniform distribution

array(7) {
  [1]=>
  int(14397)
  [2]=>
  int(14218)
  [3]=>
  int(14425)
  [4]=>
  int(14116)
  [5]=>
  int(14387)
  [6]=>
  int(14256)
  [7]=>
  int(14201)
}

Comments

1

My solution:

<?php

function getRandom()
{
     return rand(1,5);
}

$random_number = getRandom();
$random_number += time();

$random_number = ($random_number % 7) + 1;

1 Comment

That works, but it's using an "outside" function which kind of wasn't allowed
0

Just for contributing to a nice question, I think that this could be more generic. That means we maybe do not want 1-7 based on rand(1,5) but 3-7 or 1-10 etc etc.

The function works fine for numbers 1-25, as I am using another solution with 2d array.

function getMoreRand($start, $end){
        $restart = $start; //Save $start value, to restart if we reach the $end number 
        $parser = 0; //Count number elements in 2d array
        $result = 0; //Return the result based on rand(1,5)

        //Create a 2d array(), 5x5 to simulate the 1-5 random number selection from rand(1,5)
        for($row = 0; $row < 5; $row++){
            for($col = 0; $col < 5; $col++){
                $vars[$row][$col] = $start;

                //If the array elements left <= selected range left
                if((25-$parser) <= ($end-$start)){
                    $vars[$row][$col] = 0;
                }else{
                    if($start == $end){
                        $start = $restart;
                    }else{
                        $start++;
                    }
                }       
                $parser++;

            }//END OF FOR COL LOOP
        }//END OF FOR ROW LOOP


        while($result == 0){
            $i = getRandom(); //Choose 1-5
            $j = getRandom(); //Choose 1-5
            $result = $vars[$i-1][$j-1]; //Get number from 2d array, based on rand(1,5)
        }

        echo $result;
    }

Comments

-2
function getMoreRandom()
{
    $value = 0;
    for($i=1;$i<=5;$i++) $value += getRandom();
    return ($value % 7) + 1;
}
  • First, call getRandom 5 times, to get a range of 5 to 25. This has exactly 21 values - a multiple of 7.
  • Then, find the modulus of 7. This produces a numnber between 0 and 6, and each has a 3 in 21, or 1 in 7, chance of appearing.
  • Then, add one for the correct range.

6 Comments

This maps [1, 2, 3, 4, 5] to [1, 2, 4, 5, 7]. You will never get 3 or 6.
This is true, but given that your seed only has five available values, and you can't introduce a new random number, you're left with few other options.
It's stated nowhere that he can't use getRandom() more than once.
Now you get all the numbers, but not distributed uniformly. Think about rolling two dice: it is more likely to roll a 7 than a 2 or a 12
Ok, if two dice won't work, lets try 5 (I know this question is answered, but it bugs me that my answer was wrong).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.