MediumClasses and objectsNot started

Overdue library fees

A village library charges 25 pence for every day a book is returned late, but never more than 500 pence for a single book. At closing time the librarian has a list of returned loans, each with the book's title and how many days late it came back.

Create a Loan class with a title, the number of days late and a method or property that computes the fee. Read the loans, print the fee for each one, then print the total collected.

Input

The first line is an integer n. Each of the next n lines is title,days where title contains no commas (it may contain spaces) and days is an integer number of days late.

Output

n lines in input order, each title: feep (the fee in pence followed by p), then one line Total: sump.

Example 1

Input

3
Small Boats,3
Bread Making,40
Owls,0

Output

Small Boats: 75p
Bread Making: 500p
Owls: 0p
Total: 575p

3 days cost 75p. 40 days would cost 1000p but the cap brings it down to 500p. A book returned on time costs nothing.

Constraints

  • 1 <= n <= 100
  • 0 <= days <= 1000
  • Titles are 1 to 60 characters without commas

Hints

Hint 1 of 3

The fee is DaysLate * 25, but it must never exceed 500. Math.Min clamps a value to a maximum.

Hint 2 of 3

A read-only computed property public int Fee => ...; keeps the calculation next to the data it depends on.

Hint 3 of 3

Loop over the list once: print the fee and add it to a running total, then print the total after the loop.

Solution

Show a reference solution and explanation
 C# · reference solution
int count = int.Parse(Console.ReadLine()!);
var loans = new List<Loan>();
for (int i = 0; i < count; i++)
{
    string[] parts = Console.ReadLine()!.Split(',');
    loans.Add(new Loan(parts[0], int.Parse(parts[1])));
}

int total = 0;
foreach (Loan loan in loans)
{
    Console.WriteLine($"{loan.Title}: {loan.Fee}p");
    total += loan.Fee;
}
Console.WriteLine($"Total: {total}p");

class Loan
{
    public const int PencePerDay = 25;
    public const int MaxFee = 500;

    public string Title { get; }
    public int DaysLate { get; }

    public Loan(string title, int daysLate)
    {
        Title = title;
        DaysLate = daysLate;
    }

    public int Fee => Math.Min(DaysLate * PencePerDay, MaxFee);
}

Why it works

Putting the fee rule inside the Loan class means every part of the program that needs a fee gets the same answer, and the cap lives in exactly one place. The Fee property is an expression-bodied member: it looks like a field to callers but is recomputed from DaysLate each time, so there is no stored value that could go stale. Named constants such as PencePerDay document what the magic numbers mean. The main program stays simple: build objects, ask each for its fee, accumulate. That separation between data-with-rules and the code that uses it is the core reason to write a class.

Your program
int count = int.Parse(Console.ReadLine()!);
var loans = new List<Loan>();
for (int i = 0; i < count; i++)
{
    string[] parts = Console.ReadLine()!.Split(',');
    loans.Add(new Loan(parts[0], int.Parse(parts[1])));
}

// print each loan's fee and then the total

class Loan
{
    public string Title { get; }
    public int DaysLate { get; }

    public Loan(string title, int daysLate)
    {
        Title = title;
        DaysLate = daysLate;
    }

    // add a Fee property: 25p per day, capped at 500p
}
Run is not available for C# in the browser yet. Write your program here, then download it and run it locally with .NET SDK 8.0 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 .NET SDK 8.0 at build time by the publishing checks, and the output shown is what it printed. Running C# inside the browser is not available yet, so the Run button is absent rather than pretending; copy the code and run it with .NET SDK 8.0 locally.