14
\$\begingroup\$

I like my job, but sometimes it can get a bit tedious and boring. As motivation, I want to know how many hours of work are left before I finally get my two days of weekend and relaxation.

  • I work every day from Monday to Friday, totalling 38.5 hours, starting at 9am and ending at 6pm.
  • Every day - except Friday - I get a lunch break from 1:00pm to 1:30pm. On Fridays I do not get a lunch break, but get off at 1:30pm instead. Note that these lunch breaks do not add to work time.
  • If I check the time during the weekend (Friday after 1:30pm, Saturday or Sunday), I don't want to know about next week yet - it should tell me that zero hours are remaining instead.

Given an input date, calculate the number of work hours remaining until the weekend is here (on Friday at 1:30pm). You can assume that the input hours will range from 0 to 23, and the minutes will only ever be 0 or 30, which means that you will not have to calculate fractions other than .5.

Rules

  • This is , the shortest answer, in bytes, wins.
  • As usual, standard loopholes are forbidden.
  • Input may be received in any reasonable datetime format. Timestamps, date strings, date objects, et cetera are all allowed. You can also directly take the input as the day of the week (indexed with Sunday as 0), the hours and the minutes.
  • Output may be written directly to stdout or returned as a string or numeric. Printing with trailing newlines is allowed.

Test Cases

Fri May 21 2021 09:00:00 -> 4.5
Sun Jul 25 2021 16:00:00 -> 0
Mon Aug 23 2021 04:00:00 -> 38.5
Sat Nov 06 2021 08:00:00 -> 0
Thu Oct 14 2021 10:30:00 -> 11.5
Tue Dec 07 2021 14:30:00 -> 25
Fri Jan 21 2022 00:00:00 -> 4.5

Formatted as full date strings for convencience - you do not need to use this format, check the input rules.

\$\endgroup\$
6
  • \$\begingroup\$ When does the weekend end? I notice Sunday 4PM has 0 hours (since it's during the weekend) but Monday 4AM has the full week listed - is the cutoff at Monday midnight, and should the output for Monday at 00h00 be 38.5 or 0? \$\endgroup\$
    – hyper-neutrino
    Jun 22, 2021 at 15:30
  • 1
    \$\begingroup\$ The entire Sunday is still weekend. The first second of Monday (00h00) already counts as the new week. \$\endgroup\$
    – Ian H.
    Jun 22, 2021 at 15:32
  • 3
    \$\begingroup\$ You probably should include at least one test case where the minutes are 30. \$\endgroup\$
    – Arnauld
    Jun 22, 2021 at 15:53
  • \$\begingroup\$ @Arnauld good idea, done! \$\endgroup\$
    – Ian H.
    Jun 22, 2021 at 16:08
  • \$\begingroup\$ "You can also directly take the input as the day of the week (indexed with Sunday as 0), the hours and the minutes." Can I just take the number of minutes elapsed since Sunday, where beginning of Sunay is 0? \$\endgroup\$
    – Jonah
    Jun 22, 2021 at 21:37

6 Answers 6

4
\$\begingroup\$

Python 2, 108 bytes

d,h,m=input()
t=0
while((h,m)<(13,1))+4>d%7:t+=8<h<18>13!=h*-~m*(d!=4);h+=m>0;m=30-m;d+=h/24;h%=24
print.5*t

Try it online!

-2 bytes thanks to EliteDaMyth
-5 bytes thanks to Arnauld
-5 bytes thanks to ovs

Monday = 0, Sunday = 6

\$\endgroup\$
4
  • 1
    \$\begingroup\$ i dont think you need () around h+=(m>0) \$\endgroup\$
    – user100752
    Jun 22, 2021 at 16:02
  • 1
    \$\begingroup\$ 100 bytes, based on Arnauld's suggestion. \$\endgroup\$
    – ovs
    Jun 22, 2021 at 16:11
  • \$\begingroup\$ I think d=3, h=13, m=30 should return 9, not 8.5. \$\endgroup\$
    – Arnauld
    Jun 22, 2021 at 17:07
  • \$\begingroup\$ @Arnauld fixed for 8, thanks \$\endgroup\$
    – hyper-neutrino
    Jun 22, 2021 at 17:12
2
\$\begingroup\$

JavaScript (ES6),  84 79 78  73 bytes

Saved 1 byte thanks to @l4m2

Expects (d,h,m) where d is the day of the week as described in the challenge.

(d,h,m)=>d%6?(g=k=>k--?g(k)-(k/18&(d-5?k!=26:k<27)):94-17*d)(h*2+!!m)/2:0

Try it online!

Commented

(d, h, m) =>        // d = day of week, h = hours, m = minutes
d % 6 ?             // if this is not the week-end:
  ( g = k =>        //   g is a recursive function that iterates over
                    //   the whole day with a 30 minutes granularity
    k-- ?           //     decrement k; if it was not 0:
      g(k) -        //       do a recursive call and decrement the final
      (             //       result if:
        k / 18 &    //         it's between 9 AM and 5.30 PM
                    //         (i.e. floor(k / 18) = 1)
        (           //         and:
          d - 5 ?   //           if this is not Friday:
            k != 26 //             it's not 1 PM
          :         //           else:
            k < 27  //             it's less than 1.30 PM 
        )           //     
      )             //     
    :               //     else (end of recursion):
      94 - 17 * d   //       add 38.5 hours minus 8.5 hours per full day,
                    //       which gives 77 - 17 * (d - 1) in half hours
  )(h * 2 + !!m)    //   initial call with h and m converted to half hours
  / 2               //   half the result
:                   // else:
  0                 //   just return 0
\$\endgroup\$
1
  • 1
    \$\begingroup\$ m/30=>!!m?. \$\endgroup\$
    – l4m2
    Jun 22, 2021 at 22:33
1
\$\begingroup\$

Charcoal, 53 52 49 47 bytes

I⊘Σ✂”~∨‽lC⎚À›t⟧κⅉ←eδQ﹪GÀ*¡_∧⌊⮌θμ⟧>”⁺×⁴⁸⊖N⁺⊗N¬¬N

Try it online! Link is to verbose version of code. Explanation: I couldn't find a better way of expressing the working hours than a giant compressed lookup table (especially now I've golfed 10% off).

    ”...”               Compressed lookup table of half hours
   ✂                    Sliced starting at position
              N         Input day of week
             ⊖          Decremented
          ×⁴⁸           Multiplied by 48 (half hours in day)
         ⁺              Plus
                 N      Input hour of day
                ⊗       Doubled (convert to half hours)
               ⁺        Plus
                    N   Input minute of day
                  ¬¬    Is not zero
  Σ                      Count half hours left to work
 ⊘                      Divide by 2 (convert to hours)
I                       Cast to string
                        Implicitly print

Edit: Saved 1 byte by using Sum() instead of Count(..., "1"), allowing me to save a further 3 bytes by using Sum(Slice(...)) instead of Minus(77, Sum(CycleChop(...))), allowing me to save a further 2 bytes by removing the now unnecessary Modulo(..., 7).

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

J, 59 56 bytes

1-:@#.,@(30|."1(|:48{.0(8})18 4$1),9$1)}.~30%~7 24 60&#.

Try it online!

Takes input as day hour minute.

the idea

  • View the entire week as series of 30 minute chunks, where 1 represents work time and 0 represents free time. The five relevant week days look like:

    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    
  • Find how many 30 minute chunks away from Sunday midnight the input is.

  • Delete that many elements.

  • Sum the remaining ones, and divide by 2.

J details

  • 30%~7 24 60&#. Converts to the input to minutes, then divides by 30.
  • ,@(30|."1(|:48{.0(8})18 4$1),9$1) Returns the grid above, but flattened.
  • 1-:@#. Sum and divide by 2.
\$\endgroup\$
0
\$\begingroup\$

Perl 5, 84 bytes

sub f{$_=pop;$_>51300||$_<1e4?0:(/(09|1[0-7])..$/-/[1-4]1300/)*.5+f($_+30+40*/3.$/)}

Try it online!

The function takes one numeric argument: day*10000 + hour*100 + minute where Monday is 1, Tuesday is 2, ... and Sunday is 0 (if Sunday=7 is allowed 8 bytes can be saved). Example input: 51300 = Friday 13:00.

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

JavaScript (Node.js), 95 bytes

f=d=>(h=d.getHours(),d+0)[0]!='S'&&(h>8&h<13+5*(d+0>'G')^/13:0/.test(d))/2+f(new Date(+d+18e5))

Try it online!

JavaScript (Node.js), 75 bytes from Arnauld's

(d,h,m)=>d%6&&(g=k=>k--?g(k)-(k>17&k<(d-5?36:26)^k==26):94-17*d)(h*2+!!m)/2

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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