installments with the exact sum - php

is there any way to accurately calculate the installments? remembering that the sum of these parcels shall be the total value of the? I usually do a loop which will split and burn in the database, if the number of parcels is 4, I record four records .. but I want to know if there is any way that I can piecemeal parts that final sum is accurate, as X = 500, P = 3, if I dividor (500 / 3), 166.666 will give ... but the result is that I hope to get something like: X = 500, P = 3, p¹ = 150: p² = 150, p³ = 200
Legend: X = Order Value, P = Number of Parcels. , p¹, p², p³ = parcel 1, 2 and 3
Remember, the value of the order, will never be exact, I get 2598.90, 2038.80 .. etc.

If I understand you correctly, here is my guess
$total = 23419.97; // total amount
$total_parcel = 24; // total parcel
// average parcle
$avg_parcel = floor($total / $total_parcel); // nearest integer;
// value for each parcel
$parcels = array_fill(0, $total_parcel, $avg_parcel);
// change last parcel value
// so, sum of all parcel = total
$parcels[$total_parcel-1] = $total-(($total_parcel-1)*$avg_parcel);

Related

Adding values of an array N times to reach a target

I have a target number (maximum capacity of more than one class room)
An array of department IDs .
$depts = array(1,2,3);
A function that returns the total number of students taking a particular course from a Department.
function noStudentsTakingCourse ($dept_id){
//Some expressions..
return $student_count;
}
An array of capacity of the available rooms, ie, the capacity of class rooms that are vacant
$available_room_capacities = array(50, 75, 40, 36, 100, 250);
What I want is:
From the department IDs, I want each available class room to be assigned a department in which the number of students taking that in the department is greater or equal to the room capacity.
I don't know if you get me, but am fairly new to programming and I've spent days trying to get this without any success.
$total_no_of_students_taking_course = 223;
$dept_ids_taking_course = array(1, 2, 3);
$available_room_capacities = array(50, 70, 35, 59, 95, 100);
function noOfStudentsTakingCourse($dept_id)
{
$r = 0;
if ($dept_id == 1) {
$r = 100;
} elseif ($dept_id == 2) {
$r = 56;
} elseif ($dept_id == 3) {
$r == 67;
}
return $r;
}
Hers's what i've been able to come up with. all it does is randomly sum values from the class_room array until they're greater than the total number of students taking the course. But, most times it sums more than 5 values when the department here is only 3. i want the case where by:
- Department 1 (with capacity of 100) would be allocated a room greater of equal to 100,
- Department 2 (with capacity of 56) would be allocated a room greater or equal to 56 and so on.
That means the final array would be of lenght 3 and its sum would not be less than 223 (according to the code above)
THANKS IN ADVANCE

PHP likely chance

Okay, so i don't really know how I go about this.
I'm currently working on a lottery system for a game.
I have a table with virtual items which I want to randomly select by a likely chance.
Table examples:
ID = 1, item_name = Sword, likely_chance = 75
ID = 2, Item_name = 10,000, likely_chance = 20
For id 2, 10,000 represents 10,000 coins.
I want to come up with an algorithm which will select a item with a higher chance of selecting a higher likely chance but also still be able to win a item with a lower likely chance rarely.
If you have items with "likely chances" of C1, C2, C3...Cn, then you can calculate the sum Ctotal.
Then, you can get a random value between 0 and Ctotal, and walk through your array (order is irrelevant) until the sum of "skipped" items exceeds this random value.
For example, in your case, Ctotal = 75 + 20 = 95. Get a random number between 0 and 95, and if it is less than 75 - give a sword; else - give 10000 coins. It will provide a fair winnings distribution according to your likely chances - 78.95% and 21.05%, respectively.
$items = ['Sword', '10000 coins'];
$chances = [70, 25];
$ctotal = array_sum($chances); echo "Total is $ctotal\n";
$rand = rand(0, $ctotal); echo "Rand is $rand\n";
$i = 0;
$currentSum = 0;
while (true)
{
$currentSum += $chances[$i];
if ($currentSum >= $rand)
{
echo "You win: ".$items[$i];
break;
}
$i++;
}
Here is the working Demo. Note that IDEOne remembers the last output and doesn't run this program again every time. The output will appear to be the same, but it is not.

Rounding in PHP to achieve 100%

I need to total the number of clicks over 10 links on my page and then figure out the percentage of people that clicked each. This is easy division, but how do I make sure that I get a round 100% at the end.
I want to use the below code, but am worried that a situation could arise where the percentages do not tally to 100% as this function simply removes the numbers after the period.
function percent($num_amount, $num_total) {
$count1 = $num_amount / $num_total;
$count2 = $count1 * 100;
$count = number_format($count2, 0);
echo $count;
}
Any advice would be much appreciated.
Instead of calculating one percentage in your function you could pass all your results as an array and process it as a whole. After calculating all the percentages and rounding them make a check to see if they total 100. If not, then adjust the largest value to force them all to total 100. Adjusting the largest value will make sure your results are skewed as little as possible.
The array in my example would total 100.02 before making the adjustment.
function percent(array $numbers)
{
$result = array();
$total = array_sum($numbers);
foreach($numbers as $key => $number){
$result[$key] = round(($number/$total) * 100, 2);
}
$sum = array_sum($result);//This is 100.02 with my example array.
if(100 !== $sum){
$maxKeys = array_keys($result, max($result));
$result[$maxKeys[0]] = 100 - ($sum - max($result));
}
return $result;
}
$numbers = array(10.2, 22.36, 50.10, 27.9, 95.67, 3.71, 9.733, 4.6, 33.33, 33.33);
$percentages = percent($numbers);
var_dump($percentages);
var_dump(array_sum($percentages));
Output:-
array (size=10)
0 => float 3.51
1 => float 7.69
2 => float 17.22
3 => float 9.59
4 => float 32.86
5 => float 1.28
6 => float 3.35
7 => float 1.58
8 => float 11.46
9 => float 11.46
float 100
This will also work with an associative array as the function parameter. The keys will be preserved.
These figures could now be presented in a table, graph or chart and will always give you a total of 100%;
What you want to do is this.
Total the number of clicks across the board, then divide each number by the total.
For example:
1134
5391
2374
2887
In this case, four buttons, with a total of 11786 clicks, so:
1134 / 11786 = 0.09621....
5391 / 11786 = 0.45740....
2374 / 11786 = 0.20142....
2887 / 11786 = 0.24495....
Then for each division, round the result to 'two decimal points', so the first result:
0.09621.... becomes 0.10
because the 3rd point is 5 or above, it would remain at 0.09 if the 3rd point was below 5.
Once you have all of the results rounded, multiply each by 100 then add them up.
The ending result will always be 100.
Should warn you however that depending on how you use each individual percentage, when you round them, any result less that 0.05 will become 0%, unless you keep the value before you round it so you can declare it as a percentage less than 1.
I think you want to use ceil() or round() .
Since these are floating point numbers, there is room for error. Be careful how you round, and be sure that you don't independently calculate the last remaining percentages. Simply subtract the total of what you have from 1 or 100.
Make sure you dont calculate separate sides of the equation, sum one side, then subtract the other from 1 or 100 or however you are handling your percentages.
I run into this quite a bit and have a hack for it.
$percentages = array(
'1' => 87.5,
'2' => 12.5,
'3' => 0,
'4' => 0,
'5' => 0
);
If you round those percentages for output, you will end up with 88% and 13% (101%)
round($percentages['1']);
round($percentages['2']);
// 88
// 13
So here is the code I use to fix it.
$checkTotal = array_sum($percentages);
$max = max(array_keys($percentages));
if ($checkTotal > 100) {
$percentages[$max] = $percentages[$max] - 1;
}
if ($checkTotal < 100) {
$percentages[$max] = $percentages[$max] + 1;
}
If it is 100, do nothing.
If it is less than 100, add 1 to equal 100
If it is over 100, subtract 1 to equal 100

Get result based on probability distribution

In a browser game we have items that occur based on their probabilities.
P(i1) = 0.8
P(i2) = 0.45
P(i3) = 0.33
P(i4) = 0.01
How do we implement a function in php that returns a random item based on its probability chance?
edit
The items have a property called rarity which varies from 1 to 100 and represents the probability to occcur. The item that occurs is chosen from a set of all items of a certain type. (e.x the given example above represents all artifacts tier 1)
I don't know if its the best solution but when I had to solve this a while back this is what I found:
Function taken from this blog post:
// Given an array of values, and weights for those values (any positive int)
// it will select a value randomly as often as the given weight allows.
// for example:
// values(A, B, C, D)
// weights(30, 50, 100, 25)
// Given these values C should come out twice as often as B, and 4 times as often as D.
function weighted_random($values, $weights){
$count = count($values);
$i = 0;
$n = 0;
$num = mt_rand(0, array_sum($weights));
while($i < $count){
$n += $weights[$i];
if($n >= $num){
break;
}
$i++;
}
return $values[$i];
}
Example call:
$values = array('A','B','C');
$weights = array(1,50,100);
$weighted_value = weighted_random($values, $weights);
It's somewhat unwieldy as obviously the values and weights need to be supplied separately but this could probably be refactored to suit your needs.
Tried to understand how Bulk's function works, and here is how I understand based on Benjamin Kloster answer:
https://softwareengineering.stackexchange.com/questions/150616/return-random-list-item-by-its-weight
Generate a random number n in the range of 0 to sum(weights), in this case $num so lets say from this: weights(30, 50, 100, 25).
Sum is 205.
Now $num has to be 0-30 to get A,
30-80 to get B
80-180 to get C
and 180-205 to get D
While loop finds in which interval the $num falls.

PHP rating system

I have a table (review) which stores the values (1-5) for ratings. I will use the sum of these ratings for the overall score.
I have 5 stars on the page which will show on or off depending on the overall value.
I have the overall score by counting the total value of all the ratings divided by the number of reviews in the table. This give a value below 5 every time...great.
However I now have a problem where the value could either be 1.5 or 1.75 for instance. If the value is 1.5 I will show 1 and a half stars on and 3 and a half stars off. How should I determine if the value is 1.75 to show only the 1.5 value star.
Hope that makes sense.
That should be a simple math problem, since your resolution is 1/2, multiply by two, round it, then divide by 2:
round(x * 2) / 2
round((1.75) * 2) / 2 = 2
round((1.65) * 2) / 2 = 1.5
<?php
$tests = array(-1, 0, 0.25, 0.5, 1, 1.5, 1.75, 3, 4.22, 6);
foreach($tests as $test)
echo "Initial rate = ".$test.", adjusted rate = ".adjustRate($test)."\n";
function adjustRate($val)
{
if ($val < 0)
return 0;
if ($val > 5)
return 5;
return floor($val * 2) / 2;
}
Gives for example:
Initial rate = 1.75, adjusted rate = 1.5

Categories