16
\$\begingroup\$

The following data contains the (approximate) population of each UTC timezone in the world (source):

UTC;Population (in thousands)
-11;57
-10;1853
-9.5;8
-9;639
-8;66121
-7;41542
-6;272974
-5;332101
-4.5;31923
-4;77707
-3.5;499
-3;248013
-2;4855
-1;3285
0;285534
+1;857443
+2;609921
+3;496279
+3.5;81889
+4;129089
+4.5;31042
+5;305642
+5.5;1458945
+6;199668
+6.5;50112
+7;439650
+8;1679526
+9;220112
+9.5;1814
+10;29482
+11;5267
+11.5;2
+12;6112
+13;308
+14;11

(for the sake of simplicity, I'm removing +X.75 UTC times from the list)

Assuming that every person in the world wakes up at 8AM and goes to sleep at midnight (in their local time), how many people are simultaneously awake in the world at a given UTC time?

For example, suppose the given time is 2PM UTC. These are the timezones where the local time at 2PM UTC is between 8AM inclusive and midnight exclusive:

  -6 08:00 272974
  -5 09:00 332101
-4.5 09:30 31923
  -4 10:00 77707
-3.5 10:30 499
  -3 11:00 248013
  -2 12:00 4855
  -1 13:00 3285
  +0 14:00 285534
  +1 15:00 857443
  +2 16:00 609921
  +3 17:00 496279
+3.5 17:30 81889
  +4 18:00 129089
+4.5 18:30 31042
  +5 19:00 305642
+5.5 19:30 1458945
  +6 20:00 199668
+6.5 20:30 50112
  +7 21:00 439650
  +8 22:00 1679526
  +9 23:00 220112
+9.5 23:30 1814

Now, just add the population of these timezones and output 7818023 (corresponding to ~7.8 billion people).

Input

An UTC time. You may accept two natural numbers h and m, where 0 ≤ h ≤ 23 and m ∈ {0, 30}.

Standard I/O applies, so you can accept them as lists, strings, etc. You can even accept m as a boolean value, where 0 means HH:00 and 1 means HH:30.

There are two ways of solving this question: hardcoding the output (since there are only 48 possible inputs) or hardcoding the population data and solving by time arithmetic. However, to make this challenge more interesting, you are allowed to accept the population data as an additional input, so you don't need to hardcode it (thus saving you some bytes) and focusing only on the time arithmetic. So you can read it as additional lines from STDIN or an additional function argument.

Output

How many people are awake at the given time, in thousands.

Test cases

00:00 -> 3024211
00:30 -> 3024211
01:00 -> 3460576
01:30 -> 3510688
02:00 -> 3705501
02:30 -> 5164446
03:00 -> 5222075
03:30 -> 5252618
04:00 -> 5304000
04:30 -> 5353966
05:00 -> 5518144
05:30 -> 5518144
06:00 -> 5855091
06:30 -> 5855091
07:00 -> 6670992
07:30 -> 6670992
08:00 -> 6890405
08:30 -> 6890405
09:00 -> 6893051
09:30 -> 6893043
10:00 -> 6896034
10:30 -> 6896034
11:00 -> 7143682
11:30 -> 7144181
12:00 -> 7215776
12:30 -> 7247697
13:00 -> 7574531
13:30 -> 7574531
14:00 -> 7818023
14:30 -> 7816209
15:00 -> 7637639
15:30 -> 7637639
16:00 -> 6024234
16:30 -> 6024234
17:00 -> 5585223
17:30 -> 5535119
18:00 -> 5337315
18:30 -> 3878370
19:00 -> 3573093
19:30 -> 3542051
20:00 -> 3419074
20:30 -> 3337187
21:00 -> 2846175
21:30 -> 2846175
22:00 -> 2265736
22:30 -> 2267550
23:00 -> 1630219
23:30 -> 1630219

Try to make your code with the fewest bytes as possible.


Sandbox

\$\endgroup\$
13
  • \$\begingroup\$ Aside: there's no such time as 12AM (or 12PM). You looking for midnight (or noon). \$\endgroup\$
    – Noodle9
    Commented Jan 16 at 14:31
  • 19
    \$\begingroup\$ @Noodle9 That's objectively incorrect \$\endgroup\$
    – hyperneutrino
    Commented Jan 16 at 15:38
  • 3
    \$\begingroup\$ @hyper-neutrino AM = Ante meridiem: Before noon, PM = Post meridiem: After noon. 12:00 is neither before nor after noon, and 24:00 is 12 hours after noon and 12 hours before noon. So they're not AM or PM. You can call them noon, 12:00, 12 hundred hours, midnight, 24:00, 24 hundred hours but not 12AM or 12PM. \$\endgroup\$
    – Noodle9
    Commented Jan 16 at 18:35
  • 14
    \$\begingroup\$ See Confusion at noon and midnight: "By convention, 12 AM denotes midnight and 12 PM denotes noon. Because of the potential for confusion, it is advisable to use 12 noon and 12 midnight." \$\endgroup\$ Commented Jan 16 at 19:40
  • 2
    \$\begingroup\$ New test expectations look good to me using an updated version of a deleted answer by Nick Kennedy, TIO (the inputs shown are [boolean m, h], same order as your tests). \$\endgroup\$ Commented Jan 16 at 22:22

7 Answers 7

11
\$\begingroup\$

Google Sheets, 38 bytes

=sumproduct(B:B,1/3<=mod(A:A/24+C1,1))

Paste UTC offset and population data in cells A1:B, put the time of the day in cell C1, and the formula in cell D1.

There was some confusion whether the expected results shown in the test cases were correct. The above formula matches the updated expected results.

Spreadsheet dateserials use a system where the duration of one day is 1. Eight hours, 8:00 am, is one third of a day, i.e., 1/3, and the value of 24 hours is exactly 1. In spreadsheets, mod() always takes the sign of the divisor rather than that of the dividend which lets the formula wrap around midnight.

The rules allow some flexibility with input formats. If UTC offsets are input as durations like -11:00, -10:00, -9:30 in column A1:A, they require no manipulation and can simply be added to the time of day (35 bytes):

=sumproduct(B:B,1/3<=mod(A:A+C1,1))

population_timezone3

\$\endgroup\$
0
6
\$\begingroup\$

Jelly, 11 bytes

ḅ.+%24>7.ḋ⁵

Try it online!

A full program taking three arguments (time as [m/30, h], timezones, populations) and printing the total population awake.

Thanks to @JonathanAllan for saving two bytes and fixing a bug!

Explanation

ḅ.          | Base convert from base 0.5
  +         | Add timezones
   %24      | Mod 24
      >7.   | Greater than 7.5
         ḋ⁵ | Dot product with populations
\$\endgroup\$
3
  • 1
    \$\begingroup\$ I suppose <8¬ is the same count and would work for \$\frac{m}{30}\$ as well as the boolean version. \$\endgroup\$ Commented Jan 16 at 23:35
  • \$\begingroup\$ What is the "Base convert from base 0.5" achieve here? I'm trying to understand that but I don't even see input that could be considered valid base 0.5. \$\endgroup\$
    – addison
    Commented Jan 17 at 16:50
  • 1
    \$\begingroup\$ @addison converting a list of two numbers, [half-hours, hours] from base five is a shortcut for 0.5 * half-hours + hours since \$\frac{1}{2}^{0}=1\$ and \$\frac{1}{2}^{1}=\frac{1}{2}\$. \$\endgroup\$ Commented Jan 17 at 18:56
4
\$\begingroup\$

Charcoal, 21 bytes

IΣEΦθ‹⁷·⁵﹪⁺⁺∕ζ⁶⁰ηκ²⁴ι

Attempt This Online! Link is to verbose version of code. Takes arguments in the order zones, h, m. Explanation:

    θ                   Input zones
   Φ                    Filtered where
      ⁷·⁵               Literal number `7.5`
     ‹                  Is less than
             ζ          Input minutes
            ∕           Divided by
              ⁶⁰        Literal integer `60`
           ⁺            Plus
                η       Input hours
          ⁺             Plus
                 κ      Current key
         ﹪              Modulo
                  ²⁴    Literal integer `24`
  E                     Map over entries
                    ι   Take the value
 Σ                      Take the sum
I                       Cast to string
                        Implicitly print

Python's sum sums the keys of a dictionary for some reason.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ Python's sum sums the keys of a dictionary for some reason. Probably because iterating over a dictionary will yield the keys of the dict. Otherwise you'd need dict.values(). \$\endgroup\$
    – JAD
    Commented Jan 18 at 8:14
  • \$\begingroup\$ @JAD I really want a function that I can apply to a string, list or dictionary, and get the values (or indices, but consistently). \$\endgroup\$
    – Neil
    Commented Jan 18 at 8:48
3
\$\begingroup\$

JavaScript (Node.js), 48 bytes

c=>t=>c.map(([x,y])=>s+=(t+x+40)%24<16&&y,s=0)|s

Try it online!

\$\endgroup\$
6
  • \$\begingroup\$ @doubleunary If 5337315 and 5337304 diff at +14(11) then it's 8AM and should be included. Not sure where diff between 3460576 and 2382284 \$\endgroup\$
    – l4m2
    Commented Jan 16 at 20:07
  • \$\begingroup\$ Hmm... the expected results shown in test cases exactly match what I get with the Google Sheets answer so I'm biased to think they're correct. N.B. f(CC)(23) and f(CC)(23.5) get 1630219 instead of the expected 1367111. \$\endgroup\$ Commented Jan 16 at 20:15
  • \$\begingroup\$ @doubleunary I don't get how to get 1367111 \$\endgroup\$
    – l4m2
    Commented Jan 16 at 20:26
  • \$\begingroup\$ @doubleunary I get it now. 1367111 ignores people in UTC+9 ~ UTC+14, no wonder I can't figure what the difference is \$\endgroup\$
    – l4m2
    Commented Jan 16 at 20:38
  • \$\begingroup\$ I can exactly match your results with =sumproduct(B2:B,1/3<=mod(A2:A/24+C2,1)). Posting a comment to the question to ask for clarification. \$\endgroup\$ Commented Jan 16 at 21:19
3
\$\begingroup\$

Funge-98, 126 bytes

"HTRF"4(0& 2*&+: 0'v00p
>&2*&+-: 0wv>&:bwv>     RR+'0%'`0w$:0
^$vvp16+'<> ^   > ^p10v'<>j#80:\+R<
$$<>   3j^ <^    >'>02p ^@.

Try it online!

First reads h, then m as 0 or 1, and finally each timezone as (h, m, population).

Contains a non-printable character, so here is a hex dump:

00000000: 2248 5452 4622 3428 3026 2032 2a26 2b3a  "HTRF"4(0& 2*&+:
00000010: 2030 2776 3030 700a 3e26 322a 262b 2d3a   0'v00p.>&2*&+-:
00000020: 2030 7776 3e26 3a62 7776 3e20 2020 2020   0wv>&:bwv>     
00000030: 5252 2b27 3025 270f 6030 7724 3a30 0a5e  RR+'0%'.`0w$:0.^
00000040: 2476 7670 3136 2b27 3c3e 205e 2020 203e  $vvp16+'<> ^   >
00000050: 205e 7031 3076 273c 3e6a 2338 303a 5c2b   ^p10v'<>j#80:\+
00000060: 523c 0a24 243c 3e20 2020 336a 5e20 3c5e  R<.$$<>   3j^ <^
00000070: 2020 2020 3e27 3e30 3270 205e 402e           >'>02p ^@.
\$\endgroup\$
2
\$\begingroup\$

Perl 5 List::Util, 65 bytes

sub{($t,%p)=map$_*2,@_;sum map$p{$_}/2*(($t+$_-16)%48<32),keys%p}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

T-SQL 64 Bytes

declare @x table (utc int, pop int)
declare @t time(7)
insert @x values ...

select sum(pop)from @x where datediff(h,utc,@t) between 8 and 24

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.