Move orders through a series of states.
What to build
A small state machine using a map and an enum class.
Requirements
- The states are
New,PaidandShipped. add IDcreates an order asNew, or printsexists.pay IDmoves it fromNewtoPaid.ship IDmoves it fromPaidtoShipped.- A command on a missing order prints
missing. A move not allowed from the current state printsnot allowed. reportprints each order in increasing ID order, asID state, with the state in lower case.
Input
The first line has n. Each of the next n lines is a command.
Output
Only what the commands above print.
Constraints
n is from 1 to 200.
Example
Input:
4
add 2
add 1
pay 2
report
Output:
1 new
2 paid
Why it works
Naming every state makes the rules read like the description, and the map keeps the orders sorted for the report.
Examples
Example 1 · Input
4 add 2 add 1 pay 2 report
Expected output
1 new 2 paid
Example 2 · Input
2 pay 9 add 1
Expected output
missing
Hints
Hint 1
Use map<int, Status>, with an enum class for the status.
Hint 2
Use count to check whether an order exists.
Hint 3
Only a New order can be paid, and only a Paid order can be shipped.
Solution
Show one correct solution (try it yourself first)
#include <iostream>
#include <map>
#include <string>
using namespace std;
enum class Status { New, Paid, Shipped };
string text_of(Status s) {
if (s == Status::New) return "new";
if (s == Status::Paid) return "paid";
return "shipped";
}
int main() {
int n;
cin >> n;
map<int, Status> orders;
for (int i = 0; i < n; i++) {
string command;
cin >> command;
if (command == "report") {
for (const auto& order : orders) {
cout << order.first << " " << text_of(order.second) << endl;
}
continue;
}
int id;
cin >> id;
if (command == "add") {
if (orders.count(id)) {
cout << "exists" << endl;
} else {
orders[id] = Status::New;
}
} else if (!orders.count(id)) {
cout << "missing" << endl;
} else if (command == "pay" && orders[id] == Status::New) {
orders[id] = Status::Paid;
} else if (command == "ship" && orders[id] == Status::Paid) {
orders[id] = Status::Shipped;
} else {
cout << "not allowed" << endl;
}
}
return 0;
}