Picking random element by user defined weights [duplicate] - php

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Generating random results by weight in PHP?
I have a web application where users can add 1-20 strings of text and assign a weight to them of how often it should show up. The system would then choose a random string based on the defined weights. What is the best way to go about this? Do the range values for the weight for each string matter? Could I just have the user assign a number (0-100) for each string? How would you go about choosing a random string? (Each choice doesn't worry about what was chosen before, every string has the same odds (based on weight) of being chosen at the start of each call).

I use this function in several PHP game engines:
<?php
/**
* #param array $values - just the weights
* #return integer A number between 0 and count($values) - 1
*/
function getBucketFromWeights($values) {
$total = $currentTotal = $bucket = 0;
$firstRand = mt_rand(1, 100);
foreach ($values as $amount) {
$total += $amount;
}
$rand = ($firstRand / 100) * $total;
foreach ($values as $amount) {
$currentTotal += $amount;
if ($rand > $currentTotal) {
$bucket++;
}
else {
break;
}
}
return $bucket;
}
Usage
Suppose I have the user weights in an associative array where each string points to its weight:
$weighted_strings = array(
"important string" => 100,
"terrible string" => 10,
"never string" => 0,
// etc
);
If I wanted to pull a string based on weight, I'd do this:
$weights = array_values($weighted_strings);
$strings = array_keys($weighted_strings);
$index = getBucketFromWeights($weights);
$selectedString = $strings[$index];

Here is a simple implementation:
function Probability($data, $number = 1)
{
$result = array();
if (is_array($data) === true)
{
$data = array_map('abs', $data);
$number = min(max(1, abs($number)), count($data));
while ($number-- > 0)
{
$chance = 0;
$probability = mt_rand(1, array_sum($data));
foreach ($data as $key => $value)
{
$chance += $value;
if ($chance >= $probability)
{
$result[] = $key; unset($data[$key]); break;
}
}
}
}
return $result;
}
With this function you can specify how many unique weighted random elements you want (IDEOne).

Related

How to determine if data is increasing or decreasing in PHP

Let's say we have the following data in an array:
$data1 = [3,5,7,6,8,9,13,14,17,15,16,16,16,18,22,20,21,20];
$data2 = [23,18,17,17,16,15,16,14,15,10,11,7,4,5];
As with $data1 we can say the data is increasing while in $data2 it is decreasing.
Using PHP, how do you know the data is increasing or decreasing, and is there a way on how to measure
know the rate of increasing as well as decreasing i.e in terms of percentage.
Edit
From the comments I received I got an idea and here is what I have tried.
What I want to achieve;
I want to know if the trend of the data coming in is upwards or downwards.
Want also to know the rate at which the data is rising or droping. For example $data1 = [1,3,5]; is not the same as $data2 = [1, 20, 55];. You can see $data1 rate of increase is not the same as $data2.
function increaseOrDecrease($streams = []) : array
{
$streams = [3,5,7,6,8,9,13,14,17,15,16,16,16,18,22,20,21,20]; // For the increasing
//$streams = [23,18,17,17,16,15,16,14,15,10,11,7,4,5]; // For the decreasing
$first = 0;
$diff = [];
foreach ($streams as $key => $number) {
if ($key != 0) {
$diff[] = $number - $first;
}
$first = $number;
}
$avgdifference = array_sum($diff)/count($diff); //Get the average
$side = $avgdifference > 0 ? 'UP' : 'DOWN';
$avgsum = array_sum($streams)/count($streams);
$percentage = abs($avgdifference)/$avgsum * 100;
if ($side == 'UP') {
$data = [
'up' => true,
'percent' => $percentage,
];
}else {
$data = [
'up' => false,
'percent' => $percentage,
];
}
return $data;
}
I would like some help to refactor this code or the best approach to solve the issue.
There are several ways to analyze data and extract a trend. The most classical method is called
least squares. It's a way of fitting a line
through the data. The method computes the slope and the intercept of the line. The trend is just the slope.
The formulas are given here.
A PHP implementation is the following:
function linearRegression($x, $y)
{
$x_sum = array_sum($x);
$y_sum = array_sum($y);
$xy_sum = 0;
$x2_sum = 0;
$n = count($x);
for($i=0;$i<$n;$i++)
{
$xy_sum += $x[$i] * $y[$i];
$x2_sum += $x[$i] * $x[$i];
}
$beta = ($n * $xy_sum - $x_sum * $y_sum) / ($n * $x2_sum - $x_sum * $x_sum);
$alpha = $y_sum / $n - $beta * $x_sum / $n;
return ['alpha' => $alpha, 'beta' => $beta];
}
function getTrend($data)
{
$x = range(1, count($data)); // [1, 2, 3, ...]
$fit = linearRegression($x, $data);
return $fit['beta']; // slope of fitted line
}
Examples:
echo getTrend([1, 2, 3]); // 1
echo getTrend([1, 0, -1]); // -1
echo getTrend([3,5,7,6,8,9,13,14,17,15,16,16,16,18,22,20,21,20]); // 1.065
echo getTrend([23,18,17,17,16,15,16,14,15,10,11,7,4,5]); // -1.213
You are asking for a type of data structure that can represent ascending as well as descending data. PHP got SplMinHeap and SplMaxHeap for this purpose. These built in classes make life easer when dealing with ascending or descending datasets.
A quick example ...
<?php
declare(strict_types=1);
namespace Marcel;
use SplMinHeap;
$numbers = [128, 32, 64, 8, 256];
$heap = new SplMinHeap();
foreach ($numbers as $number) {
$heap->insert($number);
}
$heap->rewind();
while($heap->valid()) {
// 8, 32, 64, 128, 256
echo $heap->current() . PHP_EOL;
$heap->next();
}
The SplMinHeap class keeps the minimum automatically on the top. So just use heaps instead of arrays that have no structure. Same goes for SplMaxHeap that keeps the highest value on the top.
Finding the differences
If you want to iterate all data and finding the differences between one to the next, you just have to iterate the heap. It 's ordered anyway.
$heap->rewind();
$smallest = $heap->current();
while($heap->valid()) {
// 8, 32, 64, 128, 256
$current = $heap->current();
echo $current . PHP_EOL;
// 0 (8 - 8), 24 (32 - 8), 32 (64 - 32), 64 (128 - 64), 128 (256 - 128)
echo "difference to the value before: " . ($current - $smallest) . PHP_EOL;
$smallest = $current;
$heap->next();
}
I would do simple things like this
$data1 = [3,5,7,6,8,9,13,14,17,15,16,16,16,18,22,20,21,20];
$data2 = [23,18,17,17,16,15,16,14,15,10,11,7,4,5];
getTrend($data1) //Returns up
getTrend($data2) // Returns down
function getTrend($arr)
{
$up = 0;
$down = 0;
$prev = "";
foreach($arr as $val)
{
if($prev != "" && $val > $prev)
{
$up = $val-$prev;
}
else if($prev != "" && $val < $prev)
{
$down = $prev-$val ;
}
$prev = $val);
}
if($up > $down)
{
return "up";
}
else if($down > $up)
{
return "down";
}
else {
return "flat";
}
}

Get nearest sequence result from an array and given pattern with PHP

I am trying to get year and month from the letters using established sequence. I know that the sequence is based on the following letters:
$letters = array('B','C','D','F','G','H','J','K','L','M','N','P','R','S','T','V','W','X','Y','Z');
It started with 0000BBB and when it reaches 9999 it becomes BBC, BBD etc. So I don't need the numbers in that case and only letters as I have a list of last registered sequence per year and month like this:
$plates = array(
array('2018','KHF','KHX','KJV','KKN','KLM','KML','KNK','KPD','KPR','KPT','----','----'),
array('2017','JWN','JXF','JYB','JYT','JZP','KBM','KCH','KCV','KDK','KFB','KFV','KGN'),
array('2016','JLN','JMF','JMY','JNR','JPK','JRG','JRZ','JSL','JTB','JTR','JVH','JVZ'),
array('2015','JCK','JCY','JDR','JFG','JFW','JGP','JHJ','JHT','JJH','JJW','JKK','JKZ'),
array('2014','HVN','HVZ','HWM','HXB','HXN','HYD','HTY','HZB','HZL','HZZ','JBL','JBY'),
array('2013','HNT','HPC','HPN','HPY','HRK','HRX','HSK','HSR','HSZ','HTK','HTV','HVF'),
array('2012','HJC','HJM','HKB','HKL','HKX','HLK','HLW','HMD','HML','HMT','HNC','HNK'),
array('2011','HBP','HCB','HCR','HDC','HDR','HFF','HFT','HGC','HGM','HGX','HHH','HHT'),
array('2010','GTC','GTS','GVM','GWC','GWV','GXP','GYD','GYM','GYX','GZJ','GZT','HBG'),
array('2009','GKS','GLC','GLP','GMC','GMN','GNF','GNY','GPJ','GPW','GRM','GSC','GSR'),
array('2008','FZR','GBN','GCK','GDH','GFC','GFY','GGV','GHG','GHT','GJJ','GJV','GKH'),
array('2007','FKY','FLV','FNB','FNZ','FRC','FSJ','FTP','FVJ','FWC','FXB','FXY','FYY'),
array('2006','DVW','DWT','DXZ','DYY','FBC','FCJ','FDP','FFK','FGF','FHD','FJD','FKC'),
array('2005','DFZ','DGX','DHZ','DKB','DLD','DMJ','DNP','DPK','DRG','DSC','DTB','DVB'),
array('2004','CRV','CSS','CTT','CVR','CWR','CXT','CYY','CZP','DBJ','DCH','DDG','DFF'),
array('2003','CDV','CFM','CGJ','CHF','CJC','CKB','CLD','CLV','CMM','CNK','CPF','CRC'),
array('2002','BSL','BTF','BTZ','BVW','BWT','BXP','BYP','BZF','BZV','CBP','CCH','CDC'),
array('2001','BFJ','BGF','BHG','BJC','BKB','BLC','BMF','BMW','BNL','BPG','BRB','BRT'),
array('2000','---','---','---','---','---','---','---','---','BBJ','BCD','BCY','BDR')
);
That means that array index 0 is the year and from 1 to 12 would be month. I am trying to find a match but then realize I can not search exact value and need to look for nearest value based on letters.
I would deeply appreciate if anyone could direct me in right direction what would be the best method of doing this.
This is a test so far but this will just return an exact match, I would have to search any possible letters such as KHW as an example that would have to match as nearest value to KHX
foreach ($plates as $key => $val) {
$search = array_search('KHX', $plates[$key]);
if($search){
echo $search."\n";
echo $plates[$key][0];
break;
}
}
You can solve it with O(log n) with a binary search. But in a more straightforward solution, you can solve it with O(n).
You can calculate the difference between each word with the below algorithm.
‍‍
<?php
function strToInt($str)
{
$result = 0;
for ($i = 0; $i < strlen($str); $i++) {
$result = $result * 100 + ord($str[$i]);
}
return $result;
}
function find($searchStr)
{
$plates = [
['2018','KHF','KHX','KJV','KKN','KLM','KML','KNK','KPD','KPR','KPT','----','----'],
['2017','JWN','JXF','JYB','JYT','JZP','KBM','KCH','KCV','KDK','KFB','KFV','KGN'],
['2016','JLN','JMF','JMY','JNR','JPK','JRG','JRZ','JSL','JTB','JTR','JVH','JVZ'],
['2015','JCK','JCY','JDR','JFG','JFW','JGP','JHJ','JHT','JJH','JJW','JKK','JKZ'],
['2014','HVN','HVZ','HWM','HXB','HXN','HYD','HTY','HZB','HZL','HZZ','JBL','JBY'],
['2013','HNT','HPC','HPN','HPY','HRK','HRX','HSK','HSR','HSZ','HTK','HTV','HVF'],
['2012','HJC','HJM','HKB','HKL','HKX','HLK','HLW','HMD','HML','HMT','HNC','HNK'],
['2011','HBP','HCB','HCR','HDC','HDR','HFF','HFT','HGC','HGM','HGX','HHH','HHT'],
['2010','GTC','GTS','GVM','GWC','GWV','GXP','GYD','GYM','GYX','GZJ','GZT','HBG'],
['2009','GKS','GLC','GLP','GMC','GMN','GNF','GNY','GPJ','GPW','GRM','GSC','GSR'],
['2008','FZR','GBN','GCK','GDH','GFC','GFY','GGV','GHG','GHT','GJJ','GJV','GKH'],
['2007','FKY','FLV','FNB','FNZ','FRC','FSJ','FTP','FVJ','FWC','FXB','FXY','FYY'],
['2006','DVW','DWT','DXZ','DYY','FBC','FCJ','FDP','FFK','FGF','FHD','FJD','FKC'],
['2005','DFZ','DGX','DHZ','DKB','DLD','DMJ','DNP','DPK','DRG','DSC','DTB','DVB'],
['2004','CRV','CSS','CTT','CVR','CWR','CXT','CYY','CZP','DBJ','DCH','DDG','DFF'],
['2003','CDV','CFM','CGJ','CHF','CJC','CKB','CLD','CLV','CMM','CNK','CPF','CRC'],
['2002','BSL','BTF','BTZ','BVW','BWT','BXP','BYP','BZF','BZV','CBP','CCH','CDC'],
['2001','BFJ','BGF','BHG','BJC','BKB','BLC','BMF','BMW','BNL','BPG','BRB','BRT'],
['2000','---','---','---','---','---','---','---','---','BBJ','BCD','BCY','BDR']
];
$minYear = null;
$minKey = null;
$minDiff = strToInt('ZZZ');
$searchInt = strToInt($searchStr);
for ($i = 0; $i < count($plates); $i++) {
for ($j = 1; $j < 13; $j++) {
if(abs($searchInt - strToInt($plates[$i][$j])) < $minDiff) {
$minDiff = abs($searchInt - strToInt($plates[$i][$j]));
$minYear = $plates[$i][0];
$minKey = $plates[$i][$j];
}
}
}
return [$minYear, $minKey];
}
print_r(find('KHW'));
The code down below is by no means optimized, but it's rather a concept of how you might solve your problem.
//Flatten out array (one dimension without years and ----)
$flatten = array();
foreach($plates as $platevalues) {
foreach($platevalues as $pv) {
if ($pv != '---' && $pv != '----' && intval($pv) == 0) {
//Create a string only if valid letters included in the $letters-array
//This string is then added to the new array that is flattened out
$pv2 = '';
for($i=0;$i<strlen($pv);$i++) {
$letter = substr($pv,$i,1);
if (in_array($letter, $letters) !== false) {
$pv2 .= $letter;
}
}
$flatten[] = $pv2;
}
}
}
//Do the search
$search = 'GWN';
$search_result = '';
//Create a new search string based on first found in flattened
//plates array (first G, then GW, then GWN)
for($i=0;$i<strlen($search);$i++) {
foreach($flatten as $key=>$f) {
if (substr($search,0,$i+1) == substr($f,0,$i+1)) {
$search_result .= substr($search,$i,1);
break;
}
}
}
/*
$search_result is: GW
*/
//Create a new array where all items that begins with GW are included
$result = [];
foreach($flatten as $key=>$item) {
if (substr($search_result,0,strlen($search_result)) ==
substr($item,0,strlen($search_result))) {
$result[] = $item;
}
}
/*
$result =
array (size=2)
0 => string 'GWC' (length=3)
1 => string 'GWV' (length=3)
*/
//Create an array with total ASCII-value for each item
//in the $result array above
$result_o = [];
foreach($result as $item) {
$o = 0;
for($i=0;$i<strlen($item);$i++) {
$o += ord(substr($item,$i,1));
}
$result_o[]= $o;
}
/*
$result_o =
array (size=2)
0 => int 225
1 => int 244
*/
//Get the total ASCII-value for the original search string
$search_o = 0;
for($i=0;$i<strlen($search);$i++) {
$search_o += ord(substr($search,$i,1));
}
/*
$search_ o = 236
*/
//Find closest value in the $result_o (ASCII) - array compared (225,244)
//to the original $search_o ASCII value above (236)
$closest = 0;
$use_key = 0;
foreach($result_o as $key=>$item) {
if ($closest == 0 || abs($search_o - $closest) > abs($item - $search_o)) {
$closest = $item;
$use_key = $key;
}
}
/*
$closest = 244 (it's closer to 236 than 225 is)
$use_key = 1
*/
To get the result you have:
/*
$result =
array (size=2)
0 => string 'GWC' (length=3)
1 => string 'GWV' (length=3)
*/
//This should print out GWV
echo 'result=' . $result[$use_key];

Get lowest price on sum of combinations in given array

This code is working fine when the array length is 8 or 10 only. When we are checking this same code for more than 10 array length.it get loading not showing the results.
How do reduce my code. If you have algorithm please share. Please help me.
This program working flow:
$allowed_per_room_accommodation =[2,3,6,5,3,5,2,5,4];
$allowed_per_room_price =[10,30,60,40,30,50,20,60,80];
$search_accommodation = 10;
i am get subsets = [5,5],[5,3,2],[6,4],[6,2,2],[5,2,3],[3,2,5]
Show lowest price room and then equal of 10 accommodation; output like as [5,3,2];
<?php
$dp=array(array());
$GLOBALS['final']=[];
$GLOBALS['room_key']=[];
function display($v,$room_key)
{
$GLOBALS['final'][] = $v;
$GLOBALS['room_key'][] = $room_key;
}
function printSubsetsRec($arr, $i, $sum, $p,$dp,$room_key='')
{
// If we reached end and sum is non-zero. We print
// p[] only if arr[0] is equal to sun OR dp[0][sum]
// is true.
if ($i == 0 && $sum != 0 && $dp[0][$sum]) {
array_push($p,$arr[$i]);
array_push($room_key,$i);
display($p,$room_key);
return $p;
}
// If $sum becomes 0
if ($i == 0 && $sum == 0) {
display($p,$room_key);
return $p;
}
// If given sum can be achieved after ignoring
// current element.
if (isset($dp[$i-1][$sum])) {
// Create a new vector to store path
// if(!is_array(#$b))
// $b = array();
$b = $p;
printSubsetsRec($arr, $i-1, $sum, $b,$dp,$room_key);
}
// If given $sum can be achieved after considering
// current element.
if ($sum >= $arr[$i] && isset($dp[$i-1][$sum-$arr[$i]]))
{
if(!is_array($p))
$p = array();
if(!is_array($room_key))
$room_key = array();
array_push($p,$arr[$i]);
array_push($room_key,$i);
printSubsetsRec($arr, $i-1, $sum-$arr[$i], $p,$dp,$room_key);
}
}
// Prints all subsets of arr[0..n-1] with sum 0.
function printAllSubsets($arr, $n, $sum,$get=[])
{
if ($n == 0 || $sum < 0)
return;
// Sum 0 can always be achieved with 0 elements
// $dp = new bool*[$n];
$dp = array();
for ($i=0; $i<$n; ++$i)
{
// $dp[$i][$sum + 1]=true;
$dp[$i][0] = true;
}
// Sum arr[0] can be achieved with single element
if ($arr[0] <= $sum)
$dp[0][$arr[0]] = true;
// Fill rest of the entries in dp[][]
for ($i = 1; $i < $n; ++$i) {
for ($j = 0; $j < $sum + 1; ++$j) {
// echo $i.'d'.$j.'.ds';
$dp[$i][$j] = ($arr[$i] <= $j) ? (isset($dp[$i-1][$j])?$dp[$i-1][$j]:false) | (isset($dp[$i-1][$j-$arr[$i]])?($dp[$i-1][$j-$arr[$i]]):false) : (isset($dp[$i - 1][$j])?($dp[$i - 1][$j]):false);
}
}
if (isset($dp[$n-1][$sum]) == false) {
return "There are no subsets with";
}
$p;
printSubsetsRec($arr, $n-1, $sum, $p='',$dp);
}
$blockSize = array('2','3','6','5','3','5','2','5','4');
$blockvalue = array('10','30','60','40','30','50','20','60','80');
$blockname = array("map","compass","water","sandwich","glucose","tin","banana","apple","cheese");
$processSize = 10;
$m = count($blockSize);
$n = count($processSize);
// sum of sets in array
printAllSubsets($blockSize, $m, $processSize);
$final_subset_room = '';
$final_set_room_keys = '';
$final_set_room =[];
if($GLOBALS['room_key']){
foreach ($GLOBALS['room_key'] as $set_rooms_key => $set_rooms) {
$tot = 0;
foreach ($set_rooms as $set_rooms) {
$tot += $blockvalue[$set_rooms];
}
$final_set_room[$set_rooms_key] = $tot;
}
asort($final_set_room);
$final_set_room_first_key = key($final_set_room);
$final_all_room['set_room_keys'] = $GLOBALS['room_key'][$final_set_room_first_key];
$final_all_room_price['set_room_price'] = $final_set_room[$final_set_room_first_key];
}
if(isset($final_all_room_price)){
asort($final_all_room_price);
$final_all_room_first_key = key($final_all_room_price);
foreach ($final_all_room['set_room_keys'] as $key_room) {
echo $blockname[$key_room].'---'. $blockvalue[$key_room];
echo '<br>';
}
}
else
echo 'No Results';
?>
I'm assuming your task is, given a list rooms, each with the amount of people it can accommodate and the price, to accommodate 10 people (or any other quantity).
This problem is similar to 0-1 knapsack problem which is solvable in polynomial time. In knapsack problem one aims to maximize the price, here we aim to minimize it. Another thing that is different from classic knapsack problem is that full room cost is charged even if the room is not completely occupied. It may reduce the effectiveness of the algorithm proposed at Wikipedia. Anyway, the implementation isn't going to be straightforward if you have never worked with dynamic programming before.
If you want to know more, CLRS book on algorithms discusses dynamic programming in Chapter 15, and knapsack problem in Chapter 16. In the latter chapter they also prove that 0-1 knapsack problem doesn't have trivial greedy solution.

PHP Generate random number without repetition without loop for mt_rand and without using range() and shuffle()

I am looking for a way to generate a specific quantity of unique random numbers (say 10,000), within a specific range of numbers like (000000000,999999999).
I'd like to do this without repeatedly using rand() or mt_rand() under a for loop as this would be computationally inefficient.
Are there any PHP libraries, or solutions which meets these requirements?
One method is to use a Format Preserving Encryption, with the output limited to the range 0 to 999999999. If you encrypt the numbers 0 to 9,999 you will get 10,000 unique outputs in the required range. With an encryption, unique inputs guarantee unique outputs as long as you don't change the key.
1) Create a class that keeps state of generation:
class Randomizer {
private $min;
private $max;
private $maxGeneration;
public function __construct($min = 0, $max = 100) {
if ($min >= $max) {
throw new Exception('Minimal value is more than or equal to Max value');
}
if ($max - $min < 3) {
throw new Exception('Nothing to randomize');
}
$this->min = $min;
$this->max = $max;
$this->maxGeneration = $max - $min - 1;
}
public function pick($quantity = 1) {
$count = 0;
$generated = [];
while($count < $quantity) {
$num = $this->generate();
if (sizeof($generated) === $this->maxGeneration) {
break;
}
if (!in_array($num, $generated)) {
$generated[] = $num;
$count++;
}
}
return ($quantity === 1) ? $generated[0] : $generated;
}
public function generate() {
return mt_rand($this->min, $this->max);
}
}
2) Use it:
$randomizer = new Randomizer(0, 999999999);
$number = $randomizer->pick(); // returns 1 number
$numbers = $randomizer->pick(100); // returns array(A, B, C...) of numbers

PHP: coin change puzzle

I'm working on Advent of Code as a way to practice TDD and learn PHPSpec. I'm stuck on Day 17, which is essentially the coin change puzzle.
The elves bought too much eggnog again - 150 liters this time. To fit it all into your refrigerator, you'll need to move it into smaller containers. You take an inventory of the capacities of the available containers.
For example, suppose you have containers of size 20, 15, 10, 5, and 5 liters. If you need to store 25 liters, there are four ways to do it:
15 and 10
20 and 5 (the first 5)
20 and 5 (the second 5)
15, 5, and 5
Filling all containers entirely, how many different combinations of containers can exactly fit all 150 liters of eggnog?
Here's my code. I wrote a test using the examples above. The combinations method should return 4 per the example, but it returns 3. It doesn't seem to be able to handle the fact that there's more than one container of size 5 litres.
Any suggestions please?
<?php
namespace Day17;
class Calculator
{
private $containers = [];
public function combinations($total, array $containers)
{
$combinations = $this->iterate($total, $containers);
return count($combinations);
}
/**
* http://stackoverflow.com/questions/12837431/find-combinations-sum-of-elements-in-array-whose-sum-equal-to-a-given-number
*
* #param $array
* #param array $combinations
* #param array $temp
* #return array
*/
private function iterate($sum, $array, $combinations = [], $temp = [])
{
if (count($temp) && !in_array($temp, $combinations)) {
$combinations[] = $temp;
}
$count = count($array);
for ($i = 0; $i < $count; $i++) {
$copy = $array;
$elem = array_splice($copy, $i, 1);
if (count($copy) > 0) {
$add = array_merge($temp, array($elem[0]));
sort($add);
$combinations = $this->iterate($sum, $copy, $combinations, $add);
} else {
$add = array_merge($temp, array($elem[0]));
sort($add);
if (array_sum($combinations) == $sum) {
$combinations[] = $add;
}
}
}
return array_filter($combinations, function ($combination) use ($sum) {
return array_sum($combination) == $sum;
});
}
}
Use the Array Indices of the Available Containers as the combination values.

Categories