I have the following script that divides the total by the number of people and stores the results in an array.
Instead of dumping the $result array at the end, I wonder if I could echo out the value of each array item in the for loop as it goes?
// initial conditions
$total = 1001;
$people = 5;
// count what is the minimal value, that all the results will have
$value = floor($total / $people);
$result = array_fill(0, $people, $value);
// distribute missing "+1"s as needed in the result
$overheads = $total - $value * $people;
for ($i = 0; $i < $overheads; $i++) {
$result[$i]++;
}
// voila...
var_dump($result);
So, the above script should loop out:
200
200
200
200
201
Technically speaking, you can't "echo out the value of each array item
in the for loop as it goes" because you're not filling the arrays
in a loop, you're filling with array_fill(). The loop you have is to
work with the remainder. If you echo out there, you'll get partial
results. So either you keep your code and echo the values at the end,
with a simple line:
foreach ($result as $r) echo "$r\n";
Or you modify your code to fill the arrays in another manner. Which
might be interesting. Note that you're forgetting about the modulus
operator, %, for the remainder of division. This line:
$overheads = $total - $value * $people;
Could be written simply as:
$overheads = $total % $people;
An idea to fill in a loop:
// initial conditions
$total = 1001;
$people = 5;
$value = floor($total/$people);
$overheads = $total % $people;
foreach (range(1, $people) as $p) {
$r = $value;
if ($overheads) {
# if there is still remainders:
$r++;
$overheads--;
}
# echo the value and also store it
echo "$r\n";
$result[] = $r;
}
// initial conditions
$total = 1001;
$people = 5;
// count what is the minimal value, that all the results will have
$value = floor($total / $people);
$result = array_fill(0, $people, $value);
// distribute missing "+1"s as needed in the result
$overheads = $total - $value * $people;
$i = 1;
foreach($result as $res)
{
if ($i < $people){
echo $res . "\n";
}else{
echo $res + 1 . "\n";
}
$i++;
}
// voila...
Related
I am trying to make a function to display client's items in an array, however only the first item id is shown in the array. What's wrong with my code? I guess I'm doing something wrong with the array.
Example of sItem value: https://pastebin.pl/view/e492ffa1
$items = array();
$client_item = bin2hex($u->sItem);
$x = 0;
for ($i = 0; $i < 78; $i++) {
$item = hexdec(reverse(substr($client_item, $x, 8)));
if ($item != 0) {
$ii = $db->get_object("SELECT * FROM Clients.dbo.ITEM WHERE Num =" . $item);
if (is_object($ii)) {
$items[] = array("ItemID" => $ii->Num, "ItemSlot" => $i);
}
}
$x += 16;
}
The code above will show just the first item in the array. All others are not shown.
var items = [{"ItemID":310511133,"ItemSlot":0}]
I am not sure what I'm doing wrong. If I remove $x += 16; then it will simply add more entries in the array with the first item id. I want more entries but not with the same item id obviously. :)
var items = [{"ItemID":310511133,"ItemSlot":0},{"ItemID":310511133,"ItemSlot":1},{"ItemID":310511133,"ItemSlot":2},{"ItemID":310511133,"ItemSlot":3},{"ItemID":310511133,"ItemSlot":4}....
This is the reverse function:
function reverse($str)
{
$len = strlen($str);
$i = $len - 2;
$ret = NULL;
while (0 <= $i) {
$ret .= substr($str, $i, 2);
$i -= 2;
}
return $ret;
}
Database Query not returning any object SELECT * FROM Clients.dbo.ITEM WHERE Num = $item
can you confirm values exists in database
you can echo $item value and see manually in database are those values exists.
I am trying to display possibilities for additions of specific numbers but have not been getting the right results.
<?php
$num3 = 20;
$set = null;
$balance = $num3;
$dig = mt_rand(1,5);
for($i = $balance; $i > 0; $i -= $dig ){
echo $dig.'<br>';
if($i < 1){
$set .= $i;
$balance = 0;
}
else{
$set .= $dig.'+';
$dig = mt_rand(1,5);
}
}
echo $set.'='.$num3;
?>
Here are some of the outputs:
2+5+1+4+5+3+=20
1+4+3+5+3+=20
3+1+1+2+3+4+4+1+3+=20
Appreciate any pointers. Thank in advance...
Ok, even though the requirement isn't completely clear, here's an approach:
(edit: demonstrating prevention of endless loop)
$max_loops = 1000;
$balance = 20;
$found = [];
while($balance > 0 && $max_loops-- > 0) {
$r = mt_rand(1, 5);
if ($balance - $r >= 0) {
$found[] = $r;
$balance -= $r;
}
}
echo implode(' + ', $found) . ' = '.array_sum($found);
Note: This code has a small risk of getting caught in an endless loop... though it's doubtful that it'll ever happen :)
Edit: Now the loop contains a hard-limit of 1000 iterations, after which the loop will end for sure...
To provoke an endless loop, set $balance = 7 and modify mt_rand(4, 5).
You can use a recursive function for this:
function randomAddends($target, $maxAddend = 5, $sum = 0, $addends = [])
{
// Return the array of addends when the target is reached
if ($target <= $sum) {
return $addends;
}
// generate a new random addend and add it to the array
$randomAddend = mt_rand(1, min($maxAddend, $target - $sum));
$addends[] = $randomAddend;
// make the recursive call with the new sum
return randomAddends($target, $maxAddend, $sum + $randomAddend, $addends);
}
The algoritham i'm trying different combinations of values will able to give my exact or approx output sum of values
I have attached image for the detail explanation , I have created column total as sum of each row value and finally I have sum all the total value, the whole total sum value is to be my expected output value.
So I'm trying to take a combination of each row sum and like to get total sum value
My algorithm i have searched in google below
function extractList($array, &$list, $temp = array()) {
if (count($temp) > 0 && ! in_array($temp, $list))
$list[] = $temp;
for($i = 0; $i < sizeof($array); $i ++) {
$copy = $array;
$elem = array_splice($copy, $i, 1);
if (sizeof($copy) > 0) {
$add = array_merge($temp, array($elem[0]));
sort($add);
extractList($copy, $list, $add);
} else {
$add = array_merge($temp, array($elem[0]));
sort($add);
if (! in_array($temp, $list)) {
$list[] = $add;
}
}
}
}
echo "<pre>";
$sum = 32 ; //SUM
$array = array(5.14327,5.72355,5.91794,4.8209,8.69933,4.12977,4.12977,2.92791,2.36829,2.21819,1.33759,1.72278,1.72278,0.589,1.06405,0.6387,0.6387,1.68995,2.51669,3.97842,2.38058,2.17175,4.88264,5.84811,6.14215);
$list = array();
# Extract All Unique Conbinations
extractList($array, $list);
#Filter By SUM = $sum
$list = array_filter($list,function($var) use ($sum) { return(array_sum($var) == $sum);});
#Return Output
print_r($list);
Attached Image here
You need to decide how you determine approximate equality. A percentage? Or an absolute amount? That's what you need in your filter lambda function.
// outside lambda
$error = $sum * 5 / 100;// 5%, or
$error = 0.02;// an absolute
...
// inside lambda
return abs(array_sum($var) - $sum) <= $error;
Let's say I have this array
$number = [2,1,4,3,6,2];
First pair the elements on an array by two's and find their difference
so this is the output in the first requirement
$diff[] = [1,1,4];
Second sum all the difference
this is the final output
$sum[] = [6];
Conditions:
the array size is always even
the first element in a pair is always greater than the second one, so their is no negative difference
What I've done so far is just counting the size of an array then after that I don't know how to pair them by two's. T_T
Is this possible in php? Is there a built in function to do it?
One line:
$number = [2,1,4,3,6,2];
$total = array_sum(array_map(function ($array) {
return current($array) - next($array);
}, array_chunk($number, 2)));
echo $total;
This should work fine:
<?
$number = array(2,1,4,3,6,2);
for($i=0;$i<count($number); $i+=2){
$dif[] = $number[$i] - $number[$i+1];
}
print_r($dif);
$sum = 0;
foreach ($dif as $item){
$sum += $item;
}
echo 'SUM = '.$sum;
?>
Working CODE
If you want all the different stages kept,
$numbers = [2,1,4,3,6,2];
$diff = [];
for($i=0,$c=count($numbers);$i<$c;$i+=2)
{
$diff[] = $numbers[$i]-$numbers[$i+1];
}
$sum = array_sum($diff);
Else, to just get the total and bypass the diff array:
$numbers = [2,1,4,3,6,2];
$total = 0;
for($i=0,$c=count($numbers);$i<$c;$i+=2)
{
$total += $numbers[$i]-$numbers[$i+1];
}
I have got this far it gives the required solution.
$arr = array(2,1,4,3,6,2);
$temp = 0;
$diff = array();
foreach ($arr as $key => $value) {
if($key % 2 == 0) {
$temp = $value;
}
else {
$diff[] = $temp - $value;
}
}
print_R($diff);
print 'Total :' . array_sum($diff);
Note : Please update if any one knows any pre-defined function than can sorten this code.
Please check and see if this works for you.
<?php
$sum=0;
$number = array(2,1,4,3,6,2);
for ($i=0;$i<=count($number);$i++) {
if ($i%2 == 1 ) {
$sum = $sum + $number[$i-1] - $number[$i];
}
}
print $sum;
?>
Well with your conditions in mind I came to the following
$number = [2,1,4,3,6,2];
$total = 0;
for($i = 0; $i < count($number); $i+=2) {
$total += $number[$i] - $number[$i + 1];
}
Try this one:
$number = array(2,1,4,3,6,2);
$diff = array();
$v3 = 0;
$i=1;
foreach($number as $val){
if ($i % 2 !== 0) {
$v1 = $val;
}
if ($i % 2 === 0) {
$v2 = $val;
$diff[] = $v1-$v2;
$v3+= $v1-$v2;
}
$i++;
}
print $v3;//total value
print_r($diff); //diff value array
This is a programming question that will require some thinking, and could really be applied to any programming language.
Suppose you have the array:
$arr=array(10,7,4,4,3,2,1,1,1,1,1,1);
This array is dynamic and could be any set of numbers.
You also have a multiplier, lets say 0.6.
The goal is to display each number, one by one, in such a manner that they add as close to the total*multiplier as possible. In this case, the numbers add to 36, *0.6 gives you 21.6
Here's the catch:
You have to round each value (whole numbers only), so your real goal is to make the numbers add as close to 22 as possible.
You cannot use any functions to solve for the sum of the array. You can only loop through it once.
The most basic attempt would be
$multiplier = 0.6;
$sum=0;
foreach($arr AS $value){
$sum+=round($multiplier * $value);
}
But this will not work since 1*0.6 will always round to 1.
I think it is possible with something like this:
$multiplier = 0.6;
$sum=0;
foreach($arr AS $value){
$real=$multiplier * $value;
$rounded=round($multiplier * $value);
$sum_rounded += $rounded;
$sum_real += $real;
//Somehow compare the two sums and break the foreach
}
I don't know where to go from here. What do you guys think?
Tried this:
$sum_real=0;
$sum_round=0;
$count=0;
foreach($rows AS $arr){
$count+=1;
$real_val=$arr*$multiplier;
$sum_round+=round($real_val);
$sum_real+=$real_val;
$avg_round=$sum_round/$count;
$avg_real = $sum_real/$count;
$val = ($avg_round>$avg_real) ? floor($real_val) : round($real_val);
}
But did not work...I think it is getting close though.
Calculate the average for both $sum_rounded and $sum_real at the beginning of each iteration of the foreach loop. If the average for $sum_rounded is larger, use floor() instead of round().
EDIT: You don't actually need to calculate the average at all, since the numbers will both be divided by the same number and that doesn't affect which one is larger. Also, add the $value that is about to be incremented to the comparisons.
foreach($arr AS $value){
$real=$multiplier * $value;
$rounded=round($multiplier * $value);
if($sum_rounded + $rounded > $sum_real + $real) {
$sum_rounded += floor($multiplier * $value);
}
else {
$sum_rounded += $rounded;
}
$sum_real += $real;
}
I think I can talk you into looping twice.
$arr = array(10,7,4,4,3,2,1,1,1,1,1,1);
$out = [];
$multiplier = 0.6;
$sum = round(array_sum($arr) * $multiplier); // that's a loop!
foreach ($arr as $value) {
$value = round($multiplier * $value);
array_push($out, $value);
$sum -= $value;
}
while ($sum > 0) {
$sum --;
$out[$sum] --;
}
while ($sum < 0) {
$sum ++;
$out[-$sum] ++;
}
Here's a 1-pass method:
$orig_sum = 0;
$rounded_sum = 0;
$new_arr = array();
for ($i = 0; $i < count($arr)-1; $i++) {
$orig_sum += $arr[$i];
$new_elt = round($arr[$i] * $multiplier);
$rounded_sum += $new_elt;
$new_arr[] = $new_elt;
}
$orig_sum += $arr[$i];
$expected_rounded_sum = round($orig_sum * $multiplier);
$new_arr[] = $expected_rounded_sum - $rounded_sum;
CODEPAD