Kalkulator waktu kerja

9

Ini didasarkan pada bagaimana perusahaan saya berurusan dengan pemantauan waktu kerja untuk setiap karyawan. Kita masing-masing memiliki kartu yang dapat dilewati di depan sensor, sehingga jam mencatat waktu di mana karyawan check-in atau keluar kantor. Setiap kali register ditautkan dengan kode:

  • Kode 0: karyawan tiba di (atau kembali ke) kantor.
  • Kode 1: karyawan meninggalkan kantor untuk makan siang.
  • Kode 2: karyawan meninggalkan kantor pada akhir hari.
  • Kode 3: karyawan meninggalkan kantor karena alasan pekerjaan.
  • Kode 4: karyawan meninggalkan kantor karena alasan pribadi.

Register kode 0 kadang-kadang akan disebut sebagai "register nol", dan register kode 1 ke kode 4 kadang-kadang disebut sebagai "register non-nol".

Jadi, hari normal bagi seorang pekerja akan menghasilkan daftar daftar seperti ini:

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

Meskipun demikian, karyawan terkadang membuat kesalahan. Kesalahan berikut secara otomatis diperbaiki oleh sistem:

  • Ada dua catatan non-nol berturut-turut. Jika catatan non-nol pertama memiliki kode 4, register kode 0 otomatis ditambahkan 15 menit setelah, atau 1 menit sebelum register berikutnya jika telah terdaftar kurang dari 15 menit setelah. Jika catatan non-nol pertama memiliki kode 3, register kode 0 otomatis selalu ditambahkan 1 menit sebelum register berikutnya. Setiap kasus lain menghasilkan kesalahan. Contoh:

    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.
    
  • Karyawan mendaftarkan dua register kode 1 atau dua register kode 2. Karena keduanya sebenarnya dapat dipertukarkan, itu tidak dihitung sebagai kesalahan. Jika kode 1 atau kode 2 mendaftar berjumlah lebih dari 2 register, itu menghasilkan kesalahan.

Tantangan

Tujuan utamanya adalah menghitung berapa jam dan menit yang dihabiskan karyawan di kantor. Ini dilakukan setelah memperbaiki (jika perlu dan mungkin) daftar register input. Perhatikan bahwa daftar register yang tepat akan mengganti register nol dengan register bukan nol.

Jadi, algoritma akan menerima daftar register untuk karyawan dan hari pemberian, dan akan mengembalikan waktu yang dihabiskan bekerja untuk hari itu. Jika waktu tidak dapat menghitung waktu yang dihabiskan jika terjadi kesalahan, itu akan mengembalikan 0 jam, 0 menit.

Aturan:

  • Waktu yang dihabiskan adalah jumlah waktu yang dihabiskan antara setiap register kode 0 dan register non-nol berikut. Jika kode bukan nol adalah 3, waktu yang dihabiskan antara register itu dan register kode 0 berikut juga akan dihitung.
  • Anda dapat mengasumsikan bahwa daftar register input akan dalam urutan waktu naik, dan bahwa semua register akan dari hari yang sama (tidak ada yang akan bekerja di luar tengah malam).
  • Register input tidak akan kosong.
  • Format input dapat berupa apa saja yang dibutuhkan kode Anda, selama waktu dinyatakan dengan nilai jam dan nilai menit (jumlah titik-mengambang jam tidak akan menjadi input yang valid). Contoh: Daftar dengan kode dan daftar dengan waktu sebagai string, kedua daftar memiliki panjang yang sama; daftar daftar bilangan bulat, menjadi bilangan bulat kode, jam dan menit register ...
  • Outputnya dapat berupa string dengan waktu (dalam format apa pun yang Anda inginkan: H: mm, HH: mm, H: m ...); daftar dua bilangan bulat dengan jam dan menit dihitung; apa pun yang dapat diartikan sebagai tuple menit-jam (angka titik-mengambang dengan jam yang dihabiskan tidak akan diizinkan). Atau Anda dapat mencetak hasilnya ke STDOUT.

Uji kasus

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

Saya tahu ini bisa membingungkan (masalah dunia nyata memiliki lebih banyak kasus untuk dipertimbangkan, jadi saya tahu itu). Tolong, jangan ragu untuk meminta lebih banyak contoh.

Ini adalah , jadi semoga kode terpendek untuk setiap bahasa menang!


Anda dapat berkomentar bagaimana meningkatkan sistem jika Anda mau, tetapi bukan itu intinya. Bos saya tidak cenderung menghabiskan waktu untuk mengubahnya. :-)

Charlie
sumber
Kotak pasir .
Charlie

Jawaban:

3

Python 3 , 327 322 318 317 byte

Terima kasih atas @JonathanFrech dan @ Mr.Xcoder karena telah menyingkirkan beberapa byte.

Mengambil input sebagai daftar kode ( C) dan daftar waktu ( T) ( (hours, minutes)tupel). Mengembalikan (hours, minutes)tuple.

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)

Diverifikasi terhadap contoh yang diberikan.

Tidak disatukan

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)
Hannes Karppila
sumber
318 byte .
Jonathan Frech
Negasi yang tidak kupikirkan. Trik yang bagus.
Hannes Karppila
Anda bisa menggunakan L(3)bukan 3in C.
Tn. Xcoder