Калькулятор робочого часу


9

Це базується на тому, як моя компанія займається моніторингом робочого часу кожного працівника. У кожного з нас є картка, яку можна передавати перед сенсором, щоб годинник реєстрував час, коли працівники заїжджають або виходять з офісу. Кожен раз, коли реєстр пов'язаний з кодом:

  • Код 0: працівник прибуває до офісу (або повертається до нього).
  • Код 1: працівник залишає офіс на обід.
  • Код 2: працівник залишає посаду в кінці робочого дня.
  • Код 3: працівник залишає посаду з робочих міркувань.
  • Код 4: працівник залишає посаду з особистих причин.

Реєстри коду 0 іноді називатимуть "нульовими регістрами", а код 1 до регістрів код 4 іноді називатимуться "ненульовими регістрами".

Отже, звичайний день для працівника генерує такий список реєстрів:

Code/Time
------------
0   8:17  // The employee arrives at the office
4  11:34  // The employee leaves the office to smoke
0  11:41  // The employee returns to the office
1  13:37  // The employee leaves the office to have lunch
0  14:11  // The employee returns to the office
3  15:02  // The employee leaves the office to visit a client
0  16:48  // The employee returns to the office
2  17:29  // The employee leaves the office to go home

Тим не менш, працівники іноді роблять помилки. Наступні помилки автоматично виправляються системою:

  • Є два поспіль ненульові записи. Якщо в першому ненульовому записі є код 4, автоматичний регістр коду 0 додається через 15 хвилин або за 1 хвилину до наступних регістрів, якщо він був зареєстрований менше ніж через 15 хвилин після. Якщо перший ненульовий запис має код 3, автоматичний регістр коду 0 завжди додається за 1 хвилину до наступного регістра. У кожному іншому випадку виникає помилка. Приклади:

    Code/Time
    ------------
    0   8:17  // The employee arrives at the office
    4  11:34  // The employee leaves the office to smoke
    1  13:37  // The employee leaves the office to have lunch
    // Automatic register with code 0 added at 11:49.
    
    Code/Time
    ------------
    0   8:17  // The employee arrives at the office
    4  11:34  // The employee leaves the office to smoke
    4  11:39  // The employee leaves again the office for personal reasons
    // Automatic register with code 0 added at 11:38.
    
    Code/Time
    ------------
    0   8:17  // The employee arrives at the office
    3  11:34  // The employee leaves the office to visit a client
    1  14:09  // The employee leaves the office to have lunch
    // Automatic register with code 0 added at 14:08.
    
  • Працівник зареєстрував два регістри коду 1 або два регістри коду 2. Оскільки ці двоє насправді взаємозамінні, це не вважається помилкою. Якщо регістри коду 1 або коду 2 містять більше 2 регістрів, це призводить до помилки.

Змагання

Основна мета - підрахувати, скільки годин і хвилин провів працівник в офісі. Це робиться після фіксації (якщо потрібно та можливо) списку вхідних регістрів. Зауважте, що правильний список регістрів буде чергувати нульові регістри з ненульовими регістрами.

Отже, алгоритм отримає перелік реєстрів для працівника та день подачі та поверне час, витрачений на роботу за цей день. Якщо час не зможе підрахувати витрачений час у випадку помилок, він повернеться 0 годин, 0 хвилин.

Правила:

  • Витрачений час - це сума часу, витраченого між кожним регістром коду 0 та наступним ненульовим регістром. Якщо ненульовий код дорівнює 3, час, що проходив між цим регістром та наступним регістром коду 0, також буде врахований.
  • Ви можете припустити, що список вхідних регістрів буде у порядку зростання, і всі регістри будуть з того самого дня (ніхто не працюватиме після півночі).
  • Реєстр введення не буде порожнім.
  • Формат введення може бути будь-яким, що потрібен вашому коду, доки час виражається значенням години та значенням хвилини (число годин із плаваючою комою не буде дійсним введенням). Приклади: Список з кодами та список із часом, як рядки, обидва списки однакової довжини; перелік списків цілих чисел, що представляють собою цілий код, годину та хвилини регістрів ...
  • Виведенням може бути рядок із часом (у будь-якому бажаному форматі: H: mm, HH: mm, H: m ...); список двох цілих чисел із обчисленими годинами та хвилинами; все, що можна інтерпретувати як годинний хвилинний кортеж (число з плаваючою комою з витраченими годинами не дозволяється). Або ви можете надрукувати результат в STDOUT.

Тестові справи

Code/Time
------------
0   8:17  // Check in
4  11:34  // Check out. Time spent since check in:  3:17
0  11:41  // Check in
1  13:37  // Check out. Time spent since check in:  1:56
0  14:11  // Check in
3  15:02  // Check out. Time spent since check in:  0:51
0  16:48  // Check in.  Time spent working outside: 1:46
2  17:29  // Check out. Time spent since check in:  0:41
// Total time (value returned): 8:31

Code/Time
------------
0   8:17
4  11:34  // Time spent: 3:17
1  15:52  // Time spent since 11:49 (automatic register 15 minutes after
          // a code 4 register): 4:03
// Total time: 7:20

Code/Time
------------
0   8:17
4  15:47  // Time spent: 7:30
1  15:52  // Time spent since 15:51 (automatic register after a code 4
          // register 1 minute before the next register as it is too
          // close in time): 0:01
// Total time: 7:31

Code/Time
------------
0   8:17
1  13:34  // Time spent: 5:17
0  14:04
1  17:55  // Time spent: 3:51 (last code 1 should be a code 2 but it does not matter)
// Total time: 9:08

Code/Time
------------
0   8:17
1  13:34
0  14:04
1  17:05
0  17:08
2  17:44
// Total time: 0:00 (too many code 1 and code 2 registers)

Code/Time
------------
0   8:17
1  13:34  // A code 1 register does not generate an automatic code 0 register
2  17:41
// Total time: 0:00 (there's a code 0 register missing)

Code/Time
------------
0   8:17
0  13:34  // what happened between these two check in registers?
2  17:41
// Total time: 0:00 (there's a check out register missing)

Code/Time
------------
0   8:17
0  13:37  // This should probably be a code 1 register, but we cannot be sure
0  14:11
2  17:29
// Total time: 0:00

Я знаю, що це може заплутати (проблема в реальному світі мала розглянути ще більше випадків, тому я це знаю). Будь ласка, не соромтеся просити більше прикладів.

Це є , тому може виграти найкоротший код для кожної мови!


Ви можете коментувати, як покращити систему, якщо хочете, але це не в цьому. Мій начальник не схильний витрачати час на його зміну. :-)


Відповіді:


3

Пітон 3 , 327 322 318 317 байт

Дякуємо @JonathanFrech та @ Mr.Xcoder за те, що позбулися деяких байт.

Приймає введення як список кодів ( C) та список разів ( T) ( (hours, minutes)кортежі). Повертається (hours, minutes)кортеж.

def f(C,T):
 T,L=[m+h*60for h,m in T],C.count
 for z in range(len(C))[::-1]:
  c=C[~-z]
  if c*C[z]:
   if c<3:return 0,0
   C.insert(z,0);b=~-T[z];T.insert(z,b if c-4else min(T[~-z]+15,b))
 while L(3):i=C.index(3);del C[i:i+2],T[i:i+2]
 return(0,0)if L(1)+L(2)>2or 0in C[1::2]else divmod(sum(T[1::2])-sum(T[::2]),60)

Перевірено на наведених прикладах.

Безумовно

def f(C, T):
    # use minutes since midnight instead of (hours, minutes)
    T=[m+h*60 for h,m in T]

    # error correction
    for z in range(len(C))[::-1]:
        if C[z-1] and C[z]:
            if C[z-1]<3:
                return 0,0

            C.insert(z,0)
            b=T[z]-1
            T.insert(z, b if C[z-1] != 4 else min(T[z-1]+15, b))

    # simplification (remove work trips (code 3))
    while L(3): # 3 in C
        i=C.index(3)
        del C[i:i+2]
        del T[i:i+2]

    # error check
    if 0 in C[1::2] or 2 < C.count(1) + C.count(2):
        return 0,0

    # sum
    s = sum(T[1::2])-sum(T[::2])

    # to (hours, minutes)
    return divmod(s, 60)


Це заперечення я не думав. Приємні трюки.
Ханнес Карппіла

ви можете використовувати L(3)замість 3in C.
Містер Xcoder
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.