3

I have a long array like the following. What I need to achieve is to check if every 6 elements in this array is found the value 1. If it is not found must be added to one of the 6 elements randomly ( by replacing any of the original values ). Also if the value is found more than 2 times every 6 elements, one of them needs to be replaced with another random number.

I have already created the code that is able to generate the following array randomly. But I do not know how to check if every 6 elements the array contains the value 1, if not how to add it randomly, if found more than 1 time how to replace one of the values with another random number.

I know it s pretty hard to understand. I hope someone will be able to help.

In few words the final result should be:

Every 6 elements this array has to contain at least the value 1 for one time and no more than one time, located every 6 elements in a random position.

This is what I have done so far, this code generates the array below:

/*
We select the elements to add randomly in the final array from a DB table
*/
    $elements = parent::$db->select('_matrix_elements', 'element_id', NULL, 'ORDER BY RAND()');
    $count = count($elements) - 1; //count the total number of the elements -1 to start from zero

    $columns = 6;
    $lines = 8;

    //generating the final array
    for ($a = 1; $a <= $lines; $a++) {
        for ($b = 1; $b <= $columns; $b++) {
            $rand = rand(1,$count);
            $line['position_'.$a.'_' . $b] = $elements[$rand]['element_id'];
        }
    }

Array
(
    [position_1_1] => 14
    [position_1_2] => 6
    [position_1_3] => 5
    [position_1_4] => 6
    [position_1_5] => 9
    [position_1_6] => 8
    [position_2_1] => 11
    [position_2_2] => 7
    [position_2_3] => 6
    [position_2_4] => 1
    [position_2_5] => 7
    [position_2_6] => 5
    [position_3_1] => 14
    [position_3_2] => 5
    [position_3_3] => 4
    [position_3_4] => 7
    [position_3_5] => 4
    [position_3_6] => 10
    [position_4_1] => 6
    [position_4_2] => 2
    [position_4_3] => 2
    [position_4_4] => 1
    [position_4_5] => 7
    [position_4_6] => 6
    [position_5_1] => 3
    [position_5_2] => 7
    [position_5_3] => 8
    [position_5_4] => 10
    [position_5_5] => 3
    [position_5_6] => 2
    [position_6_1] => 8
    [position_6_2] => 2
    [position_6_3] => 10
    [position_6_4] => 2
    [position_6_5] => 10
    [position_6_6] => 9
    [position_7_1] => 6
    [position_7_2] => 10
    [position_7_3] => 4
    [position_7_4] => 8
    [position_7_5] => 1
    [position_7_6] => 5
    [position_8_1] => 2
    [position_8_2] => 7
    [position_8_3] => 4
    [position_8_4] => 7
    [position_8_5] => 9
    [position_8_6] => 13
)
5
  • Have you considered a 2d array? $position[7][4] = 8? Commented Jul 25, 2013 at 20:00
  • @MadaraUchiha I don t understand how it may help Commented Jul 25, 2013 at 20:21
  • Not sure if it might actually help the initial raw problem. But using nested arrays instead of numbered names will solve a lot of problems in the future. Commented Jul 25, 2013 at 20:23
  • @DiegoPucci - your description is a little unclear, but I think I understand. What you're trying to do is set up an array, where each element is itself an element of 6 numbers; it's those sub-arrays you're trying to check. Is that right? Commented Jul 25, 2013 at 20:32
  • @andrewsi no the array is final as it is. I need only to add the value 1 randomly any 6 keys. So from p_1_1 and p_1_6 one value must be 1, the same from p_2_1 to p_2_6 and so on Commented Jul 25, 2013 at 20:45

2 Answers 2

1
  1. Split the list up into a two dimensional array with 6 elements in each 1D array
  2. Count the number of times each element appears in the 6 element sub array
  3. If there are no ones in the array, make a random element 1
  4. If there are 2 or more ones in the array
  5. Replace with a random number (other than one) until there is only one one
  6. Add the final sub array to a 1 dimensional array
  7. Repeat for all the sub arrays in the 2D array
$list_2d = array_chunk($list, 6); 
$final_list = array();
foreach ($list_2d as $array) { 
    $count = array_count_values($array);
    if (!array_key_exists(1, $count))
        $array[mt_rand(0, 5)] = 1;
    else if ($count[1] > 1)
        for ($i = 1; $i <= $count[1] - 1; $i++)
            $array[array_search(1, $array)] = mt_rand(2, 15);
            //Use whatever random number you want here, as long as it's not 1
    $final_list = array_merge($final_list, $array);
}
Sign up to request clarification or add additional context in comments.

Comments

0

Better to get it right straight away, than to make another solution for fixing it. Try this two functions with your code. Also I tested it so check it out here http://phpfiddle.org/lite/code/i9e-gb3. Hope this is what you need.

function randomizer($columns, $rows, $elements)
{
    $line = array();
    for ($row = 1; $row <= $rows; $row++)
    {
        $one_count = array();

        for ($col = 1; $col <= $columns; $col++)
        {
            $line['position_' . $row . '_' . $col] = randomID($elements);

            if ($line['position_' . $row . '_' . $col] == 1)
            {
                //we have 1 - store key value
                $one_count[] = 'position_' . $row . '_' . $col;
            }
        }

        if (empty($one_count))
        {
            //no 1 in last row - we will replace one random
            $rand_col = rand(1, $columns);
            $line['position_' . $row . '_' . $rand_col] = 1;
        }
        elseif (count($one_count) > 1)
        {
            //more than one 1 in last row, we will leave only one

            //first - pick one random to keep
            $keep_key = array_rand($one_count);
            unset($one_count[$keep_key]);

            // second - replace others with non 1 values
            foreach ($one_count as $repl_key)
            {
                //this time we won't take ID=1
                $line[$repl_key] = randomID($elements, true);
            }
        }
    }

    return $line;
}


function randomID($elements, $not1=false)
{
    $count = count($elements) - 1;

    $rand = rand(0, $count);
    $el_id = $elements[$rand]['element_id'];

    if ($not1 === true && $el_id == 1)
    {
        return randomID($elements, true);
    }

    return $el_id;
}

Almost forgot, about this $rand = rand(0, $count); < this is the correct way. You have done $count = count($elements) - 1; and yet started rand from 1 :)

Comments

Your Answer

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