เครื่องคำนวณเวลาทำงาน


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 ... ); รายการจำนวนเต็มสองจำนวนที่คำนวณชั่วโมงและนาที สิ่งใดที่สามารถตีความได้ว่าเป็น tuple ในหนึ่งชั่วโมงนาที (ไม่อนุญาตให้ใช้เลขทศนิยมที่มีชั่วโมงที่ใช้) หรือคุณสามารถพิมพ์ผลลัพธ์ไปที่ 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

Python 3 , 327 322 318 317 ไบต์

ขอบคุณสำหรับ @JonathanFrech และ @ Mr.Xcoder สำหรับการกำจัดบางไบต์

รับอินพุตเป็นรายการของรหัส ( C) และรายการของเวลา ( T) ( (hours, minutes)tuples) ส่งคืน(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)

ตรวจสอบกับตัวอย่างที่ได้รับ

Ungolfed

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)

318 ไบต์
Jonathan Frech

การปฏิเสธที่ฉันไม่ได้คิด เทคนิคที่ดี
Hannes Karppila

คุณสามารถใช้แทนL(3) 3in C
นาย Xcoder
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.