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
Go 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
func parseDuration(text string) int {
}
Worked examples
| Call | Result |
|---|---|
parseDuration("1h30m") | 5400 |
parseDuration("45s") | 45 |
parseDuration("2h") | 7200 |
parseDuration("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 Go
func parseDuration(text string) int {
rank := map[byte]int{'h': 1, 'm': 2, 's': 3}
mult := map[byte]int{'h': 3600, 'm': 60, 's': 1}
i, total, last := 0, 0, 0
for i < len(text) {
n, digits := 0, 0
for i < len(text) && text[i] >= '0' && text[i] <= '9' {
n = n*10 + int(text[i]-'0')
i++
digits++
}
if digits == 0 || i >= len(text) {
return -1
}
u := text[i]
r, ok := rank[u]
if !ok || r <= last {
return -1
}
last = r
total += n * mult[u]
i++
}
return total
}