loading...

Daily Challenge #280 - Driving School

thepracticaldev profile image dev.to staff ・1 min read

Write a function that will charge driving students based on the amount of time they spent in their lessons. This particular school charges for lessons as follows:

Time                            Cost
************************************
Up to 1st hour                   $30
Every subsequent half hour**     $10
** Subsequent charges are calculated by rounding up to nearest half hour.

For example, if student X has a lesson for 1hr 20 minutes, he will be charged $40 (30+10) for 1 hr 30 mins and if he has a lesson for 10 minutes, he will be charged $30 for the full hour.

Out of the kindness of its heart, the driving school also provides a 5 minutes grace period. So, if student X were to have a lesson for 65 minutes, he will only have to pay for an hour. Lessons under 5 minutes are just talks, so they should be considered free.

For a given lesson time in minutes (min), write a function price to calculate how much the lesson costs.

Tests

cost(84)
cost(102)
cost(273)

Good luck!


This challenge comes from kkavita92 on CodeWars. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions!

Posted on by:

thepracticaldev profile

dev.to staff

@thepracticaldev

The hardworking team behind dev.to ❤️

Discussion

pic
Editor guide
 

Here is my simple solution with PHP and using while loop to resolve this challenge :).

function cost($mins) {
  if ($mins <= 60) {
    return 30;
  }

  $result = 30;
  $mins -= 60;
  $halfHour = 0;

  while ($mins - 30 > 0) {
    $halfHour += 1;
    $mins -= 30;
  }

  if (30 - $mins >= 0 && $mins >= 6) {
    $halfHour += 1;
  }

  return $result + $halfHour * 10;
}
 

Via phone, but this should work:

 function cost(min) {
   let cost = 0;
   min -= 5;
   if (min <= 0) {
     return cost;
   }
   cost += 30; // first hour
   if (min < 60) {
     return cost;
   }
   while (min > 0) {
     min -= 30;
     cost += 10;
   }
   return cost;
 }
 

Rust

pub fn cost(mut mins: usize) -> usize {
    mins = mins.saturating_sub(5);
    if mins == 0 {
        0
    } else {
        30 + mins.saturating_sub(60) / 30 * 10
    }
}

which produces the same assembly as

pub fn cost(mins: usize) -> usize {
    if mins <= 5 {
        0
    } else {
        30 + mins.saturating_sub(65) / 30 * 10
    }
}
 
fn cost(mins: u8) -> u8 {
    if mins < 5 {
        return 0;
    }
    if mins < 65 {
        return 30;
    }

    let extra_time = (mins - 60) / 30 + if (mins - 60) % 30 > 5 { 1 } else { 0 };
    return 30 + (extra_time * 10);
}
 

Here's something fun, there is a set of numbers where this doesn't work, anyone up for finding it?

def cost(minutes):
    a = (minutes > 5)*30
    b = ((minutes // 30) & 1020)*10
    c = (minutes % 30 > 5 and minutes > 65)*10
    return a + b + c
 
def cost(minutes):
   if minutes <= 5:
      return 0

   if minutes <= 65:
      return 30

   minutes -= 65
   # Could also use math.ceil() here but didn't want the dependency on math for this example
   half_hours = minutes // 30 + (minutes % 30 > 0)
   return 30 + half_hours * 10
 
minutes => Math.max(0, Math.ceil((minutes-65)/30)*10) + (minutes>5)*30;

For some abuse of weak typing and code golf. Should work.

 

Python

def cost(minutes):
    if minutes <66: return 0 if minutes<6 else 30
    half = (minutes-65)//30 + (((minutes-65)%30)>0)
    return 30 + half*10