Home » Php » php – Permutations for all possible sets ( 3 digits) including zero

php – Permutations for all possible sets ( 3 digits) including zero

Posted by: admin February 25, 2020 Leave a comment

Questions:

I am creating a small game program in which there are two types of games. Single and Double.
For each game there is a fixed chart set.

Single Chart

        '128',   '129',  '120',  '130',  '140',   '123',  '124',  '125',  '126',  '127',
        '137',   '138',  '139',  '149',  '159',   '150',  '160',  '134',  '135',  '136',
        '146',   '147',  '148',  '158',  '168',   '169',  '179',  '170',  '180',  '145',
        '236',   '156',  '157',  '167',  '230',   '178',  '250',  '189',  '234',  '190',
        '245',   '237',  '238',  '239',  '249',   '240',  '269',  '260',  '270',  '235',
        '290',   '246',  '247',  '248',  '258',   '259',  '278',  '279',  '289',  '280',
        '380',   '345',  '256',  '257',  '267',   '268',  '340',  '350',  '360',  '370',
        '470',   '390',  '346',  '347',  '348',   '358',  '359',  '369',  '379',  '389',
        '489',   '480',  '490',  '356',  '357',   '349',  '368',  '378',  '450',  '460',
        '579',   '570',  '580',  '590',  '456',   '367',  '458',  '459',  '469',  '479',
        '560',   '589',  '670',  '680',  '690',   '457',  '467',  '468',  '478',  '569',
        '678',   '679',  '689',  '789',  '780',   '790',  '890',  '567',  '568',  '578',

Double Chart

        '100',   '110',  '166',  '112',  '113',   '114',  '115',  '116',  '117',  '118',
        '119',   '200',  '229',  '220',  '122',   '277',  '133',  '224',  '144',  '226',
        '155',   '228',  '300',  '266',  '177',   '330',  '188',  '233',  '199',  '244',
        '227',   '255',  '337',  '338',  '339',   '448',  '223',  '288',  '225',  '299',
        '335',   '336',  '355',  '400',  '366',   '466',  '377',  '440',  '388',  '334',
        '344',   '499',  '445',  '446',  '447',   '556',  '449',  '477',  '559',  '488',
        '399',   '660',  '599',  '455',  '500',   '600',  '557',  '558',  '577',  '550',
        '588',   '688',  '779',  '699',  '799',   '880',  '566',  '800',  '667',  '668',
        '669',   '778',  '788',  '770',  '889',   '899',  '700',  '990',  '900',  '677',

When I select a Single and entered number digit 0123456789 (any sequence(sorted & unsorted), min 4 digits & max 10 digits from 0-9, repeated), it returns the entire set which is related to Single Chart.
For this case it returns 120 sets.

If I select double and entered same digit 0123456789 it returns all the set which is related to Double Chart ONLY.

Currently I am using one solutions for Single game which is given here permutations-all-possible-sets-of-numbers but in some set it is returned like 001 but it has to be 100

Also I am not able to find the solutions for Double game.
What I try :

 public function insertSingleGameData($motorGameData)
{

    $chartvalidation    = config('chartValidation');
    $tempMotorSet       = str_split($motorGameData->Playgame->cane);
    $motorSet           = $this->arrayCombination(3, $tempMotorSet); // Get All Sets
    $motorRange         = array_unique($motorSet);
        foreach($motorRange as $cane)
        {

            if(in_array($cane, $chartvalidation['single'])){
                $tempGameData[]     =   ([
                    'playgame_id'   =>  $motorGameData->Playgame->id,
                    'user_id'       =>  $motorGameData->Playgame->user_id,
                    'cane'          =>  $cane,
                    'amount'        =>  $motorGameData->Playgame->amount,
                    'gamemaster_id' =>  $motorGameData->Playgame->gamemaster_id,
                    "created_at"    =>  \Carbon\Carbon::now(),  
                    "updated_at"    =>  \Carbon\Carbon::now(),  
                ]);
            }
        }
        Tempgame::insert($tempGameData);

}

function arrayCombination($le, $set){
    $lk = $this->combination_number($le, count($set));
    $ret = array_fill(0, $lk, array_fill(0, $le, '') );
    $temp = array();
    for ($i = 0 ; $i < $le ; $i++)
        $temp[$i] = $i;
        $ret[0] = $temp;
        for ($i = 1 ; $i < $lk ; $i++){
            if ($temp[$le-1] != count($set)-1){
                $temp[$le-1]++;
            } else {
                $od = -1;
                for ($j = $le-2 ; $j >= 0 ; $j--)
                    if ($temp[$j]+1 != $temp[$j+1]){
                        $od = $j;
                        break;
                    }
                if ($od == -1){
                    break;
                }
                $temp[$od]++;
                for ($j = $od+1 ; $j < $le ; $j++)    {
                    $temp[$j] = $temp[$od]+$j-$od;
                }
            }
            $ret[$i] = $temp;
        }
        for ($i = 0 ; $i < $lk ; $i++) {
            for ($j = 0 ; $j < $le ; $j++){
                $ret[$i][$j] = $set[$ret[$i][$j]];   
            }

        }
    $tempSet = array();
    foreach ($ret as $key => $value) {
        $tempSet[] = implode('',  $value);
    }
    return $tempSet;
    //print("<pre>".print_r($ret,true)."</pre>");
}

 function combination_number($k,$n){
    $n = intval($n);
    $k = intval($k);
    if ($k > $n){
        return 0;
    } elseif ($n == $k) {
        return 1;
    } else {
        if ($k >= $n - $k){
            $l = $k+1;
            for ($i = $l+1 ; $i <= $n ; $i++)
                $l *= $i;
            $m = 1;
            for ($i = 2 ; $i <= $n-$k ; $i++)
                $m *= $i;
        } else {
            $l = ($n-$k) + 1;
            for ($i = $l+1 ; $i <= $n ; $i++)
                $l *= $i;
            $m = 1;
            for ($i = 2 ; $i <= $k ; $i++)
                $m *= $i;            
        }
    }
    return $l/$m;
}

How can I achieve this both Single and Double game in a one function?

How to&Answers:

You can do a preg_match on numbers by creating regular expression such as:

/^[235046]+$/

This means we are trying to match a string which has digits 235046(meaning, 2 or 3 or 5 and so on) right from start (^ caret symbol) till end ($ dollar symbol). If we find a match, we collect them in another array.

Snippet:

<?php

$digits = '235046';

$single_chart_filtered = [];

foreach($single_chart as $chart_value){
    if(preg_match("/^[$digits]+$/",$chart_value) === 1){
        $single_chart_filtered[] = $chart_value;
    }
}

print_r($single_chart_filtered);

$double_chart_filtered = [];

foreach($double_chart as $chart_value){
    if(preg_match("/^[$digits]+$/",$chart_value) === 1){
        $double_chart_filtered[] = $chart_value;
    }
}

Demo: https://3v4l.org/jChvm

Answer:

001 IS a valid combination of 0123456789. You need to filter your array for the possible set:

// simple artificial setup
$single = [111,222,333,444,555];
function generatePossibleSet($input) { return [000,001,010,100,011,101,110,111]; }

$possibleSet = generatePossibleSet("01");

$set = $single;
// just interscet the picked set with the possible set
$set = array_intersect($set, $possibleSet);

This example will give [111] – the only valid combination of 0 and 1 that was in the set-list.