Read a duration a human typed
A config file lets people write timeouts as "1h30m" instead of counting seconds, and the loader has to turn that into a number without trusting it.
- The units are h, m and s. Each may appear at most once, and they must be in that order.
- Each unit is preceded by a run of digits: "2h", "30m", "45s".
- An empty string is zero seconds.
- Anything that does not fit — a stray letter, a number with no unit, units out of order — gives -1.
parseDuration(text: string) → int
C++ needs a compiler and Drill does not host one yet, so this page is the reference rather than an exercise: the problem, worked examples, and the solution in full. To type it out, the same problem runs in Python.
Where you start
int parseDuration(std::string text) {
}
Worked examples
| Call | Result |
|---|---|
parseDuration(std::string("1h30m")) | 5400 |
parseDuration(std::string("45s")) | 45 |
parseDuration(std::string("2h")) | 7200 |
parseDuration(std::string("90m")) | 5400 |
Hint
Scan digits, then expect exactly one unit letter. Remember which units you have already taken so order and repeats are both caught by the same check.
Reference solution in C++
int parseDuration(std::string text) {
std::map<char, int> rank{{'h', 1}, {'m', 2}, {'s', 3}};
std::map<char, int> mult{{'h', 3600}, {'m', 60}, {'s', 1}};
size_t i = 0;
int total = 0, last = 0;
while (i < text.size()) {
int n = 0, digits = 0;
while (i < text.size() && text[i] >= '0' && text[i] <= '9') { n = n * 10 + (text[i] - '0'); i++; digits++; }
if (digits == 0 || i >= text.size()) return -1;
char u = text[i];
if (!rank.count(u) || rank[u] <= last) return -1;
last = rank[u];
total += n * mult[u];
i++;
}
return total;
}