Can someone help me with the rest of this coding? the parts I need are the TODO
ID: 3674999 • Letter: C
Question
Can someone help me with the rest of this coding? the parts I need are the TODO at the bottom.
#include <cassert>
#include <iostream>
#include <list>
#include <map>
#include <cstddef>
using namespace std;
// one million
const int MILLION = 1000 * 1000;
// maximum size of internal data structures
const int MAX_ACCOUNTS = 40 * MILLION;
const int MAX_UNPAID = 1 * MILLION;
const int MAX_VIOLATIONS = 2 * MILLION;
// Toll Roads policies
const int ACCOUNT_MAINTENANCE_FEE_CENTS = 200; // $2 in units of cents
const int VIOLATION_PENALTY_CENTS = 5750; // $57.50 in units of cents
const int GRACE_PERIOD_DAYS = 5;
// Days of the week.
enum DayOfWeek {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
};
// All onramps on the 73. The enum values are assigned explicit integer values
// in case you want to use them as array indices.
enum Onramp {
ONRAMP_UNKNOWN_SOUTHBOUND = 0,
ONRAMP_405 = 1,
ONRAMP_FAIRVIEW = 2,
ONRAMP_BEAR = 3,
ONRAMP_55 = 4,
ONRAMP_BRISTOL = 5,
ONRAMP_JAMBOREE = 6,
ONRAMP_MACARTHUR = 7,
ONRAMP_BISON = 8,
ONRAMP_BONITA_CANYON = 9,
ONRAMP_NEWPORT_COAST = 10,
ONRAMP_EL_TORO = 11,
ONRAMP_GLENWOOD = 12,
ONRAMP_ALISO_CREEK = 13,
ONRAMP_LA_PAZ = 14,
ONRAMP_GREENFIELD = 15,
ONRAMP_5 = 16,
ONRAMP_UNKNOWN_NORTHBOUND = 17,
};
// All offramps on the 73.
enum Offramp {
OFFRAMP_UNKNOWN_NORTHBOUND = 0,
OFFRAMP_405 = 1,
OFFRAMP_BEAR = 2,
OFFRAMP_55 = 3,
OFFRAMP_IRVINE = 4,
OFFRAMP_JAMBOREE = 5,
OFFRAMP_UNIVERSITY = 6,
OFFRAMP_MACARTHUR = 7,
OFFRAMP_BISON = 8,
OFFRAMP_BONITA_CANYON = 9,
OFFRAMP_NEWPORT_COAST = 10,
OFFRAMP_EL_TORO = 11,
OFFRAMP_GLENWOOD = 12,
OFFRAMP_ALISO_CREEK = 13,
OFFRAMP_LA_PAZ = 14,
OFFRAMP_GREENFIELD = 15,
OFFRAMP_5 = 16,
OFFRAMP_UNKNOWN_SOUTHBOUND = 17,
};
// Represents a point in time, including:
// - Unix time (whole seconds since midnight 1/1/1970)
// - day of the week
// - hour (using military time, so this must be 1 through 23)
// - minute (must be 0 through 59)
class Timestamp {
public:
Timestamp(int unix_time, DayOfWeek day_of_week, int hour, int minute) {
assert(unix_time >= 0);
assert((hour >= 0) && (hour <= 23));
assert((minute >= 0) && (minute <= 59));
_unix_time = unix_time;
_day_of_week = day_of_week;
_hour = hour;
_minute = minute;
}
// Default constructor, leaving all fields uninitialized.
Timestamp() { }
// Accessors.
int unix_time() { return _unix_time; }
DayOfWeek day_of_week() { return _day_of_week; }
int hour() { return _hour; }
int minute() { return _minute; }
// Comparison operator. This is needed by some of the unit tests in main().
bool operator==(const Timestamp& right) const {
return ((_day_of_week == right._day_of_week) &&
(_unix_time == right._unix_time) &&
(_hour == right._hour) &&
(_minute == right._minute));
}
private:
DayOfWeek _day_of_week;
int _unix_time, _hour, _minute;
};
// Return the price of the toll, in units of cents, for a given trip.
//
// When is_fastrak is true, use FasTrak prices; otherwise use One-Time-Toll prices.
//
// time indicates when the trip happened, which factors into some FasTrak trips
// that happen during rush hour.
//
// start and end indicate the endpoints of the trip.
//
// All trips should be for 2 Axle Vehicles & Motorcycles (page 1 of the price
// matrix PDF).
int calculate_toll(bool is_fastrak, Timestamp& time, Onramp start, Offramp end) {
int toll_charge = 0;
bool checkSouth;//check where is it going
if((start <= 10 && start == 1) && (end == 11 && end <=16)) {
return true; } //south
else if((start == 11 && start <= 16) && (end == 1 && end <=10)) {
return false; } //north
// check time
if (time.day_of_week() == SATURDAY || time.day_of_week() == SUNDAY)
{
toll_charge -= 0.25;
}
else
{
if (!checkSouth)
{
if (time.hour() >= 8 && time.hour() < 9)
{
toll_charge += 1.53;
}
else if ((time.hour() >= 7 && time.hour() < 8) || (time.hour() >= 9 && time.hour() < 10))
{
toll_charge += 1.23;
}
}
else if (checkSouth)
{
if (time.hour() >= 17 && time.hour() < 18)
{
toll_charge += 1.53;
}
else if ((time.hour() >= 15 && time.hour() < 17) || (time.hour() >= 18 && time.hour() < 19))
{
toll_charge += 1.23;
}
}
}
// check if driver has fast track
if (is_fastrak)
{
if ((start >= 1 && start <= 4) || (start >= 6 && start <= 8))
{
if (end == 9)
{
toll_charge += 1.02;
}
else if (end == 10)
{
toll_charge += 2.31;
}
else if (end >= 11 && end <= 16)
{
toll_charge += 5.25;
}
}
else if (start == 9)
{
if ((end >= 1 && end <= 3) || (end >= 7 && end <= 8))
{
toll_charge += 1.02;
}
else if (end == 10)
{
toll_charge += 2.31;
}
else if (end > 10)
{
toll_charge += 5.25;
}
}
else if (start == 10)
{
if ((end >= 1 && end <= 3) || (end >= 7 && end <= 9))
{
toll_charge += 2.31;
}
else if (end > 10)
{
toll_charge += 5.25;
}
}
else if (start >= 11 && start <= 16 && end >= 1 && end <= 11)
{
if (end >= 1 && end <= 10)
{
toll_charge += 5.25;
}
else if (end == 11)
{
toll_charge += 2.57;
}
}
else if (start == 11 && end >= 13 && end <= 16)
{
toll_charge += 2.57;
}
else if (start == 13 && end >= 14 && end <= 16) {
toll_charge += 1.95;
}
else if (start == 14 && end >= 13 && end <= 16)
{
if (end == 13)
{
toll_charge += 1.95;
}
else if (end == 15 || end == 16)
{
toll_charge += 1.37;
}
}
else if (start <= 16 && start >= 15 && end <= 14 && end >= 13)
{
if (end == 13)
{
toll_charge += 1.95;
}
else if (end == 14)
{
toll_charge += 1.37;
}
}
}
else
{
if ((start >= 1 && start <= 4) || (start >= 6 && start <= 8))
{
if (end == 9)
{
toll_charge += 2.02;
}
else if (end == 10)
{
toll_charge += 3.31;
}
else if (end >= 11)
{
toll_charge += 7.48;
}
}
else if (start == 9)
{
if (end >= 0 && end <= 3)
{
toll_charge += 2.02;
}
else if (end >= 7 && end <= 8)
{
toll_charge += 2.02;
}
else if (end == 10)
{
toll_charge += 3.31;
}
else if (end >= 11)
{
toll_charge += 7.48;
}
}
else if (start == 10)
{
if (end >= 0 && end <= 3)
{
toll_charge += 3.31;
}
else if (end >= 7 && end <= 9)
{
toll_charge += 3.31;
}
else if (end >= 11)
{
toll_charge += 7.48;
}
}
else if (start >= 11 && end >= 0 && end <= 10)
{
if (end >= 0 && end <= 3)
{
toll_charge += 7.48;
}
else if (end >= 7 && end <= 10)
{
toll_charge += 7.48;
}
else if (end == 11)
{
toll_charge += 3.57;
}
}
else if (start == 11 && end > 12) {
toll_charge += 3.57;
}
else if (start >= 14 && start <= 17 && end == 15)
{
toll_charge += 2.95;
}
else if (start == 13 && end >= 14 && end <= 17)
{
toll_charge += 2.95;
}
else if(start == 14 && end >= 15 && end <= 17)
{
toll_charge += 2.37;
}
else if (start >= 15 && start <= 17 && end == 14)
{
toll_charge += 2.37;
}
}
return toll_charge;
// TODO: REWRITE THIS FUNCTION
}
// A trip recored by a FasTrak transponder inside the car of someone with a
// registered FasTrak account. Each transponder has an integer transponder_id
// which is unique to the transponder device, and is linked to the owner's
// account.
class TransponderTrip {
public:
TransponderTrip(Timestamp time, Onramp start, Offramp end, int transponder_id) {
_time = time;
_start = start;
_end = end;
_transponder_id = transponder_id;
}
// Accessors.
Timestamp& time() { return _time; }
Onramp start() { return _start; }
Offramp end() { return _end; }
int transponder_id() { return _transponder_id; }
private:
Timestamp _time;
Onramp _start;
Offramp _end;
int _transponder_id;
};
// A trip recored by the license plate cameras. This represents a trip taken
// by someone without any FasTrak account.
class LicenseTrip {
public:
LicenseTrip(Timestamp time, Onramp start, Offramp end, string& plate_number) {
assert(!plate_number.empty());
_time = time;
_start = start;
_end = end;
_plate_number = plate_number;
}
// Accessors.
Timestamp& time() { return _time; }
Onramp start() { return _start; }
Offramp end() { return _end; }
string& plate_number() { return _plate_number; }
// Compute the toll, in cents, of this trip.
int toll(bool is_fastrack, Timestamp& time, Onramp start, Offramp end) {
int tollAmt = calculate_toll(is_fastrack, time, start, end);
return tollAmt;
}
private:
Timestamp _time;
Onramp _start;
Offramp _end;
string _plate_number;
};
// Represents a FasTrak account. Each account has
//
// - account_number, a unique integer that identifies the account.
//
// - balance, the amount of money owed, in units of cents. A negative
// balance means that the account holder owes money.
//
// - transponder_id, the integer transponder ID linked to this account.
//
// - plate_number, a string containing the license plate number (strictly
// speaking not a "number" since license plates may contain letters)
class FastTrakAccount {
public:
FastTrakAccount(int account_number, int balance, int transponder_id, string& plate_number) {
assert(!plate_number.empty());
_account_number = account_number;
_balance = balance;
_transponder_id = transponder_id;
_plate_number = plate_number;
}
// Accessors.
int account_number() { return _account_number; }
int balance() { return _balance; }
int transponder_id() { return _transponder_id; }
string& plate_number() { return _plate_number; }
// Mutators.
void set_balance(int newBalance) { _balance = newBalance; }
// Debit (subtract) a number of cents against this account. cents must be
// a positive number of cents. balance will decrease by cents.
void debit(int cents, FastTrakAccount accountDebit) {
if (cents > 0) {
accountDebit._balance -= cents;
set_balance(accountDebit._balance);
}
}
// Credit (add) a number of cents toward this account. cents must be a
// positive number of cents. balance will increase by cents.
void credit(int cents, FastTrakAccount accountCredit) {
if(cents > 0) {
accountCredit._balance += cents;
set_balance(accountCredit._balance);
}
}
private:
int _account_number, _balance, _transponder_id;
string _plate_number;
};
// Represents a toll violation, meaning that a motorist drove using the
// One-Time-Toll option, but never followed through on paying the toll
// within the 5-day grace period. This becomes a traffic ticket that
// the motorist will have to pay. A Violation is defined only by a
// license plate number and a balance, in units of cents.
class Violation {
public:
Violation(string& plate_number, int balance) {
assert(!plate_number.empty());
assert(balance > 0);
_plate_number = plate_number;
_balance = balance;
}
// Accessors.
string& plate_number() { return _plate_number; }
int balance() { return _balance; }
private:
string _plate_number;
int _balance;
};
template <typename ELT>
class DoublyLinkedNode {
public:
DoublyLinkedNode(DoublyLinkedNode<ELT>* prev, ELT element, DoublyLinkedNode<ELT>* next) {
_prev = prev;
_element = element;
_next = next;
}
DoublyLinkedNode<ELT>* prev() {
return _prev;
}
ELT element() {
return _element;
}
DoublyLinkedNode<ELT>* next() {
return _next;
}
void set_prev(DoublyLinkedNode<ELT>* prev) {
_prev = prev;
}
void set_element(ELT element) {
_element = element;
}
void set_next(DoublyLinkedNode<ELT>* next) {
_next = next;
}
private:
ELT _element;
DoublyLinkedNode<ELT> *_prev, *_next;
};
template<typename ELT>
class DoublyLinkedListIterator;
template <typename ELT>
class DoublyLinkedList {
friend class DoublyLinkedListIterator<ELT>;
public:
DoublyLinkedList() {
// Create header and trailer nodes.
_header = new DoublyLinkedNode<ELT>(nullptr, ELT(), nullptr);
_trailer = new DoublyLinkedNode<ELT>(nullptr, ELT(), nullptr);
// Make the header and trailer point to each other.
_header->set_next(_trailer);
_trailer->set_prev(_header);
_length = 0;
}
~DoublyLinkedList() {
// Remove all nodes.
clear();
// Free the header and trailer too.
delete _header;
delete _trailer;
}
int length() { return _length; }
bool is_empty() {
// There are at least two valid ways we could implement this.
assert( (_header->next() == _trailer) == (0 == _length) );
return (0 == _length);
}
ELT front() {
assert(!is_empty());
return _header->next()->element();
}
ELT back() {
assert(!is_empty());
return _trailer->prev()->element();
}
void add_front(ELT e) {
// Note that _header->next() is valid, even when the list is
// empty, due to the trailer node.
add_before(_header->next(), e);
}
void add_back(ELT e) {
add_before(_trailer, e);
}
void remove_front() {
remove(_header->next());
}
void remove_back() {
remove(_trailer->prev());
}
void clear() {
while (!is_empty())
remove_front();
}
private:
DoublyLinkedNode<ELT> *_header, *_trailer;
int _length;
void add_before(DoublyLinkedNode<ELT>* where, ELT e) {
assert(nullptr != where);
DoublyLinkedNode<ELT>* new_node = new DoublyLinkedNode<ELT>(where->prev(), e, where);
where->prev()->set_next(new_node);
where->set_prev(new_node);
_length++;
}
void remove(DoublyLinkedNode<ELT>* where) {
assert(nullptr != where);
assert(!is_empty());
where->prev()->set_next(where->next());
where->next()->set_prev(where->prev());
delete where;
_length--;
}
};
// This iterator class is almost the same as for a singly linked
// list. The main difference is that we are past the end when the
// location pointer is at the trailer node; in other words, we are
// past the end when the current location's next is nullptr.
template<typename ELT>
class DoublyLinkedListIterator {
private:
DoublyLinkedNode<ELT> *_location;
public:
DoublyLinkedListIterator(DoublyLinkedList<ELT>* list) {
assert(nullptr != list);
_location = list->_header->next();
}
bool past_end() { return (nullptr == _location->next()); }
ELT get() {
assert(!past_end());
return _location->element();
}
void advance() {
assert(!past_end());
_location = _location->next();
}
};
// The TollAdministrator class manages the entire process of tracking
// accounts, trips, and violations. It owns:
//
// - A list of FastTrakAccount objects, representing registered FastTrak
// accounts.
//
// - A list of unpaid LicenseTrip objects. When a motorist without a FastTrak
// account drives through the tolls, their license plate is recorded, and
// they have up to five days to pay the toll.
//
// - A list of Violation objects. When a LicenseTrip goes 5 days without being
// paid off, it becomes a violation.
class TollAdministrator {
public:
DoublyLinkedList<FastTrakAccount> FastTrakAccountList;
DoublyLinkedList<LicenseTrip> LicenseAccountList;
DoublyLinkedList<Violation> ViolationAccountList;
// Create a new TollAdministrator, where the account list,
// unpaid trip list, and violation list are all initially empty.
TollAdministrator() {
// TODO: REWRITE THIS FUNCTION
}
// Destructor. This should delete any objects remaining in any
// of the three lists.
~TollAdministrator() {
// TODO: REWRITE THIS FUNCTION
}
// Accessors. Each list has a _count() accessor that returns the
// number of elements in the list, and an accessor that returns
// one of the elements of the list by index.
// Return the number of FasTrak accounts.
int account_count() {
// TODO: REWRITE THIS FUNCTION
return { FastTrakAccountList.length() };
return 0;
}
// Return the FasTrak account at index i, which must satisfy
// (i >= 0) && (i < account_count()) .
FastTrakAccount& account(int i) {
DoublyLinkedList<FastTrakAccount> *accountReturn = new DoublyLinkedList<FastTrakAccount>;
while((i >= 0) && (i < account_count()))
{
accountReturn->add_front(FastTrakAccountList.front());
}
//return FastTrakAccount nullptr
return *((FastTrakAccount*) nullptr);
}
// Return the number of unpaid LicenseTrip objects.
int unpaid_count() {
return { LicenseAccountList.length() };
return 0;
}
// Return the unpaid LicenseTrip at index i, which must satisfy
// (i >= 0) && (i < unpaid_count()) .
LicenseTrip& unpaid(int i) {
DoublyLinkedList<LicenseTrip> *accountReturn = new DoublyLinkedList<LicenseTrip>;
while((i >= 0) && (i < unpaid_count()))
{
accountReturn->add_front(LicenseAccountList.front());
}
//return LicenseTrip nullptr
return *((LicenseTrip*) nullptr);
}
// Return the number of Violation objects.
int violation_count() {
return { ViolationAccountList.length() };
return 0;
}
// Return the Violation object at index i, which must satisfy
// (i >= 0) && (i < violation_count()) .
Violation& violation(int i) {
DoublyLinkedList<Violation> *accountReturn = new DoublyLinkedList<Violation>;
while((i >= 0) && (i < violation_count()))
{
accountReturn->add_front(ViolationAccountList.front());
}
//return Violation nullptr
return *((Violation*) nullptr);
}
// Add a new FastTrak account object. account must not be a nullptr.
// This increments account_count(). This TollAdministrator class is
// responsible for deleting the account object in the TollAdministrator
// destructor.
void register_account(FastTrakAccount* account) {
assert(account != nullptr);
FastTrakAccountList.add_front(*account);
FastTrakAccountList.length();
}
// Register a TransponderTrip object. trip must not be nullptr.
// If there is a registered FastTrakAccount whose transponder_id()
// matches trip's transponder_id(), then debit the toll for the
// trip from the matching account. If there is no matching account,
// that means the transponder is obsolete or invalid, so ignore
// the trip. In either case, this function should delete the trip
// object.
void register_transponder_trip(TransponderTrip* trip) {
assert(trip != nullptr);
// TODO: REWRITE THIS FUNCTION
}
// Register a LicenseTrip object. trip must not be nullptr.
// This function adds trip to the end of the unpaid list, which
// increments unpaid_count(). This TripAdministrator class is
// responsible for eventually deleting the trip object. The trip
// may get deleted when it is paid off on time; or when the
// trip transforms into a Violation object; or if neither of those
// ever happen, the trip must be deleted in TripAdministrator's
// destructor.
void register_license_trip(LicenseTrip* trip) {
assert(trip != nullptr);
// TODO: REWRITE THIS FUNCTION
}
// Register a one-time payment. If there are any unpaid LicenseTrip
// objects whose plate_number() matches plate_number(), and whose
// toll cost is less than or equal to cents, then the matching
// unpaid LicenseTrip is considered paid off and should be deleted,
// decrementing unpaid_count(). Otherwise (there are no matches),
// this function has no effect.
void one_time_payment(string& plate_number, int cents) {
// TODO: REWRITE THIS FUNCTION
}
// Charge the monthly maintenance fee to all FastTrak accounts.
// This should debit ACCOUNT_MAINTENANCE_FEE_CENTS from each
// account.
void debit_monthly_fees() {
// TODO: REWRITE THIS FUNCTION
}
// Check for unpaid LicenseTrip objects whose grace period has
// expired, and should be converted to Violation objects. This should
// check each LicenseTrip to see if its time() is more than GRACE_PERIOD_DAYS
// in the past, relative to current_time. This is computed based on
// the unix_time() data member (remember that this is recorded in units of
// seconds, not days). LicenseTrips that haven't expired yet are left
// unchanged. For each trip that has expired, the trip is removed from the
// unpaid list, decrementing unpaid_count(); and a new Violation is added
// to the violation list, incrementing violation_count().
void update_violations(Timestamp& current_time) {
// TODO: REWRITE THIS FUNCTION
}
private:
// TODO: ADD DATA MEMBERS
};
Explanation / Answer
#include "stdafx.h"
#include <string>
#include <cassert>
#include <iostream>
#include <list>
#include <map>
using namespace std;
// one million
const int MILLION = 1000 * 1000;
// maximum size of internal data structures
const int MAX_ACCOUNTS = 40 * MILLION;
const int MAX_UNPAID = 1 * MILLION;
const int MAX_VIOLATIONS = 2 * MILLION;
// Toll Roads policies
const int ACCOUNT_MAINTENANCE_FEE_CENTS = 200; // $2 in units of cents
const int VIOLATION_PENALTY_CENTS = 5750; // $57.50 in units of cents
const int GRACE_PERIOD_DAYS = 5;
// Days of the week.
enum DayOfWeek {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
};
// All onramps on the 73. The enum values are assigned explicit integer values
// in case you want to use them as array indices.
enum Onramp {
>>>>>>>>> ////////////////////////////////////
>>>>>>> //////////////////////////////
};
// All offramps on the 73.
enum Offramp {
OFFRAMP_UNKNOWN_NORTHBOUND = 0,
OFFRAMP_405 = 1,
OFFRAMP_BEAR = 2,
OFFRAMP_55 = 3,
OFFRAMP_IRVINE = 4,
OFFRAMP_JAMBOREE = 5,
OFFRAMP_UNIVERSITY = 6,
OFFRAMP_MACARTHUR = 7,
OFFRAMP_BISON = 8,
OFFRAMP_BONITA_CANYON = 9,
OFFRAMP_NEWPORT_COAST = 10,
OFFRAMP_EL_TORO = 11,
OFFRAMP_GLENWOOD = 12,
OFFRAMP_ALISO_CREEK = 13,
OFFRAMP_LA_PAZ = 14,
OFFRAMP_GREENFIELD = 15,
OFFRAMP_5 = 16,
OFFRAMP_UNKNOWN_SOUTHBOUND = 17,
};
// Represents a point in time, including:
// - Unix time (whole seconds since midnight 1/1/1970)
// - day of the week
// - hour (using military time, so this must be 1 through 23)
// - minute (must be 0 through 59)
class Timestamp {
public:
Timestamp(int unix_time, DayOfWeek day_of_week, int hour, int minute) {
assert(unix_time >= 0);
assert((hour >= 0) && (hour <= 23));
assert((minute >= 0) && (minute <= 59));
_unix_time = unix_time;
_day_of_week = day_of_week;
_hour = hour;
_minute = minute;
}
// Default constructor, leaving all fields uninitialized.
Timestamp() { }
// Accessors.
int unix_time() { return _unix_time; }
DayOfWeek day_of_week() { return _day_of_week; }
int hour() { return _hour; }
int minute() { return _minute; }
// Comparison operator. This is needed by some of the unit tests in main().
bool operator==(const Timestamp& right) const {
return ((_day_of_week == right._day_of_week) &&
(_unix_time == right._unix_time) &&
(_hour == right._hour) &&
(_minute == right._minute));
}
private:
DayOfWeek _day_of_week;
int _unix_time, _hour, _minute;
};
// Return the price of the toll, in units of cents, for a given trip.
//
// When is_fastrak is true, use FasTrak prices; otherwise use One-Time-Toll prices.
//
// time indicates when the trip happened, which factors into some FasTrak trips
// that happen during rush hour.
//
// start and end indicate the endpoints of the trip.
//
// All trips should be for 2 Axle Vehicles & Motorcycles (page 1 of the price
// matrix PDF).
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int calculate_toll(bool is_fastrak, Timestamp& time, Onramp start, Offramp end) {
//test is the start and end availiable
if (start == end)
{
return 0;
}
else if (start < 0 || start >17 || end < 0 || end > 17)
{
return 0;
}
else if (start==0 && end==17|| start == 17 && end == 0 ||end == 4 || end == 5 || end == 6|| start ==5 || start < 9 && end < 9 || start== 12 && end>12 || end==12 && start > 12|| start>14 && end>14)
{
return 0;
}
int moneyCharged = 0;
bool isHeadingNorth; //check heading south or north
if (start < end)
{
isHeadingNorth = false; //southbound
}
else
{
isHeadingNorth = true; //northbound
}
// check if driver has fast track
if (is_fastrak)
{
if (start >= 1 && start <= 4 || start >= 6 && start <= 8)
{
if (end == 9)
{
moneyCharged += 102;
}
else if (end == 10)
{
moneyCharged += 231;
}
else if (end >= 11 && end <= 16)
{
moneyCharged += 525;
}
}
else if (start == 9)
{
if (end >= 1 && end && end <= 3 || end >= 7 && end <= 8)
{
moneyCharged += 102;
}
else if (end == 10)
{
moneyCharged += 231;
}
else if (end > 10)
{
moneyCharged += 525;
}
}
else if (start == 10)
{
if (end >= 1 && end && end <= 3 || end >= 7 && end <= 9)
{
moneyCharged += 231;
}
else if (end > 10)
{
moneyCharged += 525;
}
}
else if (start >= 11 && start <= 16 && end >= 1 && end <= 11)
{
if (end >= 1 && end <= 10)
{
moneyCharged += 525;
}
else if (end == 11)
{
moneyCharged += 257;
}
}
else if (start == 11 && end >= 13 && end <= 16)
{
moneyCharged += 257;
}
else if (start == 13 && end >= 14 && end <= 16) {
moneyCharged += 195;
}
else if (start == 14 && end >= 13 && end <= 16)
{
if (end == 13)
{
moneyCharged += 195;
}
else if (end == 15 || end == 16)
{
moneyCharged += 137;
}
}
else if (start <= 16 && start >= 15 && end <= 14 && end >= 13)
{
if (end == 13)
{
moneyCharged += 195;
}
else if (end == 14)
{
moneyCharged += 137;
}
}
// check time
if (moneyCharged > 300)
{
if (time.day_of_week() == SATURDAY || time.day_of_week() == SUNDAY) // is weekend?
{
moneyCharged -= 25;
}
else //weekdays
{
if (isHeadingNorth)
{
if (time.hour() >= 8 && time.hour() < 9)
{
moneyCharged += 153;
}
else if (time.hour() >= 7 && time.hour() < 8 || time.hour() >= 9 && time.hour() < 10)
{
moneyCharged += 123;
}
}
else if (!isHeadingNorth)
{
if (time.hour() >= 17 && time.hour() < 18)
{
moneyCharged += 153;
}
else if (time.hour() >= 15 && time.hour() < 17 || time.hour() >= 18 && time.hour() < 19)
{
moneyCharged += 123;
}
}
}
}
}
else
{
// if driver doesn't have fast track, then it is a one time toll
// if driver entered between northbound and bison and exited after bonita
if (start >= 1 && start <= 4 || start >= 6 && start <= 8)
{
if (end == 9)
{
moneyCharged += 202;
}
else if (end == 10)
{
moneyCharged += 331;
}
else if (end >= 11)
{
moneyCharged += 748;
}
}
else if (start == 9)
{
if (end >= 0 && end <= 3)
{
moneyCharged += 202;
}
else if (end >= 7 && end <= 8)
{
moneyCharged += 202;
}
else if (end == 10)
{
moneyCharged += 331;
}
else if (end >= 11)
{
moneyCharged += 748;
}
}
else if (start == 10)
{
if (end >= 0 && end <= 3)
{
moneyCharged += 331;
}
else if (end >= 7 && end <= 9)
{
moneyCharged += 331;
}
else if (end >= 11)
{
moneyCharged += 748;
}
}
else if (start >= 11 && end >= 0 && end <= 11)
{
if (end >= 0 && end <= 3)
{
moneyCharged += 748;
}
else if (end >= 7 && end <= 10)
{
moneyCharged += 748;
}
else if (end == 11)
{
moneyCharged += 357;
}
}
else if (start == 11 && end > 12) {
moneyCharged += 357;
}
else if (start >= 14 && start <= 17 && end == 15)
{
moneyCharged += 295;
}
else if (start == 13 && end >= 14 && end <= 17)
{
moneyCharged += 295;
}
else if(start == 14 && end >= 15 && end <= 17)
{
moneyCharged += 237;
}
else if (start >= 15 && start <= 17 && end == 14)
{
moneyCharged += 237;
}
}
if(start == 17 && end == 11)
{
int blah = 0;
}
return moneyCharged;
}
// A trip recored by a FasTrak transponder inside the car of someone with a
// registered FasTrak account. Each transponder has an integer transponder_id
// which is unique to the transponder device, and is linked to the owner's
// account.
class TransponderTrip {
public:
TransponderTrip(Timestamp time, Onramp start, Offramp end, int transponder_id) {
_time = time;
_start = start;
_end = end;
_transponder_id = transponder_id;
}
// Accessors.
Timestamp& time() { return _time; }
Onramp start() { return _start; }
Offramp end() { return _end; }
int transponder_id() { return _transponder_id; }
private:
Timestamp _time;
Onramp _start;
Offramp _end;
int _transponder_id;
};
// A trip recored by the license plate cameras. This represents a trip taken
// by someone without any FasTrak account.
class LicenseTrip {
public:
LicenseTrip(){}
LicenseTrip(Timestamp time, Onramp start, Offramp end, string& plate_number) {
assert(!plate_number.empty());
_time = time;
_start = start;
_end = end;
_plate_number = plate_number;
}
// Accessors.
Timestamp& time() { return _time; }
Onramp start() { return _start; }
Offramp end() { return _end; }
string& plate_number() { return _plate_number; }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Compute the toll, in cents, of this trip.
int toll(bool is_fastrack, Timestamp& time, Onramp start, Offramp end) {
// TODO: REWRITE THIS FUNCTION
// hint: call calculate_toll()
int tollTotal = calculate_toll(is_fastrack, time, start, end);
return tollTotal;
}
private:
Timestamp _time;
Onramp _start;
Offramp _end;
string _plate_number;
};
// Represents a FasTrak account. Each account has
//
// - account_number, a unique integer that identifies the account.
//
// - balance, the amount of money owed, in units of cents. A negative
// balance means that the account holder owes money.
//
// - transponder_id, the integer transponder ID linked to this account.
//
// - plate_number, a string containing the license plate number (strictly
// speaking not a "number" since license plates may contain letters)
class FastTrakAccount {
public:
FastTrakAccount() {
}
FastTrakAccount(int account_number, int balance, int transponder_id, string& plate_number) {
assert(!plate_number.empty());
AccountNumber = account_number;
Balance = balance;
TransponderId = transponder_id;
PlateNumber = plate_number;
}
int AccountNumber;
int Balance;
int TransponderId;
string PlateNumber;
// Accessors.
int account_number() { return AccountNumber; }
int balance() { return Balance; }
int transponder_id() { return TransponderId; }
string& plate_number() { return PlateNumber; }
void setBalance(int newBalance)
{
Balance = newBalance;
}
// Debit (subtract) a number of cents against this account. cents must be
// a positive number of cents. balance will decrease by cents.
void debit(int cents, FastTrakAccount accountToUpdate) {
if ( cents > 0)
{
accountToUpdate.Balance -= cents;
setBalance(accountToUpdate.Balance);
}
}
// Credit (add) a number of cents toward this account. cents must be a
// positive number of cents. balance will increase by cents.
void credit(int cents, FastTrakAccount accountToUpdate) {
if ( cents > 0)
{
accountToUpdate.Balance += cents;
setBalance(accountToUpdate.Balance);
int blah = 0;
}
}
private:
int _account_number, _balance, _transponder_id;
string _plate_number;
};
// Represents a toll violation, meaning that a motorist drove using the
// One-Time-Toll option, but never followed through on paying the toll
// within the 5-day grace period. This becomes a traffic ticket that
// the motorist will have to pay. A Violation is defined only by a
// license plate number and a balance, in units of cents.
class Violation {
public:
Violation(){}
Violation(string& plate_number, int balance) {
assert(!plate_number.empty());
assert(balance > 0);
_plate_number = plate_number;
_balance = balance;
}
// Accessors.
string& plate_number() { return _plate_number; }
int balance() { return _balance; }
private:
string _plate_number;
int _balance;
};
template <typename ELT>
class DoublyLinkedNode {
public:
DoublyLinkedNode(DoublyLinkedNode<ELT>* prev, ELT element, DoublyLinkedNode<ELT>* next) {
_prev = prev;
_element = element;
_next = next;
}
DoublyLinkedNode<ELT>* prev() {
return _prev;
}
ELT element() {
return _element;
}
DoublyLinkedNode<ELT>* next() {
return _next;
}
void set_prev(DoublyLinkedNode<ELT>* prev) {
_prev = prev;
}
void set_element(ELT element) {
_element = element;
}
void set_next(DoublyLinkedNode<ELT>* next) {
_next = next;
}
private:
ELT _element;
DoublyLinkedNode<ELT> *_prev, *_next;
};
template<typename ELT>
class DoublyLinkedListIterator;
template <typename ELT>
class DoublyLinkedList {
friend class DoublyLinkedListIterator<ELT>;
public:
DoublyLinkedList() {
// Create header and trailer nodes.
_header = new DoublyLinkedNode<ELT>(nullptr, ELT(), nullptr);
_trailer = new DoublyLinkedNode<ELT>(nullptr, ELT(), nullptr);
// Make the header and trailer point to each other.
_header->set_next(_trailer);
_trailer->set_prev(_header);
_length = 0;
}
~DoublyLinkedList() {
// Remove all nodes.
clear();
// Free the header and trailer too.
delete _header;
delete _trailer;
}
int length() { return _length; }
bool is_empty() {
// There are at least two valid ways we could implement this.
assert( (_header->next() == _trailer) == (0 == _length) );
return (0 == _length);
}
ELT front() {
assert(!is_empty());
return _header->next()->element();
}
ELT back() {
assert(!is_empty());
return _trailer->prev()->element();
}
void add_front(ELT e) {
// Note that _header->next() is valid, even when the list is
// empty, due to the trailer node.
add_before(_header->next(), e);
}
void add_back(ELT e) {
add_before(_trailer, e);
}
void remove_front() {
remove(_header->next());
}
void remove_back() {
remove(_trailer->prev());
}
void clear() {
while (!is_empty())
remove_front();
}
private:
DoublyLinkedNode<ELT> *_header, *_trailer;
int _length;
void add_before(DoublyLinkedNode<ELT>* where, ELT e) {
assert(nullptr != where);
DoublyLinkedNode<ELT>* new_node = new DoublyLinkedNode<ELT>(where->prev(), e, where);
where->prev()->set_next(new_node);
where->set_prev(new_node);
_length++;
}
void remove(DoublyLinkedNode<ELT>* where) {
assert(nullptr != where);
assert(!is_empty());
where->prev()->set_next(where->next());
where->next()->set_prev(where->prev());
delete where;
_length--;
}
};
// This iterator class is almost the same as for a singly linked
// list. The main difference is that we are past the end when the
// location pointer is at the trailer node; in other words, we are
// past the end when the current location's next is nullptr.
template<typename ELT>
class DoublyLinkedListIterator {
private:
DoublyLinkedNode<ELT> *_location;
public:
DoublyLinkedListIterator(DoublyLinkedList<ELT>* list) {
assert(nullptr != list);
_location = list->_header->next();
}
bool past_end() { return (nullptr == _location->next()); }
ELT get() {
assert(!past_end());
return _location->element();
}
void advance() {
assert(!past_end());
_location = _location->next();
}
};
// The TollAdministrator class manages the entire process of tracking
// accounts, trips, and violations. It owns:
//
// - A list of FastTrakAccount objects, representing registered FastTrak
// accounts.
//
// - A list of unpaid LicenseTrip objects. When a motorist without a FastTrak
// account drives through the tolls, their license plate is recorded, and
// they have up to five days to pay the toll.
//
// - A list of Violation objects. When a LicenseTrip goes 5 days without being
// paid off, it becomes a violation.
class TollAdministrator {
public:
DoublyLinkedList<FastTrakAccount> AccountList;
// Create a new TollAdministrator, where the account list,
// unpaid trip list, and violation list are all initially empty.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TollAdministrator() {
// TODO: REWRITE THIS FUNCTION
}
// Destructor. This should delete any objects remaining in any
// of the three lists.
~TollAdministrator() {
// TODO: REWRITE THIS FUNCTION
}
// Accessors. Each list has a _count() accessor that returns the
// number of elements in the list, and an accessor that returns
// one of the elements of the list by index.
// Return the number of FasTrak accounts.
int account_count() {
return AccountList.length();
}
// Return the FasTrak account at index i, which must satisfy
// (i >= 0) && (i < account_count()) .
FastTrakAccount& account(int i) {
// TODO: REWRITE THIS FUNCTION
int counter = 0;
DoublyLinkedList<FastTrakAccount> *accountToReturn = new DoublyLinkedList<FastTrakAccount>;
accountToReturn->add_front(AccountList.front);
while(counter < i)
{
}
//return FastTrakAccount nullptr;
}
// Return the number of unpaid LicenseTrip objects.
int unpaid_count() {
// TODO: REWRITE THIS FUNCTION
return 0;
}
// Return the unpaid LicenseTrip at index i, which must satisfy
// (i >= 0) && (i < unpaid_count()) .
LicenseTrip& unpaid(int index) {
// TODO: REWRITE THIS FUNCTION
return *((LicenseTrip*) nullptr);
}
// Return the number of Violation objects.
int violation_count() {
// TODO: REWRITE THIS FUNCTION
return 0;
}
// Return the Violation object at index i, which must satisfy
// (i >= 0) && (i < violation_count()) .
Violation& violation(int index) {
// TODO: REWRITE THIS FUNCTION
return *((Violation*) nullptr);
}
// Add a new FastTrak account object. account must not be a nullptr.
// This increments account_count(). This TollAdministrator class is
// responsible for deleting the account object in the TollAdministrator
// destructor.
void register_account(FastTrakAccount* account) {
assert(account != nullptr);
AccountList.add_back(*account);
AccountList.length();
// TODO: REWRITE THIS FUNCTION
}
// Register a TransponderTrip object. trip must not be nullptr.
// If there is a registered FastTrakAccount whose transponder_id()
// matches trip's transponder_id(), then debit the toll for the
// trip from the matching account. If there is no matching account,
// that means the transponder is obsolete or invalid, so ignore
// the trip. In either case, this function should delete the trip
// object.
void register_transponder_trip(TransponderTrip* trip) {
assert(trip != nullptr);
// TODO: REWRITE THIS FUNCTION
}
// Register a LicenseTrip object. trip must not be nullptr.
// This function adds trip to the end of the unpaid list, which
// increments unpaid_count(). This TripAdministrator class is
// responsible for eventually deleting the trip object. The trip
// may get deleted when it is paid off on time; or when the
// trip transforms into a Violation object; or if neither of those
// ever happen, the trip must be deleted in TripAdministrator's
// destructor.
void register_license_trip(LicenseTrip* trip) {
assert(trip != nullptr);
// TODO: REWRITE THIS FUNCTION
}
// Register a one-time payment. If there are any unpaid LicenseTrip
// objects whose plate_number() matches plate_number(), and whose
// toll cost is less than or equal to cents, then the matching
// unpaid LicenseTrip is considered paid off and should be deleted,
// decrementing unpaid_count(). Otherwise (there are no matches),
// this function has no effect.
void one_time_payment(string& plate_number, int cents) {
// TODO: REWRITE THIS FUNCTION
}
// Charge the monthly maintenance fee to all FastTrak accounts.
// This should debit ACCOUNT_MAINTENANCE_FEE_CENTS from each
// account.
void debit_monthly_fees() {
// TODO: REWRITE THIS FUNCTION
}
// Check for unpaid LicenseTrip objects whose grace period has
// expired, and should be converted to Violation objects. This should
// check each LicenseTrip to see if its time() is more than GRACE_PERIOD_DAYS
// in the past, relative to current_time. This is computed based on
// the unix_time() data member (remember that this is recorded in units of
// seconds, not days). LicenseTrips that haven't expired yet are left
// unchanged. For each trip that has expired, the trip is removed from the
// unpaid list, decrementing unpaid_count(); and a new Violation is added
// to the violation list, incrementing violation_count().
void update_violations(Timestamp& current_time) {
// TODO: REWRITE THIS FUNCTION
}
private:
// TODO: ADD DATA MEMBERS
};
// This main() function runs through a set of unit tests using the assert(...) macro.
// If all of the above classes are implemented correctly, this program will run
// succesfully. If the classes have a bug, the program will crash with an assertion
// error, which is hopefully helpful.
//
// YOU MUST LEAVE THE DEFINITION OF main() UNCHANGED.
int main()
{
Timestamp monday(1, MONDAY, 2, 3);
string plate("123456");
// Timestamp
{
assert(1 == monday.unix_time());
assert(MONDAY == monday.day_of_week());
assert(2 == monday.hour());
assert(3 == monday.minute());
assert(monday == Timestamp(1, MONDAY, 2, 3));
}
// calculate_toll
{
Timestamp sat(1, SATURDAY, 9, 0),
sun(1, SUNDAY, 9, 0),
sb_peak(1, MONDAY, 17, 1),
sb_before_peak(1, MONDAY, 15, 1),
sb_after_peak(1, MONDAY, 18, 1),
nb_peak(1, MONDAY, 8, 1),
nb_before_peak(1, MONDAY, 7, 1),
nb_after_peak(1, MONDAY, 9, 1);
// diagonal entry
assert(0 == calculate_toll(false, sat, ONRAMP_MACARTHUR, OFFRAMP_MACARTHUR));
// other black entry
assert(0 == calculate_toll(false, sat, ONRAMP_BRISTOL, OFFRAMP_GREENFIELD));
// crossed-out entry
assert(0 == calculate_toll(true, sat, ONRAMP_UNKNOWN_SOUTHBOUND, OFFRAMP_UNKNOWN_SOUTHBOUND));
assert(0 == calculate_toll(true, sat, ONRAMP_UNKNOWN_NORTHBOUND, OFFRAMP_UNKNOWN_NORTHBOUND));
// trip that is the same price at all times
assert(102 == calculate_toll(true, sat, ONRAMP_55, OFFRAMP_BONITA_CANYON));
assert(102 == calculate_toll(true, sun, ONRAMP_55, OFFRAMP_BONITA_CANYON));
assert(102 == calculate_toll(true, sb_peak, ONRAMP_55, OFFRAMP_BONITA_CANYON));
assert(102 == calculate_toll(true, sb_before_peak, ONRAMP_55, OFFRAMP_BONITA_CANYON));
assert(102 == calculate_toll(true, sb_after_peak, ONRAMP_55, OFFRAMP_BONITA_CANYON));
assert(102 == calculate_toll(true, nb_peak, ONRAMP_55, OFFRAMP_BONITA_CANYON));
assert(102 == calculate_toll(true, nb_before_peak, ONRAMP_55, OFFRAMP_BONITA_CANYON));
assert(102 == calculate_toll(true, nb_after_peak, ONRAMP_55, OFFRAMP_BONITA_CANYON));
assert(202 == calculate_toll(false, sat, ONRAMP_55, OFFRAMP_BONITA_CANYON));
assert(202 == calculate_toll(false, sun, ONRAMP_55, OFFRAMP_BONITA_CANYON));
assert(202 == calculate_toll(false, sb_peak, ONRAMP_55, OFFRAMP_BONITA_CANYON));
assert(202 == calculate_toll(false, sb_before_peak, ONRAMP_55, OFFRAMP_BONITA_CANYON));
assert(202 == calculate_toll(false, sb_after_peak, ONRAMP_55, OFFRAMP_BONITA_CANYON));
assert(202 == calculate_toll(false, nb_peak, ONRAMP_55, OFFRAMP_BONITA_CANYON));
assert(202 == calculate_toll(false, nb_before_peak, ONRAMP_55, OFFRAMP_BONITA_CANYON));
assert(202 == calculate_toll(false, nb_after_peak, ONRAMP_55, OFFRAMP_BONITA_CANYON));
// northbound variable-price trip
assert((525 - 25) == calculate_toll(true, sat, ONRAMP_FAIRVIEW, OFFRAMP_ALISO_CREEK));
assert((525 - 25) == calculate_toll(true, sun, ONRAMP_FAIRVIEW, OFFRAMP_ALISO_CREEK));
assert((525 + 153) == calculate_toll(true, sb_peak, ONRAMP_FAIRVIEW, OFFRAMP_ALISO_CREEK));
assert((525 + 123) == calculate_toll(true, sb_before_peak, ONRAMP_FAIRVIEW, OFFRAMP_ALISO_CREEK));
assert((525 + 123) == calculate_toll(true, sb_after_peak, ONRAMP_FAIRVIEW, OFFRAMP_ALISO_CREEK));
assert(525 == calculate_toll(true, nb_peak, ONRAMP_FAIRVIEW, OFFRAMP_ALISO_CREEK));
assert(525 == calculate_toll(true, nb_before_peak, ONRAMP_FAIRVIEW, OFFRAMP_ALISO_CREEK));
assert(525 == calculate_toll(true, nb_after_peak, ONRAMP_FAIRVIEW, OFFRAMP_ALISO_CREEK));
assert(748 == calculate_toll(false, sat, ONRAMP_FAIRVIEW, OFFRAMP_ALISO_CREEK));
assert(748 == calculate_toll(false, sun, ONRAMP_FAIRVIEW, OFFRAMP_ALISO_CREEK));
assert(748 == calculate_toll(false, sb_peak, ONRAMP_FAIRVIEW, OFFRAMP_ALISO_CREEK));
assert(748 == calculate_toll(false, sb_before_peak, ONRAMP_FAIRVIEW, OFFRAMP_ALISO_CREEK));
assert(748 == calculate_toll(false, sb_after_peak, ONRAMP_FAIRVIEW, OFFRAMP_ALISO_CREEK));
assert(748 == calculate_toll(false, nb_peak, ONRAMP_FAIRVIEW, OFFRAMP_ALISO_CREEK));
assert(748 == calculate_toll(false, nb_before_peak, ONRAMP_FAIRVIEW, OFFRAMP_ALISO_CREEK));
assert(748 == calculate_toll(false, nb_after_peak, ONRAMP_FAIRVIEW, OFFRAMP_ALISO_CREEK));
// southbound variable-price trip
assert((525 - 25) == calculate_toll(true, sat, ONRAMP_EL_TORO, OFFRAMP_55));
assert((525 - 25) == calculate_toll(true, sun, ONRAMP_EL_TORO, OFFRAMP_55));
assert(525 == calculate_toll(true, sb_peak, ONRAMP_EL_TORO, OFFRAMP_55));
assert(525 == calculate_toll(true, sb_before_peak, ONRAMP_EL_TORO, OFFRAMP_55));
assert(525 == calculate_toll(true, sb_after_peak, ONRAMP_EL_TORO, OFFRAMP_55));
assert((525 + 153) == calculate_toll(true, nb_peak, ONRAMP_EL_TORO, OFFRAMP_55));
assert((525 + 123) == calculate_toll(true, nb_before_peak, ONRAMP_EL_TORO, OFFRAMP_55));
assert((525 + 123) == calculate_toll(true, nb_after_peak, ONRAMP_EL_TORO, OFFRAMP_55));
assert(748 == calculate_toll(false, sat, ONRAMP_EL_TORO, OFFRAMP_55));
assert(748 == calculate_toll(false, sun, ONRAMP_EL_TORO, OFFRAMP_55));
assert(748 == calculate_toll(false, sb_peak, ONRAMP_EL_TORO, OFFRAMP_55));
assert(748 == calculate_toll(false, sb_before_peak, ONRAMP_EL_TORO, OFFRAMP_55));
assert(748 == calculate_toll(false, sb_after_peak, ONRAMP_EL_TORO, OFFRAMP_55));
assert(748 == calculate_toll(false, nb_peak, ONRAMP_EL_TORO, OFFRAMP_55));
assert(748 == calculate_toll(false, nb_before_peak, ONRAMP_EL_TORO, OFFRAMP_55));
assert(748 == calculate_toll(false, nb_after_peak, ONRAMP_EL_TORO, OFFRAMP_55));
// sample a few other tolls
assert(357 == calculate_toll(false, sb_peak, ONRAMP_UNKNOWN_NORTHBOUND, OFFRAMP_EL_TORO));
assert(0 == calculate_toll(true, sb_peak, ONRAMP_FAIRVIEW, OFFRAMP_JAMBOREE));
assert(202 == calculate_toll(false, sb_peak, ONRAMP_JAMBOREE, OFFRAMP_BONITA_CANYON));
assert((525 + 153) == calculate_toll(true, sb_peak, ONRAMP_BISON, OFFRAMP_GREENFIELD));
}
// TransponderTrip
{
TransponderTrip trip(monday, ONRAMP_405, OFFRAMP_5, 123);
assert(monday == trip.time());
assert(ONRAMP_405 == trip.start());
assert(OFFRAMP_5 == trip.end());
assert(123 == trip.transponder_id());
}
// LicenseTrip
{
LicenseTrip trip(monday, ONRAMP_405, OFFRAMP_5, plate);
assert(monday == trip.time());
assert(ONRAMP_405 == trip.start());
assert(OFFRAMP_5 == trip.end());
assert(plate == trip.plate_number());
assert(748 == trip.toll(false, trip.time(), trip.start(), trip.end()));
}
// FastTrakAccount
{
FastTrakAccount account(1, 2, 3, plate);
assert(1 == account.account_number());
assert(2 == account.balance());
assert(3 == account.transponder_id());
assert(plate == account.plate_number());
// add $5
account.credit(500, account);
assert(502 == account.balance());
// remove $3
account.debit(300, account);
assert(202 == account.balance());
}
// Violation
{
Violation violation(plate, 123);
assert(plate == violation.plate_number());
assert(123 == violation.balance());
}
// TollAdministrator
{
TollAdministrator admin;
assert(0 == admin.account_count());
assert(0 == admin.unpaid_count());
assert(0 == admin.violation_count());
// register two accounts
FastTrakAccount* a1 = new FastTrakAccount(1, 0, 123, string("PLT1"));
FastTrakAccount* a2 = new FastTrakAccount(2, 0, 456, string("PLT2"));
admin.register_account(a1);
assert(1 == admin.account_count());
assert("PLT1" == admin.account(0).plate_number());
admin.register_account(a2);
assert(2 == admin.account_count());
assert("PLT1" == admin.account(0).plate_number());
assert("PLT2" == admin.account(1).plate_number());
// transponder trip for a2
TransponderTrip* t1 = new TransponderTrip(Timestamp(1, TUESDAY, 8, 21), ONRAMP_BEAR, OFFRAMP_GREENFIELD, 456);
admin.register_transponder_trip(t1);
assert(2 == admin.account_count());
assert(0 == admin.unpaid_count());
assert(0 == admin.violation_count());
assert(-525 == admin.account(1).balance());
// transponder trip for a1
TransponderTrip* t2 = new TransponderTrip(Timestamp(1, WEDNESDAY, 8, 21), ONRAMP_5, OFFRAMP_EL_TORO, 123);
admin.register_transponder_trip(t2);
assert(2 == admin.account_count());
assert(0 == admin.unpaid_count());
assert(0 == admin.violation_count());
assert(-257 == admin.account(0).balance());
// transponder trip for unrecognized transponder ID has no effect
TransponderTrip* t3 = new TransponderTrip(Timestamp(1, THURSDAY, 8, 21), ONRAMP_5, OFFRAMP_EL_TORO, 789);
admin.register_transponder_trip(t3);
assert(2 == admin.account_count());
assert(0 == admin.unpaid_count());
assert(0 == admin.violation_count());
assert(-257 == admin.account(0).balance());
assert(-525 == admin.account(1).balance());
// register two license trips
LicenseTrip* t4 = new LicenseTrip(Timestamp(1, MONDAY, 18, 41), ONRAMP_405, OFFRAMP_5, string("MRBIG"));
admin.register_license_trip(t4);
assert(2 == admin.account_count());
assert(1 == admin.unpaid_count());
assert(0 == admin.violation_count());
assert("MRBIG" == admin.unpaid(0).plate_number());
assert(748 == admin.unpaid(0).toll(false, t4->time(), t4->start(), t4->end()));
LicenseTrip* t5 = new LicenseTrip(Timestamp(1, SUNDAY, 11, 42), ONRAMP_405, OFFRAMP_5, string("EWING2"));
admin.register_license_trip(t5);
assert(2 == admin.account_count());
assert(2 == admin.unpaid_count());
assert(0 == admin.violation_count());
assert("EWING2" == admin.unpaid(1).plate_number());
assert(748 == admin.unpaid(1).toll(false, t5->time(), t5->start(), t5->end()));
// payment has no effect because it's too small
admin.one_time_payment(string("MRBIG"), 100);
assert(2 == admin.account_count());
assert(2 == admin.unpaid_count());
assert(0 == admin.violation_count());
// payment has no effect because the plate doesn't match
admin.one_time_payment(string("OUTATIME"), 800);
assert(2 == admin.account_count());
assert(2 == admin.unpaid_count());
assert(0 == admin.violation_count());
// pay second trip
admin.one_time_payment(string("EWING2"), 748);
assert(2 == admin.account_count());
assert(1 == admin.unpaid_count());
assert(0 == admin.violation_count());
assert("MRBIG" == admin.unpaid(0).plate_number());
// advance time a little bit; first trip isn't a violation yet
admin.update_violations(Timestamp(1000, MONDAY, 12, 12));
assert(2 == admin.account_count());
assert(1 == admin.unpaid_count());
assert(0 == admin.violation_count());
// advance time more than four days, so the first trip becomes a violation
admin.update_violations(Timestamp(MILLION, MONDAY, 12, 12));
assert(2 == admin.account_count());
assert(0 == admin.unpaid_count());
assert(1 == admin.violation_count());
assert("MRBIG" == admin.violation(0).plate_number());
assert((5750 + 748) == admin.violation(0).balance());
// monthly fees
admin.debit_monthly_fees();
assert(2 == admin.account_count());
assert(0 == admin.unpaid_count());
assert(1 == admin.violation_count());
assert(-457 == admin.account(0).balance());
assert(-725 == admin.account(1).balance());
}
cout << "Success, all tests passed." << endl;
return 0;
}