16
\$\begingroup\$

Introduction

Here in Germany the ruling on work times is very strict. If you work 6 or more hours a day, you have to take at least a 30 minute break. If you work 9 or more hours, you need to take a 45 minute break. If you work less than 6 hours, you don't have to take any breaks.

Of course you can split those breaks, but each part has to be at least 15 minutes long to be counted.

The Challenge

In this challenge you will get a list of work periods and you have to check if enough breaks were taken, using the following rules:

Let w be the work time in hours:

w < 6         -> No breaks needed
6 <= w < 9    -> 30 minute break needed
w >= 9        -> 45 minute break needed

Additionally, each break has to be at least 15 minutes long. Also you can always take more breaks than needed. Those are all "at least" values.

Input

Your input will be a list of work periods. The exact format is up to you, but it has to contain only time values as hours and minutes.

Example:

Format here is a list of tuples while each tuple represents a working period. The first element in a tuple will be the start time, the second one will be the end time.

[("07:00","12:00"),("12:30","15:30"),("15:45","17:15")]

This results in a total work time of 9.5 hours and a total break time of 45 minutes.

Note that those working periods don't have to be separated by breaks. There can also be working periods which just follow each other (example see test cases).

Also note that breaks don't count into the working time. Those are two separate values.

You may assume that the working periods are ordered.

Output

Given this input, output a truthy value if enough breaks were taken and a falsy value if not.

Rules

  • Specify the input format you are using in your submission.
  • You don't have to handle empty input. There will always be at least one working period.
  • The working periods will only span one day, so you don't have to handle work over midnight.
  • Date-/Time-/Whatever- Builtins allowed, as long as it comes with your language.
  • Function or full program allowed.
  • Default rules for input/output.
  • Standard loopholes apply.
  • This is , so lowest byte-count wins. Tie-breaker is earlier submission.

Test cases

Same input format as in the example above.

[("07:00","12:00"),("12:30","15:30"),("15:45","17:15")] -> TRUE  // 9:30h work, 45 minutes break -> OK
[("07:20","07:45"),("07:59","11:30"),("11:55","15:00")] -> FALSE // 7:01h work, 39 minutes break, but first break does not count because < 15 minutes
[("06:00","09:00"),("09:00","11:50")] -> TRUE   // Only 5:50h work, so no break needed
[("07:30","12:00"),("12:30","16:00")] -> TRUE   // 8h work, 30 minutes break -> OK
[("08:00","12:30"),("13:05","17:45")] -> FALSE // 9:10h work, only 35 minutes break instead of the needed 45
[("08:00","14:00")] -> FALSE  // 6h work, no breaks, but 30 minutes needed


Happy Coding!

\$\endgroup\$
0

3 Answers 3

5
\$\begingroup\$

Javascript, 108 106 bytes

m=>(k=t=0,m.map(l=>(a=l[0]*60+l[1],k+=t?a-b<15?0:a-b:0,b=l[2]*60+l[3],t+=b-a)),t/=60,t<6||k>44||t<9&&k>29)

Takes an array of arrays. Each inner array has the start hour and minute and end hour and minute respectively for each period.

f=m=>(                           // assign function to f
    k=t=0,                       // k break // t work
    m.map(l=>(                   // for each period
        a=l[0]*60+l[1],          // started time in minutes 
        k+=t?a-b<15?0:a-b:0,     // if there was a break add it
        b=l[2]*60+l[3],          // ended time in minutes
        t+=b-a                   // sum worked time (the difference)
    )),                          //
    t/=60,                       // turn t from minutes to hours
    t<6||k>44||t<9&&k>29         // the main logic
)                                //

document.body.innerHTML = '<pre>' +
  f([[07,00,12,00],[12,30,15,30],[15,45,17,15]]) + '\n' +
  f([[07,20,07,45],[07,59,11,30],[11,55,15,00]]) + '\n' +
  f([[06,00,09,00],[09,00,11,50]]) + '\n' +
  f([[07,30,12,00],[12,30,16,00]]) + '\n' +
  f([[08,00,12,30],[13,05,17,45]]) + '\n' +
  f([[08,00,14,00]]) + '\n' +
'</pre>'

\$\endgroup\$
3
\$\begingroup\$

Python 3, 135

Saved 3 bytes thanks to DSM.

This is one of my mathier solutions in a while.

def f(l):
 h=r=e=0
 for(a,b)in l:a+=a%1*2/3;b+=b%1*2/3;h+=b-a;r-=(e-a)*(e and(a-e)>.24);e=b
 return(h<6)|(6<=h<9and.5<=r)|(h>9and.74<r)

Here're my test cases, it also shows how I expect the function to be called.

assert f([(07.00, 12.00), (12.30, 15.30), (15.45, 17.15)])
assert not f([(07.20, 07.45), (07.59, 11.30), (11.55, 15.00)])
assert f([(06.00, 09.00), (09.00, 11.50)])
assert f([(07.30, 12.00), (12.30, 16.00)])
assert not f([(08.00, 12.30), (13.05, 17.45)])
assert not f([(08.00, 14.00)])
\$\endgroup\$
1
\$\begingroup\$

Pyth, 56 52 bytes

La.*bgsm*ydgyd15cPt_Jmid60Q2@[0030 45)hS,/syRcJ2C\´3

Takes input in the form [[hh,mm], [hh,mm], ...] with no leading 0s

Explanation:

La.*bgsm*ydgyd15cPt_Jmid60Q2@[0030 45)hS,/syRcJ2C\´3

La.*b                                                - def y(b): return absdiff(*b)

                    Jmid60Q                          - Unpack the input to mins and assign to J
                    J                                - autoassign J = V
                     m    Q                          - [V for d in Q]
                      id60                           - conv_base(V, 60)

      sm*ydgyd15cPt_J      2                         - Get the total break
                   _J                                - reverse(J)
                 Pt                                  - ^[1:-1]
                c          2                         - chop(2, ^)
                                                     -
       m                                             - [V for d in ^]
            yd                                       - y(d)
           g  15                                     - >= 15
         yd                                          - y(d)
        *                                            - y(d) * (y(d)>=15)
                                                     -
      s                                              - sum(^)

                            @[0030 45)hS,/syRcJ2C\´3 - Get the break required
                                             cJ2     - chop(J, 2)
                                           yR        - map(y, ^)
                                          s          - sum(^)
                                                     - Now have the total time worked in mins
                                         /      C\´  - ^/ord("`")
                                                     - (^/180)
                                                     - Now have the time worked in 3 hour intervals
                                      hS,          3 - sorted([^, 3])[0]
                                                     - (min(^, 3))
                                                     - Now have hours worked in 3 hour intervals capped at 9 hours
                            @[0030 45)               - [0,0,30,45][^]
                                                     - Get the break required for that time

     g                                               - break >= break required

Try it here

Or try all the test cases here

\$\endgroup\$

Your Answer

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

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