Adding values of an array N times to reach a target - php

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

Related

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.

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.

installments with the exact sum

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);

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

Generating a random number but with a twist

I need to generate a random number.
But the twist is that the % of lower numbers should be greater than the higher.
For example.
rand > 1 to 100
13,
15,
12,
16,
87,
15,
27,
12,
1,
12,
98,
12,
53,
12,
14....
The bold integers will be the ones return from the 1-100 range.
The math should be like so rand = a number lower than max/2
Hope you guys can help.
Ps, How would a matrix come into this ? im not superior at maths :(
The abs answer seems to be the one.
$up = $down = 0;
while(true)
{
if(abs((rand()%150)-50) < 50)
{
$up++;
}else
{
$down++;
}
if( ($up + $down) == 500){ break;}
}
echo $up . '/' . $down;
how about
n = abs((rand()%150)-50)
$x = rand(0,1) ? rand(1,100) : rand(1,50);
Simple method: the first rand(0,1) selects between the two cases. Either 1..50 or 1..100 as random range. Since 1,100 already encompases 1,50, the latter range is selected 100% of the time, the former case only in 1 of 2 runs.
If you want a distribution where the highest numer 99 gets selected almost never, but the lower numbers 1..20 pretty frequent, then a simple rand(1,rand(1,100)) would do.
$rand = (rand() * rand()) / (getrandmax() * getrandmax());
This will give you a random number between 0 and 1 with a high probability of falling into the lower end of the range and the probability of a larger number decreasing exponentially. You can then scale this result to any range that you want.

Categories