I have data for 2 profiles that I would like to compare.
Each profile has a 'total points' value and a 'points per day' value and I would like to calculate how many days it would take the hare to overtake the tortoise.
$hare_points = 10000;
$hare_ppd = 700;
$tortoise_points = 16000;
$tortoise_ppd = 550;
What would be the most efficient way to determine how many days it would take for the hare to catch up with the tortoise? My first through was to run a loop to just count through the days, but very quickly realised there must be an efficient algorithm out there that will not want to destroy the server that it is running on lol
Assuming ppd is points per day:
<?php
$hare_points = 10000;
$hare_ppd = 700;
$tortoise_points = 16000;
$tortoise_ppd = 550;
$hare_diff = $tortoise_points - $hare_points;
$hare_ppd_diff = abs($tortoise_ppd - $hare_ppd);
$days = $hare_diff/$hare_ppd_diff;
echo $days; // 40
/* Test:
* 40 * 700 = 28000; hare
* 40 * 550 = 22000; tortoise
*
* hare_p = 28000 + 10000 = 38 000
* toit_p = 22000 + 16000 = 38 000
*
* So the math is right. On 40th day, they are equal
*
*/
It's a simple set of equations to solve.
hare_total = hare_points + hare_ppd * days
tortoise_total = tortoise_points + tortoise_ppd * days
You're trying to find out the day the points are the same, so:
hare_total = tortoise_total
hare_points + hare_ppd * days = tortoise_points + tortoise_ppd * days
hare_points - tortoise_points = (tortoise_ppd - hare_ppd) * days
So there's your answer:
$days = ($hare_points - $tortoise_points) / ($tortoise_ppd - $hare_ppd)
Just plug that into your function and round up / down to an integer depending on how you want to interpret the answer.
Related
I need a Function that rounds the minutes of a time stamp to round up the next 15 minutes when the time is 5 minutes above the previous 15 minutes.
01:05:00 = 01:15:00
01:04:00 = 01:00:00
01:20:00 = 01:30:00
01:19:00 = 01:15:00
I have this right now but the flaw is some times it will round down due to the really poor attempt on my part.
function roundTime10($timestamp10, $precision10 = 10) {
$timestamp10 = strtotime($timestamp10);
$precision10 = 60 * $precision10;
return date('H:i:s', round($timestamp10 / $precision10) * $precision10);
}
$Billable_Time = roundTime10($Billable_Time);
function roundTime15($timestamp15, $precision15 = 15) {
$timestamp15 = strtotime($timestamp15);
$precision15 = 60 * $precision15;
return date('H:i:s', round($timestamp15 / $precision15) * $precision15);
}
$Billable_Time = roundTime15($Billable_Time);
echo $Billable_Time;
could anyone show me a better way to do this or ad to my way to make it work?
The basic logic for this is "subtract five minutes, divide by 15 to an integer result then add one and multiply by fifteen".
01:04:00 = 01:00:00: 4-5 = -1. -1/15 = -0.xxx (round down to -1). (-1+1)*15 = 0
01:20:00 = 01:30:00: 20-5 = 15. 15/15 = 1 (round down to 1). (1+1)*15 = 30
01:19:00 = 01:15:00: 19-5 = 14. 14/15 = 0.xxx (round down to 0). (0+1)*15 = 15
I don't have a PHP interpreter handy so won't write the code but you need to replace "round($timestamp15 / $precision15) * $precision15" with something that uses the logic above. You'll want to use the PHP floor() as it rounds negatives down while round() rounds towards or away from zero.
How can I calculate percentage between two time values in php:
Completed time 4min. and 35sec. Maximum time 11min.
What would the remaining 6min and 25sec be in percentage?
First, make those minutes into seconds:
4 min 35 sec = 275 seconds
11 min = 660 seconds
Your percentage of remaining time will be (275 / 660) * 100. The percentage of time left would be ((660 - 275) / 660) * 100. Of course, that's all in seconds. Don't know how you are receiving that time in php, but it might look like:
$maxTime = 660;
$timeTaken = 275;
$percentage = ($timeTaken / $maxTime) * 100;
// To get percentage of time left
$percentLeft = (($maxTime - $timeTaken) / $maxTime) * 100;
If you have minutes and second separately, it will be:
$min = 4;
$sek = 35;
$maxmin = 11;
$percentage = round((60*$maxmin - (60*$min + $sek))/($maxmin*60)*100,2);
result is 58,33
I am trying to convert a decimal time into an actual time format with hours and minutes, ie: in xx:xx hours.
My query is:
select SUM(vt.vluchtdec) AS vluchttijddecimal
from tbl_vluchtgegevens vg
left join tbl_vluchttijd vt
on vg.vluchttijddec = vt.vluchttijdID
WHERE vg.vertrekdatum <=NOW();
And I am echoing
. $row['vluchttijddecimal'] .
I have also tried this, but this also still gives me my response in a decimal format:
$result = mysql_query("select SUM(vt.vluchtdec) AS vluchttijddecimal
from tbl_vluchtgegevens vg
left join tbl_vluchttijd vt
on vg.vluchttijddec = vt.vluchttijdID
WHERE vg.vertrekdatum <=NOW();");
while($row = mysql_fetch_array($result))
{
$dec = $row['vluchttijddecimal'];
function
convertTime($dec)
{
// start by converting to seconds
$seconds = $dec * 3600;
// we're given hours, so let's get those the easy way
$hours = floor($dec);
// since we've "calculated" hours, let's remove them from the seconds variable
$seconds -= $hours * 3600;
// calculate minutes left
$minutes = floor($seconds / 60);
// remove those from seconds as well
$seconds -= $minutes * 60;
// return the time formatted HH:MM:SS
return lz($hours).":".lz($minutes).":".lz($seconds);
}
// lz = leading zero
function lz($num)
{
return (strlen($num) < 2) ? "0{$num}" : $num;
}
echo "" .$dec."";
In MS Access I would do something like this:
CInt([vluchttijddecimal]) & ":" & Format([vluchttijddecimal]*60 Mod 60;"00")
But this does not work or I don't know how to do so in MySQL / php.
For anyone that is interested... This is how you would convert decimal time (Where 0.1 == 6 minutes) to hours and minutes (0.2333 == 14 minutes) in MYSQL alone. no PHP is needed. This also accounts for the need to round seconds to minutes.
SELECT CONCAT(FLOOR(timeInDec),':', LPAD(ROUND((timeInDec - FLOOR(timeInDec)) * 60) % 60,2,0)) AS TimeInHoursMinutes
FROM YourTable;
Replace timeInDec with the column name that contains the decimal time you would like to convert.
This will return 0:06 for 0.1000 decimal value so leading zeros are accounted for in single digit minutes.
You can do this in you SQL statement something like this:
SELECT CONCAT(CEIL(mydecimal),':', LPAD(Floor(mydecimal*60 % 60),2,'0')) as formated text
Where mydecimal is your unformatted field name
I think I have calculated your time values... although it was kinda pain.
It appears your "decimal time" is "hours.minutes"? Rather horrible and definitely not a good format: for dealing with time its best to stick to integers that specify either a total of minutes/seconds/hours or whatever granularity you need.
But assuming it is hours.minutes, you should be able to do it like this in PHP:
while($row = mysql_fetch_array($result))
{
$dec = $row['vluchttijddecimal'];
return sprintf("%2d:%2d", floor($dec), floor(($dec - floor($dec))*100));
}
Hopefully I am correct in assuming that you mean, for example that 2.5 hours = 2H 30mins. If so, then your 'time' is a time interval and is best represented by the DateInterval class.
This function will do what you want:-
/**
* Converts a 'decimal time' in the format 1.5hours to DateInterval object
*
* #param Int $decimalTime
* #return DateInterval
*/
function decTimeToInterval($decimalTime)
{
$hours = floor($decimalTime);
$decimalTime -= $hours;
$minutes = floor($decimalTime * 60);
$decimalTime -= ($minutes/60);
$seconds = floor($decimalTime * 3600);
$interval = new \DateInterval("PT{$hours}H{$minutes}M{$seconds}S");
return $interval;
}
echo decTimeToInterval(512.168)->format("%H:%I:%S");
See it working
If you want to add times in the format 'H:i' without converting them to and from decimals, you can do it like this:-
function sumTimes($time1, $time2)
{
list($hours1, $minutes1) = explode(':', $time1);
list($hours2, $minutes2) = explode(':', $time2);
$totalHours = $hours1 + $hours2;
$totalMinutes = $minutes1 + $minutes2;
if($totalMinutes >= 60){
$hoursInMins = floor($totalMinutes/60);
$totalHours += $hoursInMins;
$totalMinutes -= ($hoursInMins * 60);
}
return "$totalHours:$totalMinutes";
}
echo sumTimes('12:54', '100:06') . PHP_EOL;
echo sumTimes('12:54', '100:20') . PHP_EOL;
See it working
This is what I used for my Payroll System:
SELECT If(total_late>0, LPAD(CONCAT(REPLACE(FLOOR(total_late/60) + FORMAT(total_late%60*0.01,2), '.', ':'), ':00'), 8, 0), '00:00:00') FROM MyTable
I multiplied it by 0.01 because my variables are in Seconds. Eg. 60.00 = 1min
I would suggest this to include seconds. It is based on #Richard's solutions. Just notice I've changed CEIL by FLOOR in #Richard's solution.
SET #timeInDec=1.505;
SELECT CONCAT(FLOOR(#timeInDec),':', LPAD(FLOOR(#timeInDec*60 % 60),2,'0'),':', LPAD(FLOOR(MOD(#timeInDec*60 % 60,1)*100),2,0)) as timeInDec;
Heres the code I have at the moment, its all working as intended, however, the cumulative total isn't working, and I'm positive I'm doing something absolutely stupid.
assume period = 20
assume inflation = 3
assume nightlycost = 100
assume nights = 7
$yearlycost = $nightlycost*$nights;
while ($period > 0) {
$period = $period-1;
$yearlyincrease = ($inflation / 100) * $yearlycost;
$nightlyincrease = ($inflation / 100) * $nightlycost;
$nightlycost = $nightlycost + $nightlyincrease;
$yearlycost = ($yearlycost + $yearlyincrease) + $yearlycost;
}
Result:
Nightly Hotel Rate in 20 years: $180.61 - <?php echo round($nightlycost, 2); ?> correct
Weekly Hotel Rate in 20 years: $1264.27 - <?php echo round($nightlycost, 2) * 7; ?> correct
Total cost to you over 20 years: $988595884.74 - <?php echo round($yearlycost, 2); ?> incorrect
Everything outputs correctly and as expected, except for the yearly cumulative cost. It should take the previous yearly cost and add that years cost+inflation.
Example: first year is 700, so second year should be 700 + 700 + 21 (21 is 3%, the inflation for that year). Second year cumulative total is thus: 1421. Third year will be 1421 + 721 (last years total) + 3% of 721.
Hopefully this is clear enough for you to see where I'm going wrong. Thanks!
I find it hard to understand where your code goes wrong, but my intuition is that the last line in your loop body should have a multiplication.
Basically, you have a base cost for period 0. Then you want to calculate the cumulative cost given inflation after X years. That cost is (pseudocode)
base = nightlycost + nights
infl = 1.03
cumulative = base + base*infl + base*infl^2 + base*infl^3 + ... + base*infl^periods
The last expression can be simplified to
cumulative = base*((1-infl^periods)/(1-infl))
(This holds according to Eq. 4 here: http://mathworld.wolfram.com/ExponentialSumFormulas.html)
Example:
$base = 100*7;
$infl = 1.03; // 3% of inflation/year
$periods = 2;
$cumulative = $base * (1-pow($infl, $periods))/(1-$infl);
print "Cumulative cost after $periods is $cumulative\n";
// Let's try with three periods.
$periods = 3;
$cumulative = $base * (1-pow($infl, $periods))/(1-$infl);
print "Cumulative cost after $periods is $cumulative\n";
Output:
Cumulative cost after 2 is 1421
Cumulative cost after 3 is 2163.63
I'd like to have a php function which will deduct a value, say, 50 from an initial integer of say, 500 at a set interval.
For example: Every 30 days, deduct 50 from 500. So after 90 days, you are left with 350, etc.
I can do subtractions, it's the interval routine that I can't figure out.
If not PHP, JS is great too. This is used to count down a value from the beginning of the year, to the end.
You have a starting number, and you trying to figure out what your current value is. Its a basic total - (time pass * decrement) problem.
So example, You have your original time.
$originalDate = '2011-01-01';
$now = '2011-03-01';
//it will count no. of days
$dateDiff=(strtotime($now) - strtotime($originalDate))/ (60 * 60 * 24);
$startingValue = 500;
$descrement = 50;
$currentValue = $startingValue - ($dateDiff/30*$descrement);
if you want this in a function:
/* deduct()
*
* #param $start - the starting amount to subtract from
* #param $amount - the amount to subtract by
* #param $interval - the interval between deductions
* #param $current_time - the current time to measure against the interval
*
* #return the amount after deduction $amount
* every $interval from $start until $current_time
*/
function deduct($start, $amount, $interval, $current_time) {
return $start - ($amount * floor($current_time / $interval));
}
You can easily pass in a time value using time(), or something like that, formatted into your unit of time.