In Vernor Vinge's excellent and fascinating book A Deepness in the Sky (which, by the way, I highly recommend1), the Qeng Ho, a culture that spans various star systems, has no notion of "days," "months," "years," etc., and hence has a unique timekeeping system that measures time entirely in seconds. The most commonly used units are the Ksec (kilosecond), Msec (megasecond), and Gsec (gigasecond). Here's a handy chart from my own copy of the book (since I can't find it online):
You are currently flying on the Pham Nuwen, and you have just received a message from a strange, unknown planet called "Earth."2 They use different time units than you do, and your computers don't recognize theirs. As the resident Programmer-Archaeologist of the ship, your job is to patch the time-handling code so that it recognizes Earth units of time.
Naturally, since you're only out of coldsleep for another few Ksecs, you want to make your code as short as possible so it can be written quickly. Fortunately, as an interstellar trading culture, the Qeng Ho has access to every programming language invented.
Input
The input will be a single string containing one or more space-separated
components. A component is defined as an integer number > 0 and ≤ 255, then
a space, and then one of second
, minute
, hour
, day
, week
, month
,
year
, decade
, or century
, possibly plural (with an added s
, or
centuries
for the last case).
Here are some valid example inputs:
10 days 12 hours
1 year
184 centuries 1 second
9 weeks 6 days 2 hours 1 minute 20 seconds
You may assume the following about the input:
Pluralization of units will always agree with the relevant number.
If there are multiple components in the input, they will always be in descending order of length.
Here are what the various input units mean, for the purposes of this challenge:
unit relative absolute
---------------------------------------
second 1 second 1 second
minute 60 seconds 60 seconds
hour 60 minutes 3600 seconds
day 24 hours 86400 seconds
week 7 days 604800 seconds
month 30 days 2592000 seconds
year 365 days 31536000 seconds
decade 10 years 315360000 seconds
century 10 decades 3153600000 seconds
Output
Here are the Qeng Ho units which your code has to support:
unit relative absolute
----------------------------------------
second 1 second 1 second
Ksec 1000 seconds 1000 seconds
Msec 1000 Ksecs 1000000 seconds
Gsec 1000 Msecs 1000000000 seconds
Use the following algorithm to determine your code's output:
First, add up the total amount of time that the input represents.
Find the largest Qeng Ho unit that is shorter or the same amount of time as the input—essentially, find the largest unit that there is at least one of.
Convert the total amount of time given in the input into this unit, and output the result, rounded to three decimal places.
You may have your choice of which of the following methods to use: rounding up,
rounding down, rounding away from zero, or rounding towards ∞ or -∞. If the
rounded result ends in 0
, you may either remove trailing zeroes or keep as
many as you want (or do both, depending on the input).
If the rounded result is exactly 1.000
, you must use the singular form
(second
, Ksec
, Msec
, Gsec
); otherwise, use the plural form (seconds
,
Ksecs
, Msecs
, Gsecs
).
In certain edge-cases, you might be using the unit of, for example, Ksec, but
obtain a rounded result of 1000.000 Ksecs. In this case, you may simply output
1000.000 Ksecs
instead of 1 Msec
.
You may always assume that the input is in descending order of units (century,
decade, year, etc.); furthermore, the component that comes after any given unit
will always be shorter (that is, 1 decade 20 years
is invalid input).
Test cases
Note: results marked with an asterisk (*
) may vary by a negligible amount due
to rounding differences.
input output
-------------------------------------------------------------
1 hour 3.600 Ksecs
1 day 86.400 Ksecs
2 weeks 1.210 Msecs
1 year 31.536 Msecs
32 years 1.009 Gsecs *
1 second 1.000 second
1 century 6 decades 5.046 Gsecs *
255 centuries 804.168 Gsecs
2 weeks 6 days 1 hour 19 minutes 4 seconds 1.733 Msecs
1 week 3 days 3 hours 7 minutes 875.220 Ksecs
1 week 4 days 13 hours 46 minutes 40 seconds 1.000 Msec
2 months 2 hours 5.191 Msecs *
16 minutes 39 seconds 999.000 seconds
Rules
- This is code-golf, so the shortest code in bytes wins.
1: only if you like hard scifi, of course. In which case I recommend reading A Fire Upon the Deep first, which is (in my opinion) even more fantastic.
2: well, technically "Old Earth" is mentioned several times in A Deepness in the Sky, but...
2 months 2 hours
as "2 months * 2 hours." \$\endgroup\$