Files
wehub-resource-sync dde272c4b8
i18n - Build Validation / Validate i18n Builds (24) (push) Has been cancelled
CI - Node.js / Lint (24) (push) Has been cancelled
CI - Node.js / Build (24) (push) Has been cancelled
CI - Node.js / Test (24) (push) Has been cancelled
CI - Node.js / Test - Upcoming Changes (24) (push) Has been cancelled
CI - Node.js / Test - i18n (italian, 24) (push) Has been cancelled
CI - Node.js / Test - i18n (portuguese, 24) (push) Has been cancelled
CD - Docker - GHCR Images / Build and Push Images (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 11:55:53 +08:00

122 lines
2.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: 6a26df3e2988bcdded204897
title: "Challenge 361: Spoken Time"
challengeType: 29
dashedName: challenge-361
---
# --description--
Given the angles for the hour and minute hands of an analog clock in degrees (clockwise from 12), return the time in spoken English.
Convert the minute hand angle to minutes (360° = 60 minutes), then use the following rules:
| Minutes | Spoken |
|---------|--------|
| 0 | `"Y o'clock"` |
| 15 | `"quarter past Y"` |
| 129 (excluding 15) | `"X minutes past Y"` |
| 30 | `"half past Y"` |
| 45 | `"quarter to Z"` |
| 3159 (excluding 45) | `"X minutes to Z"` (where `X` is 60 - minutes) |
Where `Y` is the current hour and `Z` is the next hour, both derived from the hour hand angle (360° = 12 hours).
Note: Hand angles may not land exactly on a number, consider rounding them somehow.
# --hints--
`get_spoken_time(90, 0)` should return `"3 o'clock"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_spoken_time(90, 0), "3 o'clock")`)
}})
```
`get_spoken_time(160, 120)` should return `"20 minutes past 5"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_spoken_time(160, 120), "20 minutes past 5")`)
}})
```
`get_spoken_time(255, 180)` should return `"half past 8"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_spoken_time(255, 180), "half past 8")`)
}})
```
`get_spoken_time(67.5, 92)` should return `"quarter past 2"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_spoken_time(67.5, 92), "quarter past 2")`)
}})
```
`get_spoken_time(200, 240)` should return `"20 minutes to 7"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_spoken_time(200, 240), "20 minutes to 7")`)
}})
```
`get_spoken_time(322.5, 273)` should return `"quarter to 11"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_spoken_time(322.5, 273), "quarter to 11")`)
}})
```
`get_spoken_time(117.5, 335)` should return `"5 minutes to 4"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_spoken_time(117.5, 335), "5 minutes to 4")`)
}})
```
# --seed--
## --seed-contents--
```py
def get_spoken_time(hour_angle, minute_angle):
return hour_angle
```
# --solutions--
```py
def get_spoken_time(hour_angle, minute_angle):
minutes = int(minute_angle / 6)
hour = int(hour_angle / 30) or 12
next_hour = (hour % 12) + 1
if minutes == 0:
return f"{hour} o'clock"
if minutes == 15:
return f"quarter past {hour}"
if minutes == 30:
return f"half past {hour}"
if minutes == 45:
return f"quarter to {next_hour}"
if minutes < 30:
return f"{minutes} minutes past {hour}"
return f"{60 - minutes} minutes to {next_hour}"
```