PHP - Packing widgets into the fewest number of boxes, plus minimum order quantityWhat is the most memory...
Calculus Optimization - Point on graph closest to given point
least quadratic residue under GRH: an EXPLICIT bound
Is it possible to make sharp wind that can cut stuff from afar?
How can bays and straits be determined in a procedurally generated map?
Concept of linear mappings are confusing me
Could a US political party gain complete control over the government by removing checks & balances?
What Brexit solution does the DUP want?
XeLaTeX and pdfLaTeX ignore hyphenation
Copycat chess is back
What do you call something that goes against the spirit of the law, but is legal when interpreting the law to the letter?
Non-Jewish family in an Orthodox Jewish Wedding
What does "enim et" mean?
How do we improve the relationship with a client software team that performs poorly and is becoming less collaborative?
"which" command doesn't work / path of Safari?
What typically incentivizes a professor to change jobs to a lower ranking university?
Draw simple lines in Inkscape
New order #4: World
Japan - Any leeway for max visa duration due to unforeseen circumstances?
Is there a minimum number of transactions in a block?
Is there really no realistic way for a skeleton monster to move around without magic?
How is the relation "the smallest element is the same" reflexive?
Extreme, but not acceptable situation and I can't start the work tomorrow morning
Why has Russell's definition of numbers using equivalence classes been finally abandoned? ( If it has actually been abandoned).
Why don't electron-positron collisions release infinite energy?
PHP - Packing widgets into the fewest number of boxes, plus minimum order quantity
What is the most memory efficient way to load big arrays into PHP script?Finding the minimum number of required deletions to have a non-repeating stringFind the minimum number of operations to convert 1 into n, and print the sequence of numbersFinding the minimum number of swaps to sort a listPlace arithmetic signs in correct order to get the numberPHP code to insert phone number and IP address into a table if not already present
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}
$begingroup$
The problem is this:
A company supplies widgets in a set of pack sizes:
- 250
- 500
- 1000
- 2000
- 5000
Customers can order any number of widgets, but the following rules apply:
- Only whole packs can be sent and …
- No more widgets than necessary should be sent and …
- The fewest packs possible should be sent
Some examples showing the number of widgets ordered and the required pack quantities and sizes to correctly fulfill the order:
- 1 (1 x 250)
- 251 (1 x 500)
- 501 (1 x 500 and 1 x 250)
- 12001 (2 x 5000 and 1 x 2000 and 1 x 250)
I’ve looked at some algorithms (greedy coin change, LAFF, etc.) as these seem to provide similar solutions, but can’t seem to see how to adapt them to the above.
For example:
<?php
function countWidgets($amount)
{
$packs = array(5000, 2000, 1000, 500,
250);
$packCounter = array(0, 0, 0, 0, 0);
$packsCount = count($packs);
// loop packs
for ($i = 0; $i < $packsCount; $i++)
{
if ($amount >= $packs[$i])
{
$packCounter[$i] = intval($amount /
$packs[$i]);
$amount = $amount -
$packCounter[$i] *
$packs[$i];
}
}
// if remainder
if ($amount > 0) {
// and if smallest pack size populated
if ($packCounter[4] == 1) {
// clear smallest pack size
$packCounter[4] = 0;
// increment next biggest pack size
$packCounter[3] += 1;
} else {
// increment smallest pack size
$packCounter[4] +=1;
}
}
// Print packs
echo ("Pack ->"."n");
for ($i = 0; $i < $packsCount; $i++)
{
if ($packCounter[$i] != 0)
{
echo ($packs[$i] . " : " .
$packCounter[$i] . "n");
}
}
}
$amount = 251;
countWidgets($amount);
php algorithm
New contributor
$endgroup$
add a comment |
$begingroup$
The problem is this:
A company supplies widgets in a set of pack sizes:
- 250
- 500
- 1000
- 2000
- 5000
Customers can order any number of widgets, but the following rules apply:
- Only whole packs can be sent and …
- No more widgets than necessary should be sent and …
- The fewest packs possible should be sent
Some examples showing the number of widgets ordered and the required pack quantities and sizes to correctly fulfill the order:
- 1 (1 x 250)
- 251 (1 x 500)
- 501 (1 x 500 and 1 x 250)
- 12001 (2 x 5000 and 1 x 2000 and 1 x 250)
I’ve looked at some algorithms (greedy coin change, LAFF, etc.) as these seem to provide similar solutions, but can’t seem to see how to adapt them to the above.
For example:
<?php
function countWidgets($amount)
{
$packs = array(5000, 2000, 1000, 500,
250);
$packCounter = array(0, 0, 0, 0, 0);
$packsCount = count($packs);
// loop packs
for ($i = 0; $i < $packsCount; $i++)
{
if ($amount >= $packs[$i])
{
$packCounter[$i] = intval($amount /
$packs[$i]);
$amount = $amount -
$packCounter[$i] *
$packs[$i];
}
}
// if remainder
if ($amount > 0) {
// and if smallest pack size populated
if ($packCounter[4] == 1) {
// clear smallest pack size
$packCounter[4] = 0;
// increment next biggest pack size
$packCounter[3] += 1;
} else {
// increment smallest pack size
$packCounter[4] +=1;
}
}
// Print packs
echo ("Pack ->"."n");
for ($i = 0; $i < $packsCount; $i++)
{
if ($packCounter[$i] != 0)
{
echo ($packs[$i] . " : " .
$packCounter[$i] . "n");
}
}
}
$amount = 251;
countWidgets($amount);
php algorithm
New contributor
$endgroup$
$begingroup$
I don't see what the problem is here? You start by trying the biggest pack, until there are fewer widgets left than the size of that pack. Then you move to a smaller pack, and so on, until the smallest pack. If there are some ordered widget left, after all of this, you add one smallest pack. That's it. If you can do it by hand, then you can certainly program it.
$endgroup$
– KIKO Software
Apr 2 at 11:08
$begingroup$
Can you confirm that the code is complete and that it functions correctly? If so, I recommend that you edit to add a summary of the testing (ideally as reproducible unit-test code). If it's not working, it isn't ready for review (see help center) and the question may be deleted.
$endgroup$
– Toby Speight
Apr 2 at 11:46
add a comment |
$begingroup$
The problem is this:
A company supplies widgets in a set of pack sizes:
- 250
- 500
- 1000
- 2000
- 5000
Customers can order any number of widgets, but the following rules apply:
- Only whole packs can be sent and …
- No more widgets than necessary should be sent and …
- The fewest packs possible should be sent
Some examples showing the number of widgets ordered and the required pack quantities and sizes to correctly fulfill the order:
- 1 (1 x 250)
- 251 (1 x 500)
- 501 (1 x 500 and 1 x 250)
- 12001 (2 x 5000 and 1 x 2000 and 1 x 250)
I’ve looked at some algorithms (greedy coin change, LAFF, etc.) as these seem to provide similar solutions, but can’t seem to see how to adapt them to the above.
For example:
<?php
function countWidgets($amount)
{
$packs = array(5000, 2000, 1000, 500,
250);
$packCounter = array(0, 0, 0, 0, 0);
$packsCount = count($packs);
// loop packs
for ($i = 0; $i < $packsCount; $i++)
{
if ($amount >= $packs[$i])
{
$packCounter[$i] = intval($amount /
$packs[$i]);
$amount = $amount -
$packCounter[$i] *
$packs[$i];
}
}
// if remainder
if ($amount > 0) {
// and if smallest pack size populated
if ($packCounter[4] == 1) {
// clear smallest pack size
$packCounter[4] = 0;
// increment next biggest pack size
$packCounter[3] += 1;
} else {
// increment smallest pack size
$packCounter[4] +=1;
}
}
// Print packs
echo ("Pack ->"."n");
for ($i = 0; $i < $packsCount; $i++)
{
if ($packCounter[$i] != 0)
{
echo ($packs[$i] . " : " .
$packCounter[$i] . "n");
}
}
}
$amount = 251;
countWidgets($amount);
php algorithm
New contributor
$endgroup$
The problem is this:
A company supplies widgets in a set of pack sizes:
- 250
- 500
- 1000
- 2000
- 5000
Customers can order any number of widgets, but the following rules apply:
- Only whole packs can be sent and …
- No more widgets than necessary should be sent and …
- The fewest packs possible should be sent
Some examples showing the number of widgets ordered and the required pack quantities and sizes to correctly fulfill the order:
- 1 (1 x 250)
- 251 (1 x 500)
- 501 (1 x 500 and 1 x 250)
- 12001 (2 x 5000 and 1 x 2000 and 1 x 250)
I’ve looked at some algorithms (greedy coin change, LAFF, etc.) as these seem to provide similar solutions, but can’t seem to see how to adapt them to the above.
For example:
<?php
function countWidgets($amount)
{
$packs = array(5000, 2000, 1000, 500,
250);
$packCounter = array(0, 0, 0, 0, 0);
$packsCount = count($packs);
// loop packs
for ($i = 0; $i < $packsCount; $i++)
{
if ($amount >= $packs[$i])
{
$packCounter[$i] = intval($amount /
$packs[$i]);
$amount = $amount -
$packCounter[$i] *
$packs[$i];
}
}
// if remainder
if ($amount > 0) {
// and if smallest pack size populated
if ($packCounter[4] == 1) {
// clear smallest pack size
$packCounter[4] = 0;
// increment next biggest pack size
$packCounter[3] += 1;
} else {
// increment smallest pack size
$packCounter[4] +=1;
}
}
// Print packs
echo ("Pack ->"."n");
for ($i = 0; $i < $packsCount; $i++)
{
if ($packCounter[$i] != 0)
{
echo ($packs[$i] . " : " .
$packCounter[$i] . "n");
}
}
}
$amount = 251;
countWidgets($amount);
php algorithm
php algorithm
New contributor
New contributor
edited Apr 2 at 13:39
Matthew French
New contributor
asked Apr 2 at 8:08
Matthew FrenchMatthew French
113
113
New contributor
New contributor
$begingroup$
I don't see what the problem is here? You start by trying the biggest pack, until there are fewer widgets left than the size of that pack. Then you move to a smaller pack, and so on, until the smallest pack. If there are some ordered widget left, after all of this, you add one smallest pack. That's it. If you can do it by hand, then you can certainly program it.
$endgroup$
– KIKO Software
Apr 2 at 11:08
$begingroup$
Can you confirm that the code is complete and that it functions correctly? If so, I recommend that you edit to add a summary of the testing (ideally as reproducible unit-test code). If it's not working, it isn't ready for review (see help center) and the question may be deleted.
$endgroup$
– Toby Speight
Apr 2 at 11:46
add a comment |
$begingroup$
I don't see what the problem is here? You start by trying the biggest pack, until there are fewer widgets left than the size of that pack. Then you move to a smaller pack, and so on, until the smallest pack. If there are some ordered widget left, after all of this, you add one smallest pack. That's it. If you can do it by hand, then you can certainly program it.
$endgroup$
– KIKO Software
Apr 2 at 11:08
$begingroup$
Can you confirm that the code is complete and that it functions correctly? If so, I recommend that you edit to add a summary of the testing (ideally as reproducible unit-test code). If it's not working, it isn't ready for review (see help center) and the question may be deleted.
$endgroup$
– Toby Speight
Apr 2 at 11:46
$begingroup$
I don't see what the problem is here? You start by trying the biggest pack, until there are fewer widgets left than the size of that pack. Then you move to a smaller pack, and so on, until the smallest pack. If there are some ordered widget left, after all of this, you add one smallest pack. That's it. If you can do it by hand, then you can certainly program it.
$endgroup$
– KIKO Software
Apr 2 at 11:08
$begingroup$
I don't see what the problem is here? You start by trying the biggest pack, until there are fewer widgets left than the size of that pack. Then you move to a smaller pack, and so on, until the smallest pack. If there are some ordered widget left, after all of this, you add one smallest pack. That's it. If you can do it by hand, then you can certainly program it.
$endgroup$
– KIKO Software
Apr 2 at 11:08
$begingroup$
Can you confirm that the code is complete and that it functions correctly? If so, I recommend that you edit to add a summary of the testing (ideally as reproducible unit-test code). If it's not working, it isn't ready for review (see help center) and the question may be deleted.
$endgroup$
– Toby Speight
Apr 2 at 11:46
$begingroup$
Can you confirm that the code is complete and that it functions correctly? If so, I recommend that you edit to add a summary of the testing (ideally as reproducible unit-test code). If it's not working, it isn't ready for review (see help center) and the question may be deleted.
$endgroup$
– Toby Speight
Apr 2 at 11:46
add a comment |
2 Answers
2
active
oldest
votes
$begingroup$
OK, I agree that this is a bit harder than I assumed yesterday. You basically have two opposing demands:
- No more widgets than necessary should be sent.
- The fewest packs possible should be sent.
You cannot fulfill both. So if I tried to send 1200 widgets, rule 2 says I should send a pack of 2000, however, rule 1 says I should send 2 packs: one of 1000 and one of 250. Which rule should prevail?
I chose that rule 1 should prevail in the solution below. The reason is that no customer wants more widgets than absolutely necessary.
$packSizes = [ 250,
500,
1000,
2000,
5000];
function optimizePacks($packSizes,$number)
{
rsort($packSizes);
$requiredPacks = array_fill_keys($packSizes,0);
foreach ($packSizes as $size) {
$packs = floor($number/$size);
if ($packs > 0) {
$requiredPacks[$size] = $packs;
$number -= $packs*$size;
}
}
if ($number > 0) $requiredPacks[min($packSizes)]++;
return $requiredPacks;
}
$packs = optimizePacks($packSizes,6666);
print_r($packs);
This will work for any array of pack sizes and any number of widgets. The output of this code is:
Array (
[5000] => 1
[2000] => 0
[1000] => 1
[500] => 1
[250] => 1 )
Which is one pack more than rule 2 would demand (one of 5000 and two of 1000). It would, of course, be possible to let rule 2 prevail, but I cannot fulfill both rules.
$endgroup$
$begingroup$
You missed a ruleOnly whole packs can be sent
The other 2 rules do not compete, you can sendNo more widgets than necessary should be sent.
andThe fewest packs possible should be sent
For example1200
would not be more thennecessary
and the2000
unit box would befewest packs
- See theOnly whole packs
is the real competing rule (against, fewest packs) if that makes sense, well it makes sense to me. Themore then necessary
rule is actually half a rule So it can be ignored without theOnly whole packs
rule.
$endgroup$
– ArtisticPhoenix
yesterday
$begingroup$
Sending 1200 parts in a box that "can" hold 2000 is not sending more parts then necessary, it's sending the necessary parts in a bigger box. I built something like this before, I thought of the game Mancala
$endgroup$
– ArtisticPhoenix
yesterday
add a comment |
$begingroup$
Here is one using a while loop and simple subtaction:
$packSizes = [250,500,1000,2000,5000];
$number = 3000;
function optimizePacks($packSizes,$number)
{
//insure packs are in decending order
rsort($packSizes);
//create a default array
$results = array_fill_keys($packSizes, 0);
while($number > 0){
echo "---------- $number ----------n";
foreach($packSizes as $size){
if($size <= $number) break;
}
++$results[$size];
$number -= $size;
}
return $results;
}
$tests = [
1, // (1 x 250)
251, // (1 x 500)
501, // (1 x 500 and 1 x 250)
12001 // (2 x 5000 and 1 x 2000 and 1 x 250)
];
foreach($tests as $test) print_r(optimizePacks($packSizes,$test));
Output
---------- 1 ----------
Array
(
[5000] => 0
[2000] => 0
[1000] => 0
[500] => 0
[250] => 1
)
---------- 251 ----------
---------- 1 ----------
Array
(
[5000] => 0
[2000] => 0
[1000] => 0
[500] => 0
[250] => 2 //deviates from your example output (see below)
)
---------- 501 ----------
---------- 1 ----------
Array
(
[5000] => 0
[2000] => 0
[1000] => 0
[500] => 1
[250] => 1
)
---------- 12001 ----------
---------- 7001 ----------
---------- 2001 ----------
---------- 1 ----------
Array
(
[5000] => 2
[2000] => 1
[1000] => 0
[500] => 0
[250] => 1
)
Sandbox
These 2 examples are at odds with each other
251, // (1 x 500)
501, // (1 x 500 and 1 x 250)
The first one you make one incomplete 500
part box
The second one you make a 500 (complete box) and an extra 250 with one part.
So the question is, why is the first one only 1 box as it should be 250 x 2 boxes. Conversely why is the second 2 boxes when it could be 1000 x 1 boxes.
So either you fit them in the smallest box that can contain them with the extra overflowing. Or you put them in complete boxes and put the remainder in the smallest box.
UPDATE
If you want the reverse I came up with this:
$packSizes = [250,500,1000,2000,5000];
function optimizePacks($packSizes,$number)
{
//insure packs are in ascending order
sort($packSizes);
//create a default array
$results = array_fill_keys($packSizes, 0);
while($number > 0){
echo "---------- $number ----------n";
foreach($packSizes as $size){
if($size >= $number) break;
}
++$results[$size];
$number -= $size;
}
return $results;
}
$tests = [
1, // (1 x 250)
251, // (1 x 500)
501, // (1 x 500 and 1 x 250)
12001 // (2 x 5000 and 1 x 2000 and 1 x 250)
];
foreach($tests as $test) print_r(optimizePacks($packSizes,$test));
Output
---------- 1 ----------
Array
(
[250] => 1
[500] => 0
[1000] => 0
[2000] => 0
[5000] => 0
)
---------- 251 ----------
Array
(
[250] => 0
[500] => 1
[1000] => 0
[2000] => 0
[5000] => 0
)
---------- 501 ----------
Array
(
[250] => 0
[500] => 0
[1000] => 1 //deviates from your example output
[2000] => 0
[5000] => 0
)
---------- 12001 ----------
---------- 7001 ----------
---------- 2001 ----------
Array
(
[250] => 0
[500] => 0
[1000] => 0
[2000] => 0
[5000] => 3 //deviates from your example output
)
This also points out how the last example is at odds with this way. Which is to fit the most parts in the smallest size box. This may be a bigger box but it will not overflow. For example it wont pick 5000 for 1 part.
I used a pretty nice trick with the foreach in the above code, that let me simplify it greatly.
This only works if you sort it ASC, because if we don't find a box that can hold the full number, the last iteration leaves $size
at the Max value in the array (its the last one after all). Which is exactly what we want because then we subtract that from $number
and repeat the process.
However if we do find a box that can contain all the parts, we simply exit (break) the foreach loop. This will be the smallest box that can fit all the parts (naturally). And we also subtract this which will leave $number
at <= 0
and break the while loop which completes the function and returns the results.
Sandbox
If you really want them (the sizes, compare the 2 results in my examples) in the other order, we can either send them in that order and build the default first, or sort one way build the default then reverse the array (which should be faster then sort).
function optimizePacks($packSizes,$number)
{
//insure packs are in decending order
rsort($packSizes);
//create a default array (baking in the order)
$results = array_fill_keys($packSizes, 0);
//flip the order
$packSizes = array_reverse($packSizes);
while($number > 0){
Sandbox
Summery
Essentially you can't have both of these (or your mixed examples) without a whole lot of conditional statements that would violate using a dynamic array of sizes. You could do that with fixed sizes and special if conditions, for example. This is because your inconsistently applying your rules.
Hope it helps, I get some weird enjoyment out of figuring this stuff out... lol
$endgroup$
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Matthew French is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f216702%2fphp-packing-widgets-into-the-fewest-number-of-boxes-plus-minimum-order-quanti%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
OK, I agree that this is a bit harder than I assumed yesterday. You basically have two opposing demands:
- No more widgets than necessary should be sent.
- The fewest packs possible should be sent.
You cannot fulfill both. So if I tried to send 1200 widgets, rule 2 says I should send a pack of 2000, however, rule 1 says I should send 2 packs: one of 1000 and one of 250. Which rule should prevail?
I chose that rule 1 should prevail in the solution below. The reason is that no customer wants more widgets than absolutely necessary.
$packSizes = [ 250,
500,
1000,
2000,
5000];
function optimizePacks($packSizes,$number)
{
rsort($packSizes);
$requiredPacks = array_fill_keys($packSizes,0);
foreach ($packSizes as $size) {
$packs = floor($number/$size);
if ($packs > 0) {
$requiredPacks[$size] = $packs;
$number -= $packs*$size;
}
}
if ($number > 0) $requiredPacks[min($packSizes)]++;
return $requiredPacks;
}
$packs = optimizePacks($packSizes,6666);
print_r($packs);
This will work for any array of pack sizes and any number of widgets. The output of this code is:
Array (
[5000] => 1
[2000] => 0
[1000] => 1
[500] => 1
[250] => 1 )
Which is one pack more than rule 2 would demand (one of 5000 and two of 1000). It would, of course, be possible to let rule 2 prevail, but I cannot fulfill both rules.
$endgroup$
$begingroup$
You missed a ruleOnly whole packs can be sent
The other 2 rules do not compete, you can sendNo more widgets than necessary should be sent.
andThe fewest packs possible should be sent
For example1200
would not be more thennecessary
and the2000
unit box would befewest packs
- See theOnly whole packs
is the real competing rule (against, fewest packs) if that makes sense, well it makes sense to me. Themore then necessary
rule is actually half a rule So it can be ignored without theOnly whole packs
rule.
$endgroup$
– ArtisticPhoenix
yesterday
$begingroup$
Sending 1200 parts in a box that "can" hold 2000 is not sending more parts then necessary, it's sending the necessary parts in a bigger box. I built something like this before, I thought of the game Mancala
$endgroup$
– ArtisticPhoenix
yesterday
add a comment |
$begingroup$
OK, I agree that this is a bit harder than I assumed yesterday. You basically have two opposing demands:
- No more widgets than necessary should be sent.
- The fewest packs possible should be sent.
You cannot fulfill both. So if I tried to send 1200 widgets, rule 2 says I should send a pack of 2000, however, rule 1 says I should send 2 packs: one of 1000 and one of 250. Which rule should prevail?
I chose that rule 1 should prevail in the solution below. The reason is that no customer wants more widgets than absolutely necessary.
$packSizes = [ 250,
500,
1000,
2000,
5000];
function optimizePacks($packSizes,$number)
{
rsort($packSizes);
$requiredPacks = array_fill_keys($packSizes,0);
foreach ($packSizes as $size) {
$packs = floor($number/$size);
if ($packs > 0) {
$requiredPacks[$size] = $packs;
$number -= $packs*$size;
}
}
if ($number > 0) $requiredPacks[min($packSizes)]++;
return $requiredPacks;
}
$packs = optimizePacks($packSizes,6666);
print_r($packs);
This will work for any array of pack sizes and any number of widgets. The output of this code is:
Array (
[5000] => 1
[2000] => 0
[1000] => 1
[500] => 1
[250] => 1 )
Which is one pack more than rule 2 would demand (one of 5000 and two of 1000). It would, of course, be possible to let rule 2 prevail, but I cannot fulfill both rules.
$endgroup$
$begingroup$
You missed a ruleOnly whole packs can be sent
The other 2 rules do not compete, you can sendNo more widgets than necessary should be sent.
andThe fewest packs possible should be sent
For example1200
would not be more thennecessary
and the2000
unit box would befewest packs
- See theOnly whole packs
is the real competing rule (against, fewest packs) if that makes sense, well it makes sense to me. Themore then necessary
rule is actually half a rule So it can be ignored without theOnly whole packs
rule.
$endgroup$
– ArtisticPhoenix
yesterday
$begingroup$
Sending 1200 parts in a box that "can" hold 2000 is not sending more parts then necessary, it's sending the necessary parts in a bigger box. I built something like this before, I thought of the game Mancala
$endgroup$
– ArtisticPhoenix
yesterday
add a comment |
$begingroup$
OK, I agree that this is a bit harder than I assumed yesterday. You basically have two opposing demands:
- No more widgets than necessary should be sent.
- The fewest packs possible should be sent.
You cannot fulfill both. So if I tried to send 1200 widgets, rule 2 says I should send a pack of 2000, however, rule 1 says I should send 2 packs: one of 1000 and one of 250. Which rule should prevail?
I chose that rule 1 should prevail in the solution below. The reason is that no customer wants more widgets than absolutely necessary.
$packSizes = [ 250,
500,
1000,
2000,
5000];
function optimizePacks($packSizes,$number)
{
rsort($packSizes);
$requiredPacks = array_fill_keys($packSizes,0);
foreach ($packSizes as $size) {
$packs = floor($number/$size);
if ($packs > 0) {
$requiredPacks[$size] = $packs;
$number -= $packs*$size;
}
}
if ($number > 0) $requiredPacks[min($packSizes)]++;
return $requiredPacks;
}
$packs = optimizePacks($packSizes,6666);
print_r($packs);
This will work for any array of pack sizes and any number of widgets. The output of this code is:
Array (
[5000] => 1
[2000] => 0
[1000] => 1
[500] => 1
[250] => 1 )
Which is one pack more than rule 2 would demand (one of 5000 and two of 1000). It would, of course, be possible to let rule 2 prevail, but I cannot fulfill both rules.
$endgroup$
OK, I agree that this is a bit harder than I assumed yesterday. You basically have two opposing demands:
- No more widgets than necessary should be sent.
- The fewest packs possible should be sent.
You cannot fulfill both. So if I tried to send 1200 widgets, rule 2 says I should send a pack of 2000, however, rule 1 says I should send 2 packs: one of 1000 and one of 250. Which rule should prevail?
I chose that rule 1 should prevail in the solution below. The reason is that no customer wants more widgets than absolutely necessary.
$packSizes = [ 250,
500,
1000,
2000,
5000];
function optimizePacks($packSizes,$number)
{
rsort($packSizes);
$requiredPacks = array_fill_keys($packSizes,0);
foreach ($packSizes as $size) {
$packs = floor($number/$size);
if ($packs > 0) {
$requiredPacks[$size] = $packs;
$number -= $packs*$size;
}
}
if ($number > 0) $requiredPacks[min($packSizes)]++;
return $requiredPacks;
}
$packs = optimizePacks($packSizes,6666);
print_r($packs);
This will work for any array of pack sizes and any number of widgets. The output of this code is:
Array (
[5000] => 1
[2000] => 0
[1000] => 1
[500] => 1
[250] => 1 )
Which is one pack more than rule 2 would demand (one of 5000 and two of 1000). It would, of course, be possible to let rule 2 prevail, but I cannot fulfill both rules.
edited Apr 3 at 15:33
answered Apr 3 at 14:56
KIKO SoftwareKIKO Software
1,609512
1,609512
$begingroup$
You missed a ruleOnly whole packs can be sent
The other 2 rules do not compete, you can sendNo more widgets than necessary should be sent.
andThe fewest packs possible should be sent
For example1200
would not be more thennecessary
and the2000
unit box would befewest packs
- See theOnly whole packs
is the real competing rule (against, fewest packs) if that makes sense, well it makes sense to me. Themore then necessary
rule is actually half a rule So it can be ignored without theOnly whole packs
rule.
$endgroup$
– ArtisticPhoenix
yesterday
$begingroup$
Sending 1200 parts in a box that "can" hold 2000 is not sending more parts then necessary, it's sending the necessary parts in a bigger box. I built something like this before, I thought of the game Mancala
$endgroup$
– ArtisticPhoenix
yesterday
add a comment |
$begingroup$
You missed a ruleOnly whole packs can be sent
The other 2 rules do not compete, you can sendNo more widgets than necessary should be sent.
andThe fewest packs possible should be sent
For example1200
would not be more thennecessary
and the2000
unit box would befewest packs
- See theOnly whole packs
is the real competing rule (against, fewest packs) if that makes sense, well it makes sense to me. Themore then necessary
rule is actually half a rule So it can be ignored without theOnly whole packs
rule.
$endgroup$
– ArtisticPhoenix
yesterday
$begingroup$
Sending 1200 parts in a box that "can" hold 2000 is not sending more parts then necessary, it's sending the necessary parts in a bigger box. I built something like this before, I thought of the game Mancala
$endgroup$
– ArtisticPhoenix
yesterday
$begingroup$
You missed a rule
Only whole packs can be sent
The other 2 rules do not compete, you can send No more widgets than necessary should be sent.
and The fewest packs possible should be sent
For example 1200
would not be more then necessary
and the 2000
unit box would be fewest packs
- See the Only whole packs
is the real competing rule (against, fewest packs) if that makes sense, well it makes sense to me. The more then necessary
rule is actually half a rule So it can be ignored without the Only whole packs
rule.$endgroup$
– ArtisticPhoenix
yesterday
$begingroup$
You missed a rule
Only whole packs can be sent
The other 2 rules do not compete, you can send No more widgets than necessary should be sent.
and The fewest packs possible should be sent
For example 1200
would not be more then necessary
and the 2000
unit box would be fewest packs
- See the Only whole packs
is the real competing rule (against, fewest packs) if that makes sense, well it makes sense to me. The more then necessary
rule is actually half a rule So it can be ignored without the Only whole packs
rule.$endgroup$
– ArtisticPhoenix
yesterday
$begingroup$
Sending 1200 parts in a box that "can" hold 2000 is not sending more parts then necessary, it's sending the necessary parts in a bigger box. I built something like this before, I thought of the game Mancala
$endgroup$
– ArtisticPhoenix
yesterday
$begingroup$
Sending 1200 parts in a box that "can" hold 2000 is not sending more parts then necessary, it's sending the necessary parts in a bigger box. I built something like this before, I thought of the game Mancala
$endgroup$
– ArtisticPhoenix
yesterday
add a comment |
$begingroup$
Here is one using a while loop and simple subtaction:
$packSizes = [250,500,1000,2000,5000];
$number = 3000;
function optimizePacks($packSizes,$number)
{
//insure packs are in decending order
rsort($packSizes);
//create a default array
$results = array_fill_keys($packSizes, 0);
while($number > 0){
echo "---------- $number ----------n";
foreach($packSizes as $size){
if($size <= $number) break;
}
++$results[$size];
$number -= $size;
}
return $results;
}
$tests = [
1, // (1 x 250)
251, // (1 x 500)
501, // (1 x 500 and 1 x 250)
12001 // (2 x 5000 and 1 x 2000 and 1 x 250)
];
foreach($tests as $test) print_r(optimizePacks($packSizes,$test));
Output
---------- 1 ----------
Array
(
[5000] => 0
[2000] => 0
[1000] => 0
[500] => 0
[250] => 1
)
---------- 251 ----------
---------- 1 ----------
Array
(
[5000] => 0
[2000] => 0
[1000] => 0
[500] => 0
[250] => 2 //deviates from your example output (see below)
)
---------- 501 ----------
---------- 1 ----------
Array
(
[5000] => 0
[2000] => 0
[1000] => 0
[500] => 1
[250] => 1
)
---------- 12001 ----------
---------- 7001 ----------
---------- 2001 ----------
---------- 1 ----------
Array
(
[5000] => 2
[2000] => 1
[1000] => 0
[500] => 0
[250] => 1
)
Sandbox
These 2 examples are at odds with each other
251, // (1 x 500)
501, // (1 x 500 and 1 x 250)
The first one you make one incomplete 500
part box
The second one you make a 500 (complete box) and an extra 250 with one part.
So the question is, why is the first one only 1 box as it should be 250 x 2 boxes. Conversely why is the second 2 boxes when it could be 1000 x 1 boxes.
So either you fit them in the smallest box that can contain them with the extra overflowing. Or you put them in complete boxes and put the remainder in the smallest box.
UPDATE
If you want the reverse I came up with this:
$packSizes = [250,500,1000,2000,5000];
function optimizePacks($packSizes,$number)
{
//insure packs are in ascending order
sort($packSizes);
//create a default array
$results = array_fill_keys($packSizes, 0);
while($number > 0){
echo "---------- $number ----------n";
foreach($packSizes as $size){
if($size >= $number) break;
}
++$results[$size];
$number -= $size;
}
return $results;
}
$tests = [
1, // (1 x 250)
251, // (1 x 500)
501, // (1 x 500 and 1 x 250)
12001 // (2 x 5000 and 1 x 2000 and 1 x 250)
];
foreach($tests as $test) print_r(optimizePacks($packSizes,$test));
Output
---------- 1 ----------
Array
(
[250] => 1
[500] => 0
[1000] => 0
[2000] => 0
[5000] => 0
)
---------- 251 ----------
Array
(
[250] => 0
[500] => 1
[1000] => 0
[2000] => 0
[5000] => 0
)
---------- 501 ----------
Array
(
[250] => 0
[500] => 0
[1000] => 1 //deviates from your example output
[2000] => 0
[5000] => 0
)
---------- 12001 ----------
---------- 7001 ----------
---------- 2001 ----------
Array
(
[250] => 0
[500] => 0
[1000] => 0
[2000] => 0
[5000] => 3 //deviates from your example output
)
This also points out how the last example is at odds with this way. Which is to fit the most parts in the smallest size box. This may be a bigger box but it will not overflow. For example it wont pick 5000 for 1 part.
I used a pretty nice trick with the foreach in the above code, that let me simplify it greatly.
This only works if you sort it ASC, because if we don't find a box that can hold the full number, the last iteration leaves $size
at the Max value in the array (its the last one after all). Which is exactly what we want because then we subtract that from $number
and repeat the process.
However if we do find a box that can contain all the parts, we simply exit (break) the foreach loop. This will be the smallest box that can fit all the parts (naturally). And we also subtract this which will leave $number
at <= 0
and break the while loop which completes the function and returns the results.
Sandbox
If you really want them (the sizes, compare the 2 results in my examples) in the other order, we can either send them in that order and build the default first, or sort one way build the default then reverse the array (which should be faster then sort).
function optimizePacks($packSizes,$number)
{
//insure packs are in decending order
rsort($packSizes);
//create a default array (baking in the order)
$results = array_fill_keys($packSizes, 0);
//flip the order
$packSizes = array_reverse($packSizes);
while($number > 0){
Sandbox
Summery
Essentially you can't have both of these (or your mixed examples) without a whole lot of conditional statements that would violate using a dynamic array of sizes. You could do that with fixed sizes and special if conditions, for example. This is because your inconsistently applying your rules.
Hope it helps, I get some weird enjoyment out of figuring this stuff out... lol
$endgroup$
add a comment |
$begingroup$
Here is one using a while loop and simple subtaction:
$packSizes = [250,500,1000,2000,5000];
$number = 3000;
function optimizePacks($packSizes,$number)
{
//insure packs are in decending order
rsort($packSizes);
//create a default array
$results = array_fill_keys($packSizes, 0);
while($number > 0){
echo "---------- $number ----------n";
foreach($packSizes as $size){
if($size <= $number) break;
}
++$results[$size];
$number -= $size;
}
return $results;
}
$tests = [
1, // (1 x 250)
251, // (1 x 500)
501, // (1 x 500 and 1 x 250)
12001 // (2 x 5000 and 1 x 2000 and 1 x 250)
];
foreach($tests as $test) print_r(optimizePacks($packSizes,$test));
Output
---------- 1 ----------
Array
(
[5000] => 0
[2000] => 0
[1000] => 0
[500] => 0
[250] => 1
)
---------- 251 ----------
---------- 1 ----------
Array
(
[5000] => 0
[2000] => 0
[1000] => 0
[500] => 0
[250] => 2 //deviates from your example output (see below)
)
---------- 501 ----------
---------- 1 ----------
Array
(
[5000] => 0
[2000] => 0
[1000] => 0
[500] => 1
[250] => 1
)
---------- 12001 ----------
---------- 7001 ----------
---------- 2001 ----------
---------- 1 ----------
Array
(
[5000] => 2
[2000] => 1
[1000] => 0
[500] => 0
[250] => 1
)
Sandbox
These 2 examples are at odds with each other
251, // (1 x 500)
501, // (1 x 500 and 1 x 250)
The first one you make one incomplete 500
part box
The second one you make a 500 (complete box) and an extra 250 with one part.
So the question is, why is the first one only 1 box as it should be 250 x 2 boxes. Conversely why is the second 2 boxes when it could be 1000 x 1 boxes.
So either you fit them in the smallest box that can contain them with the extra overflowing. Or you put them in complete boxes and put the remainder in the smallest box.
UPDATE
If you want the reverse I came up with this:
$packSizes = [250,500,1000,2000,5000];
function optimizePacks($packSizes,$number)
{
//insure packs are in ascending order
sort($packSizes);
//create a default array
$results = array_fill_keys($packSizes, 0);
while($number > 0){
echo "---------- $number ----------n";
foreach($packSizes as $size){
if($size >= $number) break;
}
++$results[$size];
$number -= $size;
}
return $results;
}
$tests = [
1, // (1 x 250)
251, // (1 x 500)
501, // (1 x 500 and 1 x 250)
12001 // (2 x 5000 and 1 x 2000 and 1 x 250)
];
foreach($tests as $test) print_r(optimizePacks($packSizes,$test));
Output
---------- 1 ----------
Array
(
[250] => 1
[500] => 0
[1000] => 0
[2000] => 0
[5000] => 0
)
---------- 251 ----------
Array
(
[250] => 0
[500] => 1
[1000] => 0
[2000] => 0
[5000] => 0
)
---------- 501 ----------
Array
(
[250] => 0
[500] => 0
[1000] => 1 //deviates from your example output
[2000] => 0
[5000] => 0
)
---------- 12001 ----------
---------- 7001 ----------
---------- 2001 ----------
Array
(
[250] => 0
[500] => 0
[1000] => 0
[2000] => 0
[5000] => 3 //deviates from your example output
)
This also points out how the last example is at odds with this way. Which is to fit the most parts in the smallest size box. This may be a bigger box but it will not overflow. For example it wont pick 5000 for 1 part.
I used a pretty nice trick with the foreach in the above code, that let me simplify it greatly.
This only works if you sort it ASC, because if we don't find a box that can hold the full number, the last iteration leaves $size
at the Max value in the array (its the last one after all). Which is exactly what we want because then we subtract that from $number
and repeat the process.
However if we do find a box that can contain all the parts, we simply exit (break) the foreach loop. This will be the smallest box that can fit all the parts (naturally). And we also subtract this which will leave $number
at <= 0
and break the while loop which completes the function and returns the results.
Sandbox
If you really want them (the sizes, compare the 2 results in my examples) in the other order, we can either send them in that order and build the default first, or sort one way build the default then reverse the array (which should be faster then sort).
function optimizePacks($packSizes,$number)
{
//insure packs are in decending order
rsort($packSizes);
//create a default array (baking in the order)
$results = array_fill_keys($packSizes, 0);
//flip the order
$packSizes = array_reverse($packSizes);
while($number > 0){
Sandbox
Summery
Essentially you can't have both of these (or your mixed examples) without a whole lot of conditional statements that would violate using a dynamic array of sizes. You could do that with fixed sizes and special if conditions, for example. This is because your inconsistently applying your rules.
Hope it helps, I get some weird enjoyment out of figuring this stuff out... lol
$endgroup$
add a comment |
$begingroup$
Here is one using a while loop and simple subtaction:
$packSizes = [250,500,1000,2000,5000];
$number = 3000;
function optimizePacks($packSizes,$number)
{
//insure packs are in decending order
rsort($packSizes);
//create a default array
$results = array_fill_keys($packSizes, 0);
while($number > 0){
echo "---------- $number ----------n";
foreach($packSizes as $size){
if($size <= $number) break;
}
++$results[$size];
$number -= $size;
}
return $results;
}
$tests = [
1, // (1 x 250)
251, // (1 x 500)
501, // (1 x 500 and 1 x 250)
12001 // (2 x 5000 and 1 x 2000 and 1 x 250)
];
foreach($tests as $test) print_r(optimizePacks($packSizes,$test));
Output
---------- 1 ----------
Array
(
[5000] => 0
[2000] => 0
[1000] => 0
[500] => 0
[250] => 1
)
---------- 251 ----------
---------- 1 ----------
Array
(
[5000] => 0
[2000] => 0
[1000] => 0
[500] => 0
[250] => 2 //deviates from your example output (see below)
)
---------- 501 ----------
---------- 1 ----------
Array
(
[5000] => 0
[2000] => 0
[1000] => 0
[500] => 1
[250] => 1
)
---------- 12001 ----------
---------- 7001 ----------
---------- 2001 ----------
---------- 1 ----------
Array
(
[5000] => 2
[2000] => 1
[1000] => 0
[500] => 0
[250] => 1
)
Sandbox
These 2 examples are at odds with each other
251, // (1 x 500)
501, // (1 x 500 and 1 x 250)
The first one you make one incomplete 500
part box
The second one you make a 500 (complete box) and an extra 250 with one part.
So the question is, why is the first one only 1 box as it should be 250 x 2 boxes. Conversely why is the second 2 boxes when it could be 1000 x 1 boxes.
So either you fit them in the smallest box that can contain them with the extra overflowing. Or you put them in complete boxes and put the remainder in the smallest box.
UPDATE
If you want the reverse I came up with this:
$packSizes = [250,500,1000,2000,5000];
function optimizePacks($packSizes,$number)
{
//insure packs are in ascending order
sort($packSizes);
//create a default array
$results = array_fill_keys($packSizes, 0);
while($number > 0){
echo "---------- $number ----------n";
foreach($packSizes as $size){
if($size >= $number) break;
}
++$results[$size];
$number -= $size;
}
return $results;
}
$tests = [
1, // (1 x 250)
251, // (1 x 500)
501, // (1 x 500 and 1 x 250)
12001 // (2 x 5000 and 1 x 2000 and 1 x 250)
];
foreach($tests as $test) print_r(optimizePacks($packSizes,$test));
Output
---------- 1 ----------
Array
(
[250] => 1
[500] => 0
[1000] => 0
[2000] => 0
[5000] => 0
)
---------- 251 ----------
Array
(
[250] => 0
[500] => 1
[1000] => 0
[2000] => 0
[5000] => 0
)
---------- 501 ----------
Array
(
[250] => 0
[500] => 0
[1000] => 1 //deviates from your example output
[2000] => 0
[5000] => 0
)
---------- 12001 ----------
---------- 7001 ----------
---------- 2001 ----------
Array
(
[250] => 0
[500] => 0
[1000] => 0
[2000] => 0
[5000] => 3 //deviates from your example output
)
This also points out how the last example is at odds with this way. Which is to fit the most parts in the smallest size box. This may be a bigger box but it will not overflow. For example it wont pick 5000 for 1 part.
I used a pretty nice trick with the foreach in the above code, that let me simplify it greatly.
This only works if you sort it ASC, because if we don't find a box that can hold the full number, the last iteration leaves $size
at the Max value in the array (its the last one after all). Which is exactly what we want because then we subtract that from $number
and repeat the process.
However if we do find a box that can contain all the parts, we simply exit (break) the foreach loop. This will be the smallest box that can fit all the parts (naturally). And we also subtract this which will leave $number
at <= 0
and break the while loop which completes the function and returns the results.
Sandbox
If you really want them (the sizes, compare the 2 results in my examples) in the other order, we can either send them in that order and build the default first, or sort one way build the default then reverse the array (which should be faster then sort).
function optimizePacks($packSizes,$number)
{
//insure packs are in decending order
rsort($packSizes);
//create a default array (baking in the order)
$results = array_fill_keys($packSizes, 0);
//flip the order
$packSizes = array_reverse($packSizes);
while($number > 0){
Sandbox
Summery
Essentially you can't have both of these (or your mixed examples) without a whole lot of conditional statements that would violate using a dynamic array of sizes. You could do that with fixed sizes and special if conditions, for example. This is because your inconsistently applying your rules.
Hope it helps, I get some weird enjoyment out of figuring this stuff out... lol
$endgroup$
Here is one using a while loop and simple subtaction:
$packSizes = [250,500,1000,2000,5000];
$number = 3000;
function optimizePacks($packSizes,$number)
{
//insure packs are in decending order
rsort($packSizes);
//create a default array
$results = array_fill_keys($packSizes, 0);
while($number > 0){
echo "---------- $number ----------n";
foreach($packSizes as $size){
if($size <= $number) break;
}
++$results[$size];
$number -= $size;
}
return $results;
}
$tests = [
1, // (1 x 250)
251, // (1 x 500)
501, // (1 x 500 and 1 x 250)
12001 // (2 x 5000 and 1 x 2000 and 1 x 250)
];
foreach($tests as $test) print_r(optimizePacks($packSizes,$test));
Output
---------- 1 ----------
Array
(
[5000] => 0
[2000] => 0
[1000] => 0
[500] => 0
[250] => 1
)
---------- 251 ----------
---------- 1 ----------
Array
(
[5000] => 0
[2000] => 0
[1000] => 0
[500] => 0
[250] => 2 //deviates from your example output (see below)
)
---------- 501 ----------
---------- 1 ----------
Array
(
[5000] => 0
[2000] => 0
[1000] => 0
[500] => 1
[250] => 1
)
---------- 12001 ----------
---------- 7001 ----------
---------- 2001 ----------
---------- 1 ----------
Array
(
[5000] => 2
[2000] => 1
[1000] => 0
[500] => 0
[250] => 1
)
Sandbox
These 2 examples are at odds with each other
251, // (1 x 500)
501, // (1 x 500 and 1 x 250)
The first one you make one incomplete 500
part box
The second one you make a 500 (complete box) and an extra 250 with one part.
So the question is, why is the first one only 1 box as it should be 250 x 2 boxes. Conversely why is the second 2 boxes when it could be 1000 x 1 boxes.
So either you fit them in the smallest box that can contain them with the extra overflowing. Or you put them in complete boxes and put the remainder in the smallest box.
UPDATE
If you want the reverse I came up with this:
$packSizes = [250,500,1000,2000,5000];
function optimizePacks($packSizes,$number)
{
//insure packs are in ascending order
sort($packSizes);
//create a default array
$results = array_fill_keys($packSizes, 0);
while($number > 0){
echo "---------- $number ----------n";
foreach($packSizes as $size){
if($size >= $number) break;
}
++$results[$size];
$number -= $size;
}
return $results;
}
$tests = [
1, // (1 x 250)
251, // (1 x 500)
501, // (1 x 500 and 1 x 250)
12001 // (2 x 5000 and 1 x 2000 and 1 x 250)
];
foreach($tests as $test) print_r(optimizePacks($packSizes,$test));
Output
---------- 1 ----------
Array
(
[250] => 1
[500] => 0
[1000] => 0
[2000] => 0
[5000] => 0
)
---------- 251 ----------
Array
(
[250] => 0
[500] => 1
[1000] => 0
[2000] => 0
[5000] => 0
)
---------- 501 ----------
Array
(
[250] => 0
[500] => 0
[1000] => 1 //deviates from your example output
[2000] => 0
[5000] => 0
)
---------- 12001 ----------
---------- 7001 ----------
---------- 2001 ----------
Array
(
[250] => 0
[500] => 0
[1000] => 0
[2000] => 0
[5000] => 3 //deviates from your example output
)
This also points out how the last example is at odds with this way. Which is to fit the most parts in the smallest size box. This may be a bigger box but it will not overflow. For example it wont pick 5000 for 1 part.
I used a pretty nice trick with the foreach in the above code, that let me simplify it greatly.
This only works if you sort it ASC, because if we don't find a box that can hold the full number, the last iteration leaves $size
at the Max value in the array (its the last one after all). Which is exactly what we want because then we subtract that from $number
and repeat the process.
However if we do find a box that can contain all the parts, we simply exit (break) the foreach loop. This will be the smallest box that can fit all the parts (naturally). And we also subtract this which will leave $number
at <= 0
and break the while loop which completes the function and returns the results.
Sandbox
If you really want them (the sizes, compare the 2 results in my examples) in the other order, we can either send them in that order and build the default first, or sort one way build the default then reverse the array (which should be faster then sort).
function optimizePacks($packSizes,$number)
{
//insure packs are in decending order
rsort($packSizes);
//create a default array (baking in the order)
$results = array_fill_keys($packSizes, 0);
//flip the order
$packSizes = array_reverse($packSizes);
while($number > 0){
Sandbox
Summery
Essentially you can't have both of these (or your mixed examples) without a whole lot of conditional statements that would violate using a dynamic array of sizes. You could do that with fixed sizes and special if conditions, for example. This is because your inconsistently applying your rules.
Hope it helps, I get some weird enjoyment out of figuring this stuff out... lol
edited yesterday
answered yesterday
ArtisticPhoenixArtisticPhoenix
45127
45127
add a comment |
add a comment |
Matthew French is a new contributor. Be nice, and check out our Code of Conduct.
Matthew French is a new contributor. Be nice, and check out our Code of Conduct.
Matthew French is a new contributor. Be nice, and check out our Code of Conduct.
Matthew French is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f216702%2fphp-packing-widgets-into-the-fewest-number-of-boxes-plus-minimum-order-quanti%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
$begingroup$
I don't see what the problem is here? You start by trying the biggest pack, until there are fewer widgets left than the size of that pack. Then you move to a smaller pack, and so on, until the smallest pack. If there are some ordered widget left, after all of this, you add one smallest pack. That's it. If you can do it by hand, then you can certainly program it.
$endgroup$
– KIKO Software
Apr 2 at 11:08
$begingroup$
Can you confirm that the code is complete and that it functions correctly? If so, I recommend that you edit to add a summary of the testing (ideally as reproducible unit-test code). If it's not working, it isn't ready for review (see help center) and the question may be deleted.
$endgroup$
– Toby Speight
Apr 2 at 11:46