0

I can create unique combinations with an array, but I can't set some fields as default.

I've tried to change all permute and combinate functions. First of all i did echo if col2 equals "e" letter. But it is not the correct method.

function FindWord( $word = '', $in = [] ) {
    return array_filter($in, function($s) use($word) { return $s==$word; });
}

function CreateLines2($Keywords=[], $Format=[], $Exclude=[], $Col=0, $nth=0){
    $Row = $Format;
    $RowOK=true;

    foreach($Row AS $key=>$val){
        if ($Col==$key){
            $SearchIn=array_diff($Keywords,$Exclude);
            if (!count($SearchIn) || !($Next=FindWord( '*', $SearchIn )[0]??false)){
                $RowOK = false;
                $nth = 0;
                $Col ++;
                //vd($Col.'-'.$nth,0);
                //break;
            } else {
                $Exclude[]=$Row[$key]=$Next;

            }

        } else {
            if (strpos( $val, '*' ) !== false){
                $Row[$key]=FindWord( $val, array_diff($Keywords,$Exclude) )[0];
            } else {
                $Row[$key]=$val;
            }
            $Exclude[]=$Row[$key];
        }

    }
    if ($RowOK){
        $result = implode( ",", $Row ) . "\n";
        echo $Col . "/" . $nth . " - " . $result . "<br>";
        //file_put_contents( resultFile, $result, FILE_APPEND );
        ob_flush();
        flush();
    }

    CreateLines2( $Keywords, $Row, $Exclude, $Col, $nth + 1 );
}

CreateLines2( [ 'a', 'b', 'c', 'd', 'e', 'f', 'g' ], [ '*', 'e', '*', 'g' ] );

Start of result is true, but when it will pass to second col, I'm getting same result.

a,e,b,g
c,e,b,g
d,e,b,g
f,e,b,g
f,e,b,g
f,e,b,g
f,e,b,g
f,e,b,g
f,e,b,g
f,e,b,g
f,e,b,g
f,e,b,g 

For example, I have 4 cols. 2nd col must be default "e" and 4th default value is "g". Others must be change with first array. But all rows must be unique.

I need this result:

CreateLines2( [ 'a', 'b', 'c', 'd', 'e'], [ '*', 'e', '*', ] );

a,e,b
c,e,b
d,e,b
b,e,a
c,e,a
d,e,a
a,e,c
b,e,c
d,e,c
a,e,d
b,e,d
c,e,d

I've tried How to generate in PHP all combinations of items in multiple arrays

  • I have more values in first array. But result combinations array must be specific count.
  • I can't keep results in RAM. Because my combinations will be million data. So I'm appending every line to file.

Edit #2

    function CreateLines3($Keywords=[], $Defaults=[], $Format=[], $Exclude=[], $Col=0, $nth=0){
        if (!count($Format)) {
            $Format = $Defaults;
            $Exclude = array_filter($Defaults, function($s){return strpos($s,'*')===false;});
        }

        $RowOK=true;

        foreach($Format AS $key=>$val){
            if ($Col==$key){
                if (strpos($Defaults[$key],'*')===false){
                    $RowOK = false;
                    $Exclude[]=$Format[$key];
                } else {
                    $SearchIn=array_diff($Keywords,$Exclude);
                    if (!count($SearchIn) || !($Next=FindWord( '*', $SearchIn )[0]??false)){
                        $RowOK = false;
                    } else {
                        $Exclude[]=$Format[$key]=$Next;
                    }
                }
            }
            else {
                if (strpos( $val, '*' ) !== false){
                    $Format[$key]=FindWord( $val, array_diff($Keywords,$Exclude) )[0];
                } else {
                    $Format[$key]=$val;
                }
                $Exclude[]=$Format[$key];
            }


        }
        if ($RowOK){
            $result = implode( ",", $Format ) . "\n";
            echo $Col . "/" . $nth . " - " . $result . "<br>";
            $nth++;
            ob_flush();
            flush();
        } else {
            $Col ++;
            if ($Col>=count($Format)){
                return false;
            }
            $Exclude=[];
            $nth = 0;
        }

        CreateLines3( $Keywords, $Defaults, $Format, $Exclude, $Col, $nth );
    }

    //CreateLines3( [ 'a', 'b', 'c', 'd', 'e'], [ '*', 'e', '*', ] );
    CreateLines3( [ 'a', 'b', 'c', 'd', 'e', 'f', 'g' ], [ '*', 'a', 'g', '*' ] );

New missing result: 0/0 - b,a,g,c 0/1 - d,a,g,c 0/2 - e,a,g,c 0/3 - f,a,g,c 3/0 - f,a,g,b 3/1 - f,a,g,c 3/2 - f,a,g,d 3/3 - f,a,g,e

Finally resolved but I have a memory problem.

I updated the function with start pick() in Permutations/combinations on PHP

function CPerm($words, $num, $picked = [], $Format=[]) {
    for ($i = 0; $i < count($words); $i += 1) {
        $word = $words[$i];
        $remaining_words = array_diff($words, [$word]);
        if ($num > 1) {
            // pick the remaning $num-1 words
            CPerm(array_values($remaining_words), $num - 1, array_merge($picked, [$word]), $Format);
        } else {
            $result = array_merge($picked, [$word]);

            $Save=true;
            foreach($result AS $key=>$val){
                if (strpos($Format[$key],'*')!==false){
                    if (!preg_match( "/" . str_replace( "*", "(.*?)", $Format[$key] ) . "/i",  $result[$key] ) ) {
                        $Save=false;
                    }
                } else {
                    if ($result[$key]!=$Format[$key]){
                        $Save=false;
                    }
                }
            }

            if ($Save) {
                $keywords = implode(",", $result) . "\n";
                echo $i." -" .$keywords."<br>";
                file_put_contents( resultFile, $keywords, FILE_APPEND );
            }
        }
    }
}

CPerm(range('a', 'g'), 4, [], [ '*', 'a', 'e', '*' ]);

Successful result: 0 -b,a,e,c 1 -b,a,e,d 2 -b,a,e,f 3 -b,a,e,g 0 -c,a,e,b 1 -c,a,e,d 2 -c,a,e,f 3 -c,a,e,g 0 -d,a,e,b 1 -d,a,e,c 2 -d,a,e,f 3 -d,a,e,g 0 -f,a,e,b 1 -f,a,e,c 2 -f,a,e,d 3 -f,a,e,g 0 -g,a,e,b 1 -g,a,e,c 2 -g,a,e,d 3 -g,a,e,f

If I increase array 1 combinations, starting memory problem.

CPerm(range('a', 'z'), 6, [], [ '*', 'a', 'e', '*' , '*' , '*' ]);
Alper AKPINAR
  • 71
  • 3
  • 10
  • Possible duplicate of [How to generate in PHP all combinations of items in multiple arrays](https://stackoverflow.com/questions/8567082/how-to-generate-in-php-all-combinations-of-items-in-multiple-arrays) – Andreas May 29 '19 at 16:26
  • Not. Because I have more values in first array. But result combinations array must be specific count. – Alper AKPINAR May 29 '19 at 16:56
  • Also i can't keep results in RAM. Because my combinations will be million data. – Alper AKPINAR May 29 '19 at 17:00

1 Answers1

0

Last permute class:

    class Permute{
        private $UsableKeywords,$FoundAlready,$colSize;
        private $base = [];
        protected $Unique=true;

        public function __construct($UsableKeywords=[], $FoundAlready=[], $options=[]){
            $this->Unique=$options['Unique']??false;
            $this->colSize=$options['colSize']??3;

            $this->UsableKeywords=$UsableKeywords;
            $this->FoundAlready=$FoundAlready;

            for ($i=0; $i<$this->colSize; $i++)
                $this->base[$i] = 0;

            for ($col=count($this->base)-1;$col>=0;$col--){
                while($this->getKeys($this->base,$col));

                $Say=1;
                $this->base[$col-$Say]++;

                while ($this->base[$col-$Say]==count($this->UsableKeywords)){
                    $this->base[$col-$Say]=0;
                    $Say++;
                    if (!isset($this->base[$col-$Say])) {
                        die('end');
                    }
                    $this->base[$col-$Say]++;
                }

                for($lastCols=$col; $lastCols>=$col; $lastCols--){
                    $this->base[$lastCols]=0;
                }

                $col=count($this->base);
            }

        }

        public function FindWord( $word = '', $in = [] ) {
            $results = [];

            $word = str_replace( "*", "(.*?)", $word );
            foreach ( $in AS $val ) {
                if (preg_match( "/" . trim( $word ) . "/i", trim( $val ) ) ) {
                    $results[] = $val;
                }
            }

            return $results;
        }


        public function getKeys(&$base,$col){
            $theLast = false;
            $result = [];

            for($j=0;$j<count($base);$j++) {
                if (isset($this->FoundAlready[$j])){
                    if ($Keyword = $this->FindWord( $this->FoundAlready[ $j ], [ $this->UsableKeywords[ $base[ $j ] ] ] )){
                        $result[] = $Keyword[0];
                    }

                } else {
                    $result[] = $this->UsableKeywords[$base[$j]];
                }

                if ($col==$j) $base[$j]++;

                if (count($this->UsableKeywords)==$base[ $j ]) $theLast=true;
            }

            if (count($result)==$this->colSize){
                if ($this->Unique && count(array_unique($result))!=$this->colSize ? false : true){
                    $keywords=implode(",",$result)."\n";
                    //file_put_contents( resultFile, $keywords, FILE_APPEND );
                    echo $keywords."<br/>";
                    //ob_flush();
                    //flush();
                }
            }

            return $theLast ? false : true;
        }
    }

    $vars = [
        'aa',
        'bac',
        'cab',
        'ddd',
        'eef',
        'ggg',
        '001',
        '311',
        '544',
    ];
    $FoundAlready=[
        '*',
        'bac',
        '*a*',
        '*',
        '*g*',
    ];

    new Permute(
        $vars,
        $FoundAlready,
        [
            'Unique' => true,
            'colSize' => 6,
        ]
    );

The result will be:

aa,bac,cab,ddd,ggg,eef
aa,bac,cab,ddd,ggg,001
aa,bac,cab,ddd,ggg,311
aa,bac,cab,ddd,ggg,544
aa,bac,cab,eef,ggg,ddd
aa,bac,cab,eef,ggg,001
aa,bac,cab,eef,ggg,311
aa,bac,cab,eef,ggg,544
aa,bac,cab,001,ggg,ddd
aa,bac,cab,001,ggg,eef
aa,bac,cab,001,ggg,311
aa,bac,cab,001,ggg,544
aa,bac,cab,311,ggg,ddd
aa,bac,cab,311,ggg,eef
aa,bac,cab,311,ggg,001
aa,bac,cab,311,ggg,544
aa,bac,cab,544,ggg,ddd
aa,bac,cab,544,ggg,eef
aa,bac,cab,544,ggg,001
aa,bac,cab,544,ggg,311
cab,bac,aa,ddd,ggg,eef
cab,bac,aa,ddd,ggg,001
cab,bac,aa,ddd,ggg,311
cab,bac,aa,ddd,ggg,544
cab,bac,aa,eef,ggg,ddd
cab,bac,aa,eef,ggg,001
cab,bac,aa,eef,ggg,311
cab,bac,aa,eef,ggg,544
cab,bac,aa,001,ggg,ddd
cab,bac,aa,001,ggg,eef
cab,bac,aa,001,ggg,311
cab,bac,aa,001,ggg,544
cab,bac,aa,311,ggg,ddd
cab,bac,aa,311,ggg,eef
cab,bac,aa,311,ggg,001
cab,bac,aa,311,ggg,544
cab,bac,aa,544,ggg,ddd
cab,bac,aa,544,ggg,eef
cab,bac,aa,544,ggg,001
cab,bac,aa,544,ggg,311
ddd,bac,aa,cab,ggg,eef
ddd,bac,aa,cab,ggg,001
ddd,bac,aa,cab,ggg,311
ddd,bac,aa,cab,ggg,544
ddd,bac,aa,eef,ggg,cab
ddd,bac,aa,eef,ggg,001
ddd,bac,aa,eef,ggg,311
ddd,bac,aa,eef,ggg,544
ddd,bac,aa,001,ggg,cab
ddd,bac,aa,001,ggg,eef
ddd,bac,aa,001,ggg,311
ddd,bac,aa,001,ggg,544
ddd,bac,aa,311,ggg,cab
ddd,bac,aa,311,ggg,eef
ddd,bac,aa,311,ggg,001
ddd,bac,aa,311,ggg,544
ddd,bac,aa,544,ggg,cab
ddd,bac,aa,544,ggg,eef
ddd,bac,aa,544,ggg,001
ddd,bac,aa,544,ggg,311
ddd,bac,cab,aa,ggg,eef
ddd,bac,cab,aa,ggg,001
ddd,bac,cab,aa,ggg,311
ddd,bac,cab,aa,ggg,544
ddd,bac,cab,eef,ggg,aa
ddd,bac,cab,eef,ggg,001
ddd,bac,cab,eef,ggg,311
ddd,bac,cab,eef,ggg,544
ddd,bac,cab,001,ggg,aa
ddd,bac,cab,001,ggg,eef
ddd,bac,cab,001,ggg,311
ddd,bac,cab,001,ggg,544
ddd,bac,cab,311,ggg,aa
ddd,bac,cab,311,ggg,eef
ddd,bac,cab,311,ggg,001
ddd,bac,cab,311,ggg,544
ddd,bac,cab,544,ggg,aa
ddd,bac,cab,544,ggg,eef
ddd,bac,cab,544,ggg,001
ddd,bac,cab,544,ggg,311
eef,bac,aa,cab,ggg,ddd
eef,bac,aa,cab,ggg,001
eef,bac,aa,cab,ggg,311
eef,bac,aa,cab,ggg,544
eef,bac,aa,ddd,ggg,cab
eef,bac,aa,ddd,ggg,001
eef,bac,aa,ddd,ggg,311
eef,bac,aa,ddd,ggg,544
eef,bac,aa,001,ggg,cab
eef,bac,aa,001,ggg,ddd
eef,bac,aa,001,ggg,311
eef,bac,aa,001,ggg,544
eef,bac,aa,311,ggg,cab
eef,bac,aa,311,ggg,ddd
eef,bac,aa,311,ggg,001
eef,bac,aa,311,ggg,544
eef,bac,aa,544,ggg,cab
eef,bac,aa,544,ggg,ddd
eef,bac,aa,544,ggg,001
eef,bac,aa,544,ggg,311
eef,bac,cab,aa,ggg,ddd
eef,bac,cab,aa,ggg,001
eef,bac,cab,aa,ggg,311
eef,bac,cab,aa,ggg,544
eef,bac,cab,ddd,ggg,aa
eef,bac,cab,ddd,ggg,001
eef,bac,cab,ddd,ggg,311
eef,bac,cab,ddd,ggg,544
eef,bac,cab,001,ggg,aa
eef,bac,cab,001,ggg,ddd
eef,bac,cab,001,ggg,311
eef,bac,cab,001,ggg,544
eef,bac,cab,311,ggg,aa
eef,bac,cab,311,ggg,ddd
eef,bac,cab,311,ggg,001
eef,bac,cab,311,ggg,544
eef,bac,cab,544,ggg,aa
eef,bac,cab,544,ggg,ddd
eef,bac,cab,544,ggg,001
eef,bac,cab,544,ggg,311
001,bac,aa,cab,ggg,ddd
001,bac,aa,cab,ggg,eef
001,bac,aa,cab,ggg,311
001,bac,aa,cab,ggg,544
001,bac,aa,ddd,ggg,cab
001,bac,aa,ddd,ggg,eef
001,bac,aa,ddd,ggg,311
001,bac,aa,ddd,ggg,544
001,bac,aa,eef,ggg,cab
001,bac,aa,eef,ggg,ddd
001,bac,aa,eef,ggg,311
001,bac,aa,eef,ggg,544
001,bac,aa,311,ggg,cab
001,bac,aa,311,ggg,ddd
001,bac,aa,311,ggg,eef
001,bac,aa,311,ggg,544
001,bac,aa,544,ggg,cab
001,bac,aa,544,ggg,ddd
001,bac,aa,544,ggg,eef
001,bac,aa,544,ggg,311
001,bac,cab,aa,ggg,ddd
001,bac,cab,aa,ggg,eef
001,bac,cab,aa,ggg,311
001,bac,cab,aa,ggg,544
001,bac,cab,ddd,ggg,aa
001,bac,cab,ddd,ggg,eef
001,bac,cab,ddd,ggg,311
001,bac,cab,ddd,ggg,544
001,bac,cab,eef,ggg,aa
001,bac,cab,eef,ggg,ddd
001,bac,cab,eef,ggg,311
001,bac,cab,eef,ggg,544
001,bac,cab,311,ggg,aa
001,bac,cab,311,ggg,ddd
001,bac,cab,311,ggg,eef
001,bac,cab,311,ggg,544
001,bac,cab,544,ggg,aa
001,bac,cab,544,ggg,ddd
001,bac,cab,544,ggg,eef
001,bac,cab,544,ggg,311
311,bac,aa,cab,ggg,ddd
311,bac,aa,cab,ggg,eef
311,bac,aa,cab,ggg,001
311,bac,aa,cab,ggg,544
311,bac,aa,ddd,ggg,cab
311,bac,aa,ddd,ggg,eef
311,bac,aa,ddd,ggg,001
311,bac,aa,ddd,ggg,544
311,bac,aa,eef,ggg,cab
311,bac,aa,eef,ggg,ddd
311,bac,aa,eef,ggg,001
311,bac,aa,eef,ggg,544
311,bac,aa,001,ggg,cab
311,bac,aa,001,ggg,ddd
311,bac,aa,001,ggg,eef
311,bac,aa,001,ggg,544
311,bac,aa,544,ggg,cab
311,bac,aa,544,ggg,ddd
311,bac,aa,544,ggg,eef
311,bac,aa,544,ggg,001
311,bac,cab,aa,ggg,ddd
311,bac,cab,aa,ggg,eef
311,bac,cab,aa,ggg,001
311,bac,cab,aa,ggg,544
311,bac,cab,ddd,ggg,aa
311,bac,cab,ddd,ggg,eef
311,bac,cab,ddd,ggg,001
311,bac,cab,ddd,ggg,544
311,bac,cab,eef,ggg,aa
311,bac,cab,eef,ggg,ddd
311,bac,cab,eef,ggg,001
311,bac,cab,eef,ggg,544
311,bac,cab,001,ggg,aa
311,bac,cab,001,ggg,ddd
311,bac,cab,001,ggg,eef
311,bac,cab,001,ggg,544
311,bac,cab,544,ggg,aa
311,bac,cab,544,ggg,ddd
311,bac,cab,544,ggg,eef
311,bac,cab,544,ggg,001
544,bac,aa,cab,ggg,ddd
544,bac,aa,cab,ggg,eef
544,bac,aa,cab,ggg,001
544,bac,aa,cab,ggg,311
544,bac,aa,ddd,ggg,cab
544,bac,aa,ddd,ggg,eef
544,bac,aa,ddd,ggg,001
544,bac,aa,ddd,ggg,311
544,bac,aa,eef,ggg,cab
544,bac,aa,eef,ggg,ddd
544,bac,aa,eef,ggg,001
544,bac,aa,eef,ggg,311
544,bac,aa,001,ggg,cab
544,bac,aa,001,ggg,ddd
544,bac,aa,001,ggg,eef
544,bac,aa,001,ggg,311
544,bac,aa,311,ggg,cab
544,bac,aa,311,ggg,ddd
544,bac,aa,311,ggg,eef
544,bac,aa,311,ggg,001
544,bac,cab,aa,ggg,ddd
544,bac,cab,aa,ggg,eef
544,bac,cab,aa,ggg,001
544,bac,cab,aa,ggg,311
544,bac,cab,ddd,ggg,aa
544,bac,cab,ddd,ggg,eef
544,bac,cab,ddd,ggg,001
544,bac,cab,ddd,ggg,311
544,bac,cab,eef,ggg,aa
544,bac,cab,eef,ggg,ddd
544,bac,cab,eef,ggg,001
544,bac,cab,eef,ggg,311
544,bac,cab,001,ggg,aa
544,bac,cab,001,ggg,ddd
544,bac,cab,001,ggg,eef
544,bac,cab,001,ggg,311
544,bac,cab,311,ggg,aa
544,bac,cab,311,ggg,ddd
544,bac,cab,311,ggg,eef
544,bac,cab,311,ggg,001
end
Alper AKPINAR
  • 71
  • 3
  • 10