Next Traffic Signal
National Olympiad — Municipal round (2021 season)
Submission name: traffic.cpp
Problem summary
A traffic signal has top red, middle yellow and bottom green sections. Its normal cycle is steady green → blinking green → steady yellow → steady red → red and yellow → steady green. Blinking yellow alone remains blinking yellow. Given the three section states, output the next state or error if the current state is invalid.
Input
Three characters, top to bottom: b for off; r,y,g for steady colours; uppercase letters for blinking colours.
Output
Three colour names on separate lines: black, red, yellow, green, uppercase for blinking; or error.
Constraints
The section description uses single-character colour codes. Only the five normal states and blinking-yellow state are valid.
Worked example
An independently prepared example for this explanation.
Input
b b g
Output
black black GREEN
Solution analysis
- Represent the three section codes as one string in top-to-bottom order. Enumerate the five valid states of the normal cycle explicitly.
- Find the current state and use the next entry, wrapping around after red-and-yellow. Treat bYb as a separate self-loop. Every other combination is an error.
- For bbg, green is steady, so the next state is bbG: two black sections and blinking GREEN. For bYb, output black, YELLOW, black again. A state ryg is invalid because all three lamps cannot be steady on.
Why it works
The table contains exactly the normal states and their prescribed successors. The additional blinking-yellow state follows its specified persistent mode. Therefore a matched input receives precisely its successor, and unmatched inputs are exactly the invalid states.
Watch out. Only the colour belonging to a section can light there. Preserve uppercase for blinking output. All black is an error, not a cycle state.
Commented C++17 solution
An independently written complete program with standard headers.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
string current;
for (int i = 0; i < 3; i++) {
char lamp;
cin >> lamp;
current += lamp;
}
// Each entry is a complete valid state, in cycle order.
vector<string> states = {"bbg", "bbG", "byb", "rbb", "ryb"};
string next;
if (current == "bYb") {
next = current;
}
for (int i = 0; i < 5; i++) {
if (current == states[i]) {
next = states[(i + 1) % 5];
}
}
if (next.empty()) {
cout << "error\n";
return 0;
}
for (char lamp : next) {
if (lamp == 'b') {
cout << "black\n";
} else if (lamp == 'r') {
cout << "red\n";
} else if (lamp == 'y') {
cout << "yellow\n";
} else if (lamp == 'g') {
cout << "green\n";
} else if (lamp == 'G') {
cout << "GREEN\n";
} else {
cout << "YELLOW\n";
}
}
}