If each number from the list of combinations is assigned one bit in the record of a certain number, then the combinations and groups get their bit representations.
Wherein:
- The number of non-zero bits in the representation corresponds to the number of numbers in a group or in combination (in particular, a group of four numbers corresponds to a representation with four non-zero bits);
- The enumeration of all possible groups can be carried out in a cycle according to representations from zero to 2 k -1, where k is the number of numbers in the list of combinations;
- To calculate the number of non-zero bits in the representation, an optimal 32-bit Kernighan algorithm can be applied;
- Verifying that a combination belongs to a group is a check that the bit representation of the combination does not change with a logical AND with a bit representation of the group.
Program (for both examples):
$combi1 = array ( "a" => array (11, 38), "b" => array (38, 64, 71), "c" => array (11, 24, 38, 65), "d" => array (128, 38, 57, 40) ); $combi2 = array( 'a' => array(11,38), 'b' => array(38,64,71), 'c' => array(11,24,38,65), 'd' => array(128,38,57,40), 'e' => array(38,115,64), 'f' => array(64,11,57,38) ); function bit_count($v){ // ΠΏΠΎΠ΄ΡΡΡΡ Π±ΠΈΡΠΎΠ² Π² ΡΠΈΡΠ»Π΅ ΠΏΠΎ ΠΏΠ°ΡΠ°Π»Π»Π΅Π»ΡΠ½ΠΎΠΌΡ ΠΌΠ΅ΡΠΎΠ΄Ρ ΠΠ΅ΡΠ½ΠΈΠ³Π°Π½Π° $v = $v - (($v >> 1) & 0x55555555); // reuse input as temporary $v = ($v & 0x33333333) + (($v >> 2) & 0x33333333); // temp $c = (($v + ($v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // count return $c; } function print_bin($arr_bin){ // Π²ΡΠ²ΠΎΠ΄ ΠΌΠ°ΡΡΠΈΠ²Π° Π±ΠΈΡΠΎΠ²ΡΡ
ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ΠΈΠΉ $flag_start = 0; print("array( "); array_walk($arr_bin, function($item, $key) use($flag_start){ printf("<br> '%3s' => %016b", $key, $item); }); print("<br>)<br>"); } function bit_coding($combi){ // ΡΠ»ΠΈΠ²Π°Π΅ΠΌ ΠΈ ΡΠΎΡΡΠΈΡΡΠ΅ΠΌ ΡΠΈΡΠ»Π° ΠΈΠ· ΠΌΠ°ΡΡΠΈΠ²ΠΎΠ² $common = array(); array_walk($combi, function($item) use(&$common){ $common = array_unique(array_merge($common, $item)); }); sort($common); // ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ΅ΠΌ ΡΠΈΡΠ»Π° Π±ΠΈΡΠ°ΠΌΠΈ, Π° ΠΌΠ°ΡΡΠΈΠ²Ρ - ΠΊΠΎΠΌΠ±ΠΈΠ½Π°ΡΠΈΡΠΌΠΈ Π±ΠΈΡΠΎΠ² $com_bin = array(); array_walk($combi, function($item, $key) use($common, &$com_bin){ $item_com_bin = 0; array_walk($item, function($val) use($common, &$item_com_bin){ $item_com_bin |= 1 << array_search($val, $common); }); $com_bin[$key] = $item_com_bin; }); $bit_combi = array(); $bit_combi["codes"] = $com_bin; $bit_combi["encryptions"] = $common; return $bit_combi; } function group_from_combs($group_from, $combs, $group_size, $combi_from){ $all_g = (1 << count($group_from)); $base_groups = array(); for($g = 0; $g < $all_g; $g++){ if(bit_count($g) != $group_size) continue; // ΠΎΡΡΠ°Π²ΠΈΠ»ΠΈ Π³ΡΡΠΏΠΏΡ ΡΡΠ΅Π±ΡΠ΅ΠΌΠΎΠ³ΠΎ ΡΠ°Π·ΠΌΠ΅ΡΠ° $combi_count = 0; array_walk($combs, function($item) use($g,&$combi_count) { if ($item == ($item & $g)) $combi_count++; }); if ($combi_count < $combi_from) continue; // ΠΏΡΠΎΠ²Π΅ΡΠΈΠ»ΠΈ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΊΠΎΠΌΠ±ΠΈΠ½Π°ΡΠΈΠΉ $item_group = array("g"=>$g); array_walk($combs, function($item) use($g, &$item_group) { if ($item == ($item & $g)) array_push($item_group, $item); }); array_push($base_groups,$item_group); } return $base_groups; } function decode($n, $decoder){ $b=0; $result = array(); for($test=$n; $test>0; $test = $test >> 1){ if($test&1) array_push($result, $decoder[$b]); $b++; } return $result; }; print("<br>combi1 = "); var_dump($combi1); $bit_com1 = bit_coding($combi1); print("<br>bit_com1 = "); var_dump($bit_com1); print("<br>bit_com1[codes] = "); print_bin($bit_com1["codes"]); $bin_result1 = group_from_combs( $bit_com1["encryptions"], // ΡΠ°ΡΡΠΌΠ°ΡΡΠΈΠ²Π°Π΅ΠΌ Π²ΡΠ΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΡΠ΅ Π³ΡΡΠΏΠΏΡ ΠΈΠ· ΡΠΈΡΠ΅Π», Π²Ρ
ΠΎΠ΄ΡΡΠΈΡ
Π² ΠΌΠ°ΡΡΠΈΠ² ΠΊΠΎΠΌΠ±ΠΈΠ½Π°ΡΠΈΠΉ $bit_com1["codes"], // ΠΏΡΠΎΠ²Π΅ΡΡΠ΅ΠΌ ΠΊΠ°ΠΆΠ΄ΡΡ ΠΊΠΎΠΌΠ±ΠΈΠ½Π°ΡΠΈΡ Π½Π° Π²Ρ
ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ Π² Π³ΡΡΠΏΠΏΡ $group_size = 4, // ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΠΈΡΠ΅Π» Π² Π³ΡΡΠΏΠΏΠ΅ = 4 $combi_from = 2 // ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΊΠΎΠΌΠ±ΠΈΠ½Π°ΡΠΈΠΉ Π² Π³ΡΡΠΏΠΏΠ΅ >= 2 ); print("<br>bin_result1:"); array_walk($bin_result1, function($item) { print("<br>$emsp; "); print_bin($item); }); $decoder = $bit_com1["encryptions"]; $num_result1=$bin_result1; array_walk_recursive($num_result1, function(&$item, $key) use($decoder) { $item = decode($item, $decoder); }); print("num_result1 = "); var_dump($num_result1); print("<br>combi2 = "); var_dump($combi2); $bit_com2 = bit_coding($combi2); print("<br>bit_com2 = "); var_dump($bit_com2); print("<br>bit_com2[codes] = "); print_bin($bit_com2["codes"]); $bin_result2 = group_from_combs( $bit_com2["encryptions"], // ΡΠ°ΡΡΠΌΠ°ΡΡΠΈΠ²Π°Π΅ΠΌ Π²ΡΠ΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΡΠ΅ Π³ΡΡΠΏΠΏΡ ΠΈΠ· ΡΠΈΡΠ΅Π», Π²Ρ
ΠΎΠ΄ΡΡΠΈΡ
Π² ΠΌΠ°ΡΡΠΈΠ² ΠΊΠΎΠΌΠ±ΠΈΠ½Π°ΡΠΈΠΉ $bit_com2["codes"], // ΠΏΡΠΎΠ²Π΅ΡΡΠ΅ΠΌ ΠΊΠ°ΠΆΠ΄ΡΡ ΠΊΠΎΠΌΠ±ΠΈΠ½Π°ΡΠΈΡ Π½Π° Π²Ρ
ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ Π² Π³ΡΡΠΏΠΏΡ $group_size = 4, // ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΠΈΡΠ΅Π» Π² Π³ΡΡΠΏΠΏΠ΅ = 4 $combi_from = 2 // ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΊΠΎΠΌΠ±ΠΈΠ½Π°ΡΠΈΠΉ Π² Π³ΡΡΠΏΠΏΠ΅ >= 2 ); print("<br>bin_result2:"); array_walk($bin_result2, function($item) { print("<br>$emsp; "); print_bin($item); }); $decoder = $bit_com2["encryptions"]; $num_result2=$bin_result2; array_walk_recursive($num_result2, function(&$item, $key) use($decoder) { $item = decode($item, $decoder); }); print("num_result2 = "); var_dump($num_result2);
Results:
combi1 =
array (size = 4)
'a' =>
array (size = 2)
0 => int 11
1 => int 38
'b' =>
array (size = 3)
0 => int 38
1 => int 64
2 => int 71
'c' =>
array (size = 4)
0 => int 11
1 => int 24
2 => int 38
3 => int 65
'd' =>
array (size = 4)
0 => int 128
1 => int 38
2 => int 57
3 => int 40
bit_com1 =
array (size = 2)
'codes' =>
array (size = 4)
'a' => int 5
'b' => int 164
'c' => int 71
'd' => int 284
'encryptions' =>
array (size = 9)
0 => int 11
1 => int 24
2 => int 38
3 => int 40
4 => int 57
5 => int 64
6 => int 65
7 => int 71
8 => int 128
bit_com1 [codes] = array (
'a' => 0000000000000101
'b' => 0000000010100100
'c' => 0000000001000111
'd' => 0000000100011100
)
bin_result1:
; array (
'g' => 0000000001000111
'0' => 0000000000000101
'1' => 0000000001000111
)
; array (
'g' => 0000000010100101
'0' => 0000000000000101
'1' => 0000000010100100
)
num_result1 =
array (size = 2)
0 =>
array (size = 3)
'g' =>
array (size = 4)
0 => int 11
1 => int 24
2 => int 38
3 => int 65
0 =>
array (size = 2)
0 => int 11
1 => int 38
1 =>
array (size = 4)
0 => int 11
1 => int 24
2 => int 38
3 => int 65
1 =>
array (size = 3)
'g' =>
array (size = 4)
0 => int 11
1 => int 38
2 => int 64
3 => int 71
0 =>
array (size = 2)
0 => int 11
1 => int 38
1 =>
array (size = 3)
0 => int 38
1 => int 64
2 => int 71
combi2 =
array (size = 6)
'a' =>
array (size = 2)
0 => int 11
1 => int 38
'b' =>
array (size = 3)
0 => int 38
1 => int 64
2 => int 71
'c' =>
array (size = 4)
0 => int 11
1 => int 24
2 => int 38
3 => int 65
'd' =>
array (size = 4)
0 => int 128
1 => int 38
2 => int 57
3 => int 40
'e' =>
array (size = 3)
0 => int 38
1 => int 115
2 => int 64
'f' =>
array (size = 4)
0 => int 64
1 => int 11
2 => int 57
3 => int 38
bit_com2 =
array (size = 2)
'codes' =>
array (size = 6)
'a' => int 5
'b' => int 164
'c' => int 71
'd' => int 540
'e' => int 292
'f' => int 53
'encryptions' =>
array (size = 10)
0 => int 11
1 => int 24
2 => int 38
3 => int 40
4 => int 57
5 => int 64
6 => int 65
7 => int 71
8 => int 115
9 => int 128
bit_com2 [codes] = array (
'a' => 0000000000000101
'b' => 0000000010100100
'c' => 0000000001000111
'd' => 0000001000011100
'e' => 0000000100100100
'f' => 0000000000110101
)
bin_result2:
; array (
'g' => 0000000000110101
'0' => 0000000000000101
'1' => 0000000000110101
)
; array (
'g' => 0000000001000111
'0' => 0000000000000101
'1' => 0000000001000111
)
; array (
'g' => 0000000010100101
'0' => 0000000000000101
'1' => 0000000010100100
)
; array (
'g' => 0000000100100101
'0' => 0000000000000101
'1' => 0000000100100100
)
; array (
'g' => 0000000110100100
'0' => 0000000010100100
'1' => 0000000100100100
)
num_result2 =
array (size = 5)
0 =>
array (size = 3)
'g' =>
array (size = 4)
0 => int 11
1 => int 38
2 => int 57
3 => int 64
0 =>
array (size = 2)
0 => int 11
1 => int 38
1 =>
array (size = 4)
0 => int 11
1 => int 38
2 => int 57
3 => int 64
1 =>
array (size = 3)
'g' =>
array (size = 4)
0 => int 11
1 => int 24
2 => int 38
3 => int 65
0 =>
array (size = 2)
0 => int 11
1 => int 38
1 =>
array (size = 4)
0 => int 11
1 => int 24
2 => int 38
3 => int 65
2 =>
array (size = 3)
'g' =>
array (size = 4)
0 => int 11
1 => int 38
2 => int 64
3 => int 71
0 =>
array (size = 2)
0 => int 11
1 => int 38
1 =>
array (size = 3)
0 => int 38
1 => int 64
2 => int 71
3 =>
array (size = 3)
'g' =>
array (size = 4)
0 => int 11
1 => int 38
2 => int 64
3 => int 115
0 =>
array (size = 2)
0 => int 11
1 => int 38
1 =>
array (size = 3)
0 => int 38
1 => int 64
2 => int 115
4 =>
array (size = 3)
'g' =>
array (size = 4)
0 => int 38
1 => int 64
2 => int 71
3 => int 115
0 =>
array (size = 3)
0 => int 38
1 => int 64
2 => int 71
1 =>
array (size = 3)
0 => int 38
1 => int 64
2 => int 115