MediumFunctionsNot started

Postage cost per parcel

A parcel shop prices postage by weight: up to 500 g costs 3.20; from 501 g to 2000 g costs 5.60; heavier parcels cost 5.60 plus 1.10 for every started kilogram above 2000 g, so 2001 g to 3000 g costs 6.70 and 3001 g to 4000 g costs 7.80. Express delivery doubles the price. Write a function postage(int $grams, bool $express): int that returns the price in cents, then read a list of parcels and print the price of each on its own line as euros.cents.

Input

The first line is N, the number of parcels (1 to 200). Each of the next N lines holds a weight in grams (1 to 30000), a space, and yes or no for express.

Output

N lines: the price of each parcel with exactly two decimals, for example 6.70.

Example 1

Input

4
250 no
500 yes
2000 no
2001 no

Output

3.20
6.40
5.60
6.70

250 g is in the first band. 500 g express is 3.20 doubled. 2000 g is still the second band. 2001 g starts a new kilogram above 2000 g, so 5.60 + 1.10.

Example 2

Input

2
3000 yes
3001 no

Output

13.40
7.80

3000 g is one started kilogram over (6.70), doubled for express. 3001 g starts a second kilogram: 5.60 + 2 x 1.10.

Constraints

  • 1 <= N <= 200
  • 1 <= grams <= 30000
  • The second word is exactly yes or no

Hints

Hint 1 of 3

Work in integer cents (320, 560, 110) inside the function so no rounding can creep in.

Hint 2 of 3

The number of started kilograms above 2000 g is intdiv($grams - 2000 + 999, 1000): adding 999 before dividing rounds up.

Hint 3 of 3

To print cents as money: sprintf('%d.%02d', intdiv($cents, 100), $cents % 100).

Solution

Show a reference solution and explanation
 PHP · reference solution
<?php
function postage(int $grams, bool $express): int
{
    if ($grams <= 500) {
        $cents = 320;
    } elseif ($grams <= 2000) {
        $cents = 560;
    } else {
        $startedKilos = intdiv($grams - 2000 + 999, 1000);
        $cents = 560 + 110 * $startedKilos;
    }
    return $express ? $cents * 2 : $cents;
}

$n = (int) trim(fgets(STDIN));
for ($i = 0; $i < $n; $i++) {
    [$grams, $flag] = explode(' ', trim(fgets(STDIN)));
    $cents = postage((int) $grams, $flag === 'yes');
    echo sprintf('%d.%02d', intdiv($cents, 100), $cents % 100), "\n";
}

Why it works

The function isolates the pricing rules from the input loop, so each part can be read and tested on its own. Returning integer cents is deliberate: 3.20 and 1.10 cannot be represented exactly as binary floats, and adding them repeatedly can produce a value a hair under 6.70 that then prints or compares wrongly. Integers never drift. Rounding up to a started kilogram is done with integer arithmetic too: add 999 before the integer division and any remainder pushes the result over the next boundary. The loop body only converts text to the types the function declares ((int) and === 'yes'), which is what typed parameters ask of the caller.

Lesson for this exercise: Functions in PHP

Your program
<?php
function postage(int $grams, bool $express): int
{
    // return the price in cents for this parcel
    return 0;
}

$n = (int) trim(fgets(STDIN));
for ($i = 0; $i < $n; $i++) {
    [$grams, $flag] = explode(' ', trim(fgets(STDIN)));
    $cents = postage((int) $grams, $flag === 'yes');
    echo sprintf('%d.%02d', intdiv($cents, 100), $cents % 100), "\n";
}
Run is not available for PHP in the browser yet. Write your program here, then download it and run it locally with PHP 8.4 against the examples above. The reference solution below was verified the same way.

Tests: 5 cases including the examples. Passing every test marks the exercise solved in this browser.

How this page was checked. Every program on it was run with PHP 8.4 at build time by the publishing checks, and the output shown is what it printed. Running PHP inside the browser is not available yet, so the Run button is absent rather than pretending; copy the code and run it with PHP 8.4 locally.