I need to create a large list of part numbers from instructions for how they can be constructed.
Here are two examples.
APXE-N-300-025-A0-12-ET-OO
APXE-N-300-050-A0-12-ET-OO
Each part number is broken into segments like: 0-1-2-3-4-5-6 and some parts have dependencies where, depending on the value of prior parts, there is a restricted selection for that particular part.
Here's the php I have so far. I have an array that sort of contains the pattern but I'm struggling to create the loop that outputs all the options:
$parts[0] = array('APXE');
$parts[1] = array('N','P',"S");
$parts[2] = array('300','400','600','700','800','900','1G4','1G8','2G0','2G5');
$parts[3] = array(
array('dependIndex'=>'2','dependVal'=>'300','values'=>array('025','050','075','150','200','250','500','1M0','1M7','3M5')),
array('dependIndex'=>'2','dependVal'=>'400','values'=>array('025','050','075','150','200','250','500','1M0','1M7','3M5')),
array('dependIndex'=>'2','dependVal'=>'600','values'=>array('1M7','3M5')),
array('dependIndex'=>'2','dependVal'=>'700','values'=>array('200','250','500','1M0','1M7','3M5')),
array('dependIndex'=>'2','dependVal'=>'800','values'=>array('075','150','200','250','500','1M0','1M7','3M5')),
array('dependIndex'=>'2','dependVal'=>'900','values'=>array('025','050','075','150','200','250','500','1M0','1M7','3M5')),
array('dependIndex'=>'2','dependVal'=>'1G4','values'=>array('075','150','250','500','1M0','1M7','3M5','7M0')),
array('dependIndex'=>'2','dependVal'=>'1G8','values'=>array('250','500','1M0','1M7','3M5','7M0','14M')),
array('dependIndex'=>'2','dependVal'=>'2G0','values'=>array('250','500','1M0','1M7','3M5','7M0','14M')),
array('dependIndex'=>'2','dependVal'=>'2G5','values'=>array('250','500','1M0','1M7','3M5','7M0','14M'))
);
$parts[4] = array(
array('dependIndex'=>'2','dependVal'=>'300','values'=>array('A0','A1','A2')),
array('dependIndex'=>'2','dependVal'=>'400','values'=>array('B0','B1','B2','C0')),
array('dependIndex'=>'2','dependVal'=>'600','values'=>array('D0')),
array('dependIndex'=>'2','dependVal'=>'700','values'=>array('E0')),
array('dependIndex'=>'2','dependVal'=>'800','values'=>array('F0')),
array('dependIndex'=>'2','dependVal'=>'900','values'=>array('G0','G2','G3','G4')),
array('dependIndex'=>'2','dependVal'=>'1G4','values'=>array('H0','H1')),
array('dependIndex'=>'2','dependVal'=>'1G8','values'=>array('K0')),
array('dependIndex'=>'2','dependVal'=>'2G0','values'=>array('I0')),
array('dependIndex'=>'2','dependVal'=>'2G5','values'=>array('J0','J1'))
);
$parts[5] = array('12','1L','24','48','AC');
$parts[6] = array('ET','FC','IC','FI','NT');
$parts[7] = array('OO');
foreach($parts as $part)
foreach ($part as $bit){
if(!is_array($bit) $list[] = $bit;
else foreach($bit['values'] as $val) $list[] = $val;
} //??
In the above 'dependIndex'=>'2','dependVal'=>'300' means that for all part numbers with '300' in the 2nd segment, the 3rd segment can have all that array's values.
I'm looking for a PHP function that is flexible enough to handle it when there are varying number of segments. Also the dependencies will change. So in the above example 4 could depend on 3 and 6 could depend on 1.
Can anyone say recursion? lol
Any help is greatly appreciated.
I saw your plea for help on Facebook pointing to this post and decided to take a whack at this.
I changed the way your dependencies are listed, but I believe this to work (despite it being a bit rushed and brute force-like). Hopefully it will give you a good place to start.
/*
* The following arrays should be formatted thusly:
* $exclusionlist[indexOfDeterminingColumn][indexOfDependentColumn] = array(
* 'ValueOfDeterminingColumn' => array('list', 'of', 'valid', 'values')
* );
*/
$dependencyList[3][2] = array(
'300' => array('025','050','075','150','200','250','500','1M0','1M7','3M5'),
'400' => array('025','050','075','150','200','250','500','1M0','1M7','3M5'),
'600' => array('1M7','3M5'),
'700' => array('200','250','500','1M0','1M7','3M5'),
'800' => array('075','150','200','250','500','1M0','1M7','3M5'),
'900' => array('025','050','075','150','200','250','500','1M0','1M7','3M5'),
'1G4' => array('075','150','250','500','1M0','1M7','3M5','7M0'),
'1G8' => array('250','500','1M0','1M7','3M5','7M0','14M'),
'2G0' => array('250','500','1M0','1M7','3M5','7M0','14M'),
'2G5' => array('250','500','1M0','1M7','3M5','7M0','14M')
);
$dependencyList[4][2] = array(
'300' => array('A0','A1','A2'),
'400' => array('B0','B1','B2','C0'),
'600' => array('D0'),
'700' => array('E0'),
'800' => array('F0'),
'900' => array('G0','G2','G3','G4'),
'1G4' => array('H0','H1'),
'1G8' => array('K0'),
'2G0' => array('I0'),
'2G5' => array('J0','J1')
);
$dependencyList[5][1] = array(
'N' => array('12'),
'P' => array('1L'),
'S' => array('24')
);
// $segments contains lists of all valid values for each segment of the part number
$segments[0] = array('APXE');
$segments[1] = array('N','P',"S");
$segments[2] = array('300','400','600','700','800','900','1G4','1G8','2G0','2G5');
$segments[3] = array('025','050','075','14M','150','1M0','1M7','200','250','3M5','500','7M0');
$segments[4] = array('A0','A1','A2','B0','B1','B2','C0','D0','E0','F0','G0','G2','G3','G4','H0','H1','I0','J0','J1','K0');
$segments[5] = array('12','1L','24','48','AC');
$segments[6] = array('ET','FC','IC','FI','NT');
$segments[7] = array('OO');
$partNumbers = array();
// Loop through each segment's array
foreach($segments[0] as $segment0)
if(!testForExclusion(${'segment'.key($dependencyList[0])}, key($dependencyList[0]), $segment0, 0, $dependencyList))
foreach($segments[1] as $segment1)
if(!testForExclusion(${'segment'.key($dependencyList[1])}, key($dependencyList[1]), $segment1, 1, $dependencyList))
foreach($segments[2] as $segment2)
if(!testForExclusion(${'segment'.key($dependencyList[2])}, key($dependencyList[2]), $segment2, 2, $dependencyList))
foreach($segments[3] as $segment3)
if(!testForExclusion(${'segment'.key($dependencyList[3])}, key($dependencyList[3]), $segment3, 3, $dependencyList))
foreach($segments[4] as $segment4)
if(!testForExclusion(${'segment'.key($dependencyList[4])}, key($dependencyList[4]), $segment4, 4, $dependencyList))
foreach($segments[5] as $segment5)
if(!testForExclusion(${'segment'.key($dependencyList[5])}, key($dependencyList[5]), $segment5, 5, $dependencyList))
foreach($segments[6] as $segment6)
if(!testForExclusion(${'segment'.key($dependencyList[6])}, key($dependencyList[6]), $segment6, 6, $dependencyList))
foreach($segments[7] as $segment7)
if(!testForExclusion(${'segment'.key($dependencyList[7])}, key($dependencyList[7]), $segment7, 7, $dependencyList))
$partNumbers[] = $segment0.'-'.$segment1.'-'.$segment2.'-'.$segment3.'-'.$segment4.'-'.$segment5.'-'.$segment6.'-'.$segment7;
echo count( $partNumbers );
echo '<p>';
echo implode('<br/>', $partNumbers);
function testForExclusion($determiningValue, $determiningSegment, $testValue, $testSegment, $exclusionList){
$excluded = false;
if(isset($exclusionList[$testSegment][$determiningSegment][$determiningValue])){
if(!in_array($testValue, $exclusionList[$testSegment][$determiningSegment][$determiningValue])){
$excluded = true;
}
}
return $excluded;
}
EDIT: The data structure and dependency function should be able to be used for any combination of dependencies, so this solution should be expandable.
First I think it would be good to see if you can generate one part number by using array_rand() which picks one or more random entries out of an array. Later you can modify the code to use recursion or nested foreach to output all possible parts.
foreach ($parts as $part)
{
if (!is_array($part[0]))
$list[] = array_rand($part);
else
{
$val = "UNKNOWN";
// Handle dependencies by looking back to the relevant section of
// the current part number that is being generated.
foreach ($part as $bit)
if ($list[$bit['dependIndex']] == $bit['dependVal'])
$val = array_rand($bit['values']);
$list[] = $val;
}
}
var_dump($list);
Generating all possible parts is a fairly hard problem. If this is a homework question, your professor must have a lot of confidence in you!
There are 2 functions you are looking to perform. One for resolving the dependencies, and one for the number generation.
Given the dependencies in the following model:
$dependencies = array(
'300'=>array(
0=>array('025','050','075','150','200','250','500','1M0','1M7','3M5'),
1=>array('A0','A1','A2')
),
'400'=>array(
0=>array('025','050','075','150','200','250','500','1M0','1M7','3M5'),
1=>array('B0','B1','B2','C0')
),
'600'=>array(
0=>array('1M7','3M5'),
1=>array('D0')
),
'700'=>array(
0=>array('200','250','500','1M0','1M7','3M5'),
1=>array('E0')
),
'800'=>array(
0=>array('075','150','200','250','500','1M0','1M7','3M5'),
1=>array('F0')
),
'900'=>array(
0=>array('025','050','075','150','200','250','500','1M0','1M7','3M5'),
1=>array('G0','G2','G3','G4')
),
'1G4'=>array(
0=>array('075','150','250','500','1M0','1M7','3M5','7M0'),
1=>array('H0','H1')
),
'1G8'=>array(
0=>array('250','500','1M0','1M7','3M5','7M0','14M'),
1=>array('H0','H1')
),
'2G0'=>array(
0=>array('250','500','1M0','1M7','3M5','7M0','14M'),
1=>array('I0')
),
'2G5'=>array(
0=>array('250','500','1M0','1M7','3M5','7M0','14M'),
1=>array('J0','J1')
)
);
you can create a function that combines positions 3, 4, and 5 into a pre-calculated string:
function position3($arrays){
$retVal = array();
foreach ($arrays as $key=>$value){
foreach ($value[0] as $v1){
foreach ($value[1] as $v2){
array_push($retVal, $key . '-' . $v1 . '-' . $v2);
}
}
}
return $retVal;
}
With position 3 combined in all of the defined mutations, you can map the positions into an array model as follows:
$parts[0] = array('APXE');
$parts[1] = array('N','P',"S");
$parts[2] = position3($dependencies);
$parts[3] = array('12','1L','24','48','AC');
$parts[4] = array('ET','FC','IC','FI','NT');
$parts[5] = array('OO');
You can then call a looping function that build each permutation of your combined values (in total, 13275) with this function:
function go($parts){
$total = 0;
foreach ($parts[0] as $pos1){
foreach ($parts[1] as $pos2){
foreach ($parts[2] as $pos3){
foreach ($parts[3] as $pos4){
foreach ($parts[4] as $pos5){
foreach ($parts[5] as $pos6 ){
echo implode('-', [$pos1,$pos2,$pos3,$pos4,$pos5,$pos6 ])."\n";
$total++;
}
}
}
}
}
}
echo $total;
}
Putting this all together will make:
function position3($arrays){
$retVal = array();
foreach ($arrays as $key=>$value){
foreach ($value[0] as $v1){
foreach ($value[1] as $v2){
#echo $key . '-' . $v1 . '-' . $v2 . "\n";
array_push($retVal, $key . '-' . $v1 . '-' . $v2);
}
}
}
return $retVal;
}
$dependencies = array(
'300'=>array(
0=>array('025','050','075','150','200','250','500','1M0','1M7','3M5'),
1=>array('A0','A1','A2')
),
'400'=>array(
0=>array('025','050','075','150','200','250','500','1M0','1M7','3M5'),
1=>array('B0','B1','B2','C0')
),
'600'=>array(
0=>array('1M7','3M5'),
1=>array('D0')
),
'700'=>array(
0=>array('200','250','500','1M0','1M7','3M5'),
1=>array('E0')
),
'800'=>array(
0=>array('075','150','200','250','500','1M0','1M7','3M5'),
1=>array('F0')
),
'900'=>array(
0=>array('025','050','075','150','200','250','500','1M0','1M7','3M5'),
1=>array('G0','G2','G3','G4')
),
'1G4'=>array(
0=>array('075','150','250','500','1M0','1M7','3M5','7M0'),
1=>array('H0','H1')
),
'1G8'=>array(
0=>array('250','500','1M0','1M7','3M5','7M0','14M'),
1=>array('H0','H1')
),
'2G0'=>array(
0=>array('250','500','1M0','1M7','3M5','7M0','14M'),
1=>array('I0')
),
'2G5'=>array(
0=>array('250','500','1M0','1M7','3M5','7M0','14M'),
1=>array('J0','J1')
)
);
$parts[0] = array('APXE');
$parts[1] = array('N','P',"S");
$parts[2] = position3($dependencies);
$parts[3] = array('12','1L','24','48','AC');
$parts[4] = array('ET','FC','IC','FI','NT');
$parts[5] = array('OO');
function go($parts){
$total = 0;
foreach ($parts[0] as $pos1){
foreach ($parts[1] as $pos2){
foreach ($parts[2] as $pos3){
foreach ($parts[3] as $pos4){
foreach ($parts[4] as $pos5){
foreach ($parts[5] as $pos6 ){
echo implode('-', [$pos1,$pos2,$pos3,$pos4,$pos5,$pos6 ])."\n";
$total++;
}
}
}
}
}
}
echo $total;
}
go($parts);
I think I understand what you want here... this is a very brute-force way of dealing with it, but should work:
<?php
$parts[0] = array('APXE');
$parts[1] = array('N','P',"S");
$parts[2] = array('300','400','600','700','800','900','1G4','1G8','2G0','2G5');
$parts[3] = array(
array('dependIndex'=>'2','dependVal'=>'300','values'=>array('025','050','075','150','200','250','500','1M0','1M7','3M5')),
array('dependIndex'=>'2','dependVal'=>'400','values'=>array('025','050','075','150','200','250','500','1M0','1M7','3M5')),
array('dependIndex'=>'2','dependVal'=>'600','values'=>array('1M7','3M5')),
array('dependIndex'=>'2','dependVal'=>'700','values'=>array('200','250','500','1M0','1M7','3M5')),
array('dependIndex'=>'2','dependVal'=>'800','values'=>array('075','150','200','250','500','1M0','1M7','3M5')),
array('dependIndex'=>'2','dependVal'=>'900','values'=>array('025','050','075','150','200','250','500','1M0','1M7','3M5')),
array('dependIndex'=>'2','dependVal'=>'1G4','values'=>array('075','150','250','500','1M0','1M7','3M5','7M0')),
array('dependIndex'=>'2','dependVal'=>'1G8','values'=>array('250','500','1M0','1M7','3M5','7M0','14M')),
array('dependIndex'=>'2','dependVal'=>'2G0','values'=>array('250','500','1M0','1M7','3M5','7M0','14M')),
array('dependIndex'=>'2','dependVal'=>'2G5','values'=>array('250','500','1M0','1M7','3M5','7M0','14M'))
);
$parts[4] = array(
array('dependIndex'=>'2','dependVal'=>'300','values'=>array('A0','A1','A2')),
array('dependIndex'=>'2','dependVal'=>'400','values'=>array('B0','B1','B2','C0')),
array('dependIndex'=>'2','dependVal'=>'600','values'=>array('D0')),
array('dependIndex'=>'2','dependVal'=>'700','values'=>array('E0')),
array('dependIndex'=>'2','dependVal'=>'800','values'=>array('F0')),
array('dependIndex'=>'2','dependVal'=>'900','values'=>array('G0','G2','G3','G4')),
array('dependIndex'=>'2','dependVal'=>'1G4','values'=>array('H0','H1')),
array('dependIndex'=>'2','dependVal'=>'1G8','values'=>array('K0')),
array('dependIndex'=>'2','dependVal'=>'2G0','values'=>array('I0')),
array('dependIndex'=>'2','dependVal'=>'2G5','values'=>array('J0','J1'))
);
$parts[5] = array('12','1L','24','48','AC');
$parts[6] = array('ET','FC','IC','FI','NT');
$parts[7] = array('OO');
foreach($parts[1] as $eigth){
foreach($parts[2] as $sect){
foreach($parts[3] as $keya => $firstloop){
foreach($parts[3][$keya] as $itemone){
foreach($parts[3][$keya]['values'] as $firstselector){
foreach($parts[4] as $keyb => $secondloop){
foreach($parts[4][$keyb] as $itemtwo){
foreach($parts[4][$keyb]['values'] as $secondselector){
foreach($parts[5] as $halve){
foreach($parts[6] as $quarter){
if($sect == $parts[3][$keya]['dependVal'] && $sect == $parts[3][$keyb]['dependVal']){
echo $parts[0][0] . "-" . $eigth . "-" . $sect . "-" . $firstselector . "-" . $secondselector . "-" . $halve . "-" . $quarter . "<br>";
}
}
}
}
}
}
}
}
}
}
}
?>