Last active
October 9, 2015 22:29
-
-
Save mloureiro/a0ecd1ef477e08b6b83a to your computer and use it in GitHub Desktop.
Make all available options from a demanded list
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$sections = [ | |
'bread' => [ | |
'multichoice' => false, | |
'options' => ['normal','wrap'] | |
], | |
'salad' => [ | |
'multichoice' => true, | |
'options' => ['lettuce','tomatoes', 'corn'] | |
], | |
'sauce' => [ | |
'multichoice' => true, | |
'options' => ['mostard','ketchup'] | |
], | |
'protein' => [ | |
'multichoice' => false, | |
'options' => ['hamburger','tuna', 'smoked salmon'] | |
], | |
]; | |
/** | |
* Evaluate if it is NOT a multi dimensional array | |
* | |
* @param array $list | |
* | |
* @return bool | |
*/ | |
function isFlat(array $list) | |
{ | |
foreach($list as $element) | |
{ | |
if(is_array($element)) | |
{ | |
return false; | |
} | |
} | |
return true; | |
} | |
/** | |
* Flat multi dimensional arrays into Bi dimensional (max) | |
* | |
* @param array $list | |
* | |
* @return array | |
*/ | |
function flatToBiDimensionalArray(array $list) | |
{ | |
if(isFlat($list)) | |
{ | |
return $list; | |
} | |
$final = []; | |
foreach($list as $element) | |
{ | |
if(isFlat($element)) | |
{ | |
$final[] = $element; | |
} | |
else | |
{ | |
$final = array_merge($final, flatToBiDimensionalArray($element)); | |
} | |
} | |
return $final; | |
} | |
/** | |
* Make each element of the array into an array of itself | |
* | |
* @param array $list | |
* | |
* @return array | |
*/ | |
function eachElementToArray(array $list) | |
{ | |
$final = []; | |
foreach($list as $element) | |
{ | |
$final[] = [$element]; | |
} | |
return $final; | |
} | |
/** | |
* Generate all combinations possible without order mattering | |
* | |
* @param array $list | |
* | |
* @return array | |
*/ | |
function generateAllCombinations(array $list) | |
{ | |
if(count($list) === 1) | |
{ | |
return $list; | |
} | |
$first = array_pop($list); | |
$combinations = flatToBiDimensionalArray(generateAllCombinations($list)); | |
$final = []; | |
$final[] = [$first]; | |
foreach ($combinations as $combination) | |
{ | |
$final[] = is_array($combination) | |
? array_merge([$first], $combination) | |
: [$first, $combination]; | |
} | |
if(isFlat($combinations)) | |
{ | |
$final[] = $combinations; | |
} | |
else | |
{ | |
$final = array_merge($final, $combinations); | |
} | |
return $final; | |
} | |
/** | |
* Is similar to generateAllCombinations() but doesn't attempt to flat the arrays | |
* | |
* @param array $sections | |
* | |
* @return array | |
*/ | |
function mixTogether(array $sections) | |
{ | |
if(count($sections) === 1) | |
{ | |
$key = key($sections); | |
$final = []; | |
foreach(array_pop($sections) as $type) | |
{ | |
$final[] = [$key => $type]; | |
} | |
return $final; | |
} | |
$sandwiches = []; | |
end($sections); | |
$key = key($sections); | |
$section = array_pop($sections); | |
$combinations = mixTogether($sections); | |
foreach($section as $type) | |
{ | |
foreach($combinations as $combination) | |
{ | |
$combination[$key] = $type; | |
$sandwiches[] = $combination; | |
} | |
} | |
return $sandwiches; | |
} | |
/* | |
* | |
* Script | |
* | |
*/ | |
$iterations = 100000; | |
$i = 0; | |
$start = microtime(true); | |
while($i++ < $iterations) | |
{ | |
// generate all combinations for each section | |
$sectionCombinations = []; | |
foreach ($sections as $id => $section) | |
{ | |
$sectionCombinations[$id] = $section['multichoice'] | |
? generateAllCombinations($section['options']) | |
: eachElementToArray($section['options']); | |
} | |
$sandwichList = mixTogether($sectionCombinations); | |
} | |
$end = microtime(true); | |
print_r($sandwichList); | |
$totalCombinations = count($sandwichList); | |
echo "\n\nTotal time for {$iterations} iterations with {$totalCombinations} combinations: " . ($end - $start) . " seconds\n"; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This was made for the stackoverflow question:
http://stackoverflow.com/questions/33044401/generate-all-possible-combinations