/    Sign up×
Community /Pin to ProfileBookmark

Generate combinations using PHP

Hi,

I want to generate a combination of numbers.

Example:Generating all cobination of arranging 5 numbers out of the given 30.

if i have 30 numbers and i pick 5 at a time i can arrange this in 142506 different ways. the numbers 5 and 30 should be dynamic .(If i change 5 or 30 it should be able to generate corresponding number of combinations.)

This is the first 20 combinations.

How can i generate this and dump it into a table in MySQL.

0 1_2_3_4_5_ 0
1 1_2_3_4_6_
0
2 1_2_3_4_7_ 0
3 1_2_3_4_8_
0
4 1_2_3_4_9_ 0
5 1_2_3_4_10_
0
6 1_2_3_4_11_ 0
7 1_2_3_4_12_
0
8 1_2_3_4_13_ 0
9 1_2_3_4_14_
0
10 1_2_3_4_15_ 0
11 1_2_3_4_16_
0
12 1_2_3_4_17_ 0
13 1_2_3_4_18_
0
14 1_2_3_4_19_ 0
15 1_2_3_4_20_
0
16 1_2_3_4_21_ 0
17 1_2_3_4_22_
0
18 1_2_3_4_23_ 0
19 1_2_3_4_24_
0

Thanks

to post a comment
PHP

9 Comments(s)

Copy linkTweet thisAlerts:
@scragarMar 14.2009 — This returns the arrays in the wrong order, but it works(in theory).
[code=php]function foo($max, $levels, $parents=Array()){
$children = array();// we want an empty array to fill up as we go.
if($levels){// if we have children. makes the code more efficient to put it here.
$tmp = $parents;// we need a copy of the array later. more efficient to create it here.
for($i = 1; $i < $max; $i++){
if( in_array($i, $parents))// if we already used that number skip it
continue;
$tmp[count($parents)] = $i;// add the new number to our copy of the parents array
$c = count($children);// and save recalculating $c later.
$children[$c] = foo($max, $levels-1, $tmp);// get the children of itself...
for($j = $c-1; $j>= 0; $j--)// for each of the children returned add the number to it
$children[$j][] = $i;
}
}else{// no children, this is easy
for($i = 1; $i < $max; $i++){
if( in_array($i, $parents))
continue;
$children[] = Array($i);// add the non-repeats to an array
}
}
return $children;// return the children as we've worked out.
}[/code]
Works logically, but I've not tested it.

EDIT: OK, I've commented it and it doesn't work like it should(I see a flaw in my logic ?), but it's close. If someone doesn't fit it in an hour or so I'll take another look.
Copy linkTweet thisAlerts:
@rsequieraauthorMar 14.2009 — Thanks for the reply.

Could you please let me know what the three parameters you are using in your function with reference to my problem

I want to insert these values to the DB.
Copy linkTweet thisAlerts:
@scragarMar 14.2009 — Well $max would be the highest number it counts to, so 30 in your example, $levels is the highest depth of recusion it should reach(either 4 or 5 in your example, I'm too tired to think about it right now, it's not really too important anyway, a quick edit would turn it from 4 to 5 if need be), the final element shouldn't need to be passed, it's only used when the function calls itself, and contains a list of numbers already used in the chain, so it doesn't repeat them.


EDIT: incase anyone is wondering the reason my code won't work is that the end arrays always contain ($max-$levels) elements and have a crazy structure, I'm assuming I need to use Array_merge somewhere, but I'm feel fuzzy right now, I can't think straight enough to work it out.
Copy linkTweet thisAlerts:
@rsequieraauthorMar 14.2009 — Thanks for your help..

I am new to PHP .Could you please let me know how i can print the values in order to dump them to the database.
Copy linkTweet thisAlerts:
@scragarMar 14.2009 — I haven't tried this, but I think:
[code=php]$children[$c] = foo($max, $levels-1, $tmp);// get the children of itself...
// should be replaced with:
$children = Array_merge($children, foo($max, $levels-1, $tmp));[/code]


As for storing the info in a DB, you should be able to connect to the DB, then do a nice insert query, something like[code=php]mysql_connect('HOST', 'USERNAME', 'PASSWORD');
mysql_select_db('DB NAME');

$combos = foo(30, 5);
$query = 'INSERT INTO tblname VALUES';

foreach($combos as $r){
$query .= "n ({$r[0]}, {$r[1]}, {$r[2]}, {$r[3]}, {$r[4]}), ";
}
$query = preg_replace('/, $/', '', $query);
if( mysql_query($query) ){
echo mysql_affected_rows() . " rows inserted.";
}else{
echo "error inserting the things into the database, MySQL said:<pre>n".mysql_error()."n</pre>";
}[/code]
Copy linkTweet thisAlerts:
@rsequieraauthorMar 14.2009 — This script works if i give a small number( 5,2). but when give higher number like (30,5) it will run out of memory if i increase the memory size and try it will time out.

Please help me to rresolve this.



[code=php]<?php

ini_set("memory_limit","2000M");


function foo($max, $levels, $parents=Array()){
$children = array();// we want an empty array to fill up as we go.
if($levels){// if we have children. makes the code more efficient to put it here.
$tmp = $parents;// we need a copy of the array later. more efficient to create it here.
for($i = 1; $i < $max; $i++){
if( in_array($i, $parents))// if we already used that number skip it
continue;
$tmp[count($parents)] = $i;// add the new number to our copy of the parents array
$c = count($children);// and save recalculating $c later.
$children = Array_merge($children, foo($max, $levels-1, $tmp)); // get the children of itself...
for($j = $c-1; $j>= 0; $j--)// for each of the children returned add the number to it
$children[$j][] = $i;
}
}else{// no children, this is easy
for($i = 1; $i < $max; $i++){
if( in_array($i, $parents))
continue;
$children[] = Array($i);// add the non-repeats to an array
}
}
return $children;// return the children as we've worked out.
}
$children[$c] = foo($max, $levels-1, $tmp);// get the children of itself...
// should be replaced with:
$children = Array_merge($children, foo($max, $levels-1, $tmp));
mysql_connect('localhost', 'root', 'root');
mysql_select_db('test');

$combos = foo(30,5);

$query = "INSERT INTO ticket (name) VALUES ('$combos')";

foreach($combos as $r){
$query .= "n ({$r[0]}, {$r[1]}, {$r[2]}, {$r[3]}, {$r[4]}), ";
}
$query = preg_replace('/, $/', '', $query);
if( mysql_query($query) ){
echo mysql_affected_rows() . " rows inserted.";
}else{
echo "error inserting the things into the database, MySQL said:<pre>n".mysql_error()."n</pre>";
}


?>[/code]
Copy linkTweet thisAlerts:
@scragarMar 15.2009 — [code=php]<?php

// ini_set("memory_limit","2000M");


function foo($max, $levels, $parents=Array()){
$children = array();
if($levels > 1){
$tmp = $parents;
for($i = 1; $i < $max; $i++){
if( in_array($i, $parents))
continue;
$tmp[count($parents)] = $i;
$c = count($children);
$children = Array_merge($children, foo($max, $levels-1, $tmp));
}
for($j = $c-1; $j>= 0; $j--)
$children[$j][] = $i;
}else{
for($i = 1; $i < $max; $i++){
if( in_array($i, $parents))
continue;
$children[] = Array($i);
}
}
return $children;
}




mysql_connect('localhost', 'root', 'root');
mysql_select_db('test');

$combos = foo(30,5);

$query = "INSERT INTO ticket (name) VALUES ";

foreach($combos as $r){
$query .= "n ({$r[0]}, {$r[1]}, {$r[2]}, {$r[3]}, {$r[4]}), ";
}
$query = preg_replace('/, $/', '', $query);
if( mysql_query($query) ){
echo mysql_affected_rows() . " rows inserted.";
}else{
echo "error inserting the things into the database, MySQL said:<pre>n".mysql_error()."n</pre>";
}

?>[/code]

I'm not sure there is a better way to do it without hard coding the levels it will search...

Having said that, something like this might work(it inserts them as it goes, rather than bulk inserting later):
[code=php]<?php

mysql_connect('localhost', 'root', 'root');
mysql_select_db('test');
$results = FindChildren(30, 5);
mysql_close();
echo $results . " rows inserted.";



function Insert2Db($max, $parents){
$str = "INSERT INTO ticket (name) VALUES ('".implode('_', $parents);
for($i = 1, $j = 0; $i < $max; $i++){
if(in_array($i, $parents))
continue;
if(mysql_query($str."_{$i}')"))
$j++;
}
return $j;
}

function FindChildren($max, $levels, $fnc='Insert2Db', $parents=array()){
$tmp = $parents;
$j = 0;
for($i = 1; $i < $max; $i++){
if( in_array($i, $parents))
continue;
$tmp[count($parents)] = $i;
$j += ($levels > 2)?
FindChildren($max, $levels-1, $func, $tmp):
$fnc($max, $tmp);
}
return $j;
}
[/code]
Copy linkTweet thisAlerts:
@rsequieraauthorMar 15.2009 — Tried this code.

Gives me error

[B]"Fatal error: Function name must be a string in C:Program FilesApache GroupApache2htdocscomb.php on line 31"[/B]

am i doing anything wrong?
Copy linkTweet thisAlerts:
@scragarMar 15.2009 — FindChildren($max, $levels-1, $f[b]u[/b]nc, $tmp): remove the excess U.
×

Success!

Help @rsequiera spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.18,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @AriseFacilitySolutions09,
tipped: article
amount: 1000 SATS,

tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,
)...