Bảng tính thời gian


14

Bảng chấm công

Ở nơi làm việc bạn thường phải hoàn thành bảng chấm công. Nhiệm vụ này là viết mã để giúp điều này.

Đầu vào

Hai lần trong một đồng hồ 12 giờ hơi không chuẩn, biểu thị thời điểm bắt đầu và kết thúc ngày cách nhau bởi một khoảng trắng. Số thứ ba đại diện cho số phút thực hiện cho bữa trưa. Ví dụ

9:14 5:12 30

Điều này có nghĩa là bạn bắt đầu làm việc lúc 9:14 sáng, hoàn thành công việc lúc 5:12 chiều và mất 30 phút để ăn trưa.

Bạn có thể cho rằng

  • Bất kỳ lúc nào trong cột đầu tiên là từ 00:00 (nửa đêm) cho đến nhưng không bao gồm 1 giờ chiều và bất kỳ lúc nào trong cột thứ hai là 1 giờ tối sớm nhất cho đến 11:59 tối.
  • Giờ nghỉ trưa không dài hơn ngày làm việc!

Định dạng đầu vào phải như trong các ví dụ đã cho.

Bài tập

Mã của bạn nên đọc trong một tệp (hoặc đầu vào tiêu chuẩn) của các bộ ba này và cho mỗi đầu ra bạn làm việc trong bao lâu. Đầu ra này sẽ chỉ ra số giờ. Đối với ví dụ trên đây là:

7 giờ và 58 phút trừ đi 30 phút tức là 7 giờ 28 phút.

Đầu ra

Đầu ra của bạn phải chỉ định (toàn bộ) số giờ và phút và không được liệt kê quá 59 phút. Đó là bạn không thể xuất 2 giờ 123 phút. Ngoài ra, mã của bạn có thể xuất ra ở bất kỳ định dạng nào dễ đọc của con người thuận tiện cho bạn.

Ví dụ

10:00 1:00 30    --> 2hr 30min
12:59 1:00 0     --> 0hr 1min
00:00 11:59 0    --> 23hr 59min
10:00 2:03 123   --> 2hr 0min 

3
Tôi không thấy cách định dạng đầu vào nghiêm ngặt ( :thời gian giới hạn trên đồng hồ 12 giờ) thêm bất cứ điều gì vào thử thách này.
Shaggy

3
@Shaggy Phân tích định dạng đầu vào ít nhất là thử thách đối với tôi, bởi vì bạn không thể đảm nhận vị trí nhân vật vì giờ có thể là một hoặc hai ký tự ...
Ryan

Có mã phải đọc một vài dòng? Hoặc nó là đủ nếu nó đọc một dòng?
Luis Mendo

1
Có mã phải chấp nhận nhiều dòng.
Anush

5
@ mbomb007 Bạn có thể downvote, nhưng không thích định dạng đầu vào không phải là lý do để VTC.
Okx

Câu trả lời:


7

MATL , 28 byte

`jYb0&)YOd.5+wgU13L/- 15XODT

Hãy thử trực tuyến!


1
Điều này rất ấn tượng!
Anush

Không nên đầu ra ở định dạng này "XXhr YYmin"?
ibrahim mahrir

@ibrahimmahrir Thử thách nói rằng mã của bạn có thể xuất ra ở bất kỳ định dạng nào dễ đọc của con người thuận tiện cho bạn
Luis Mendo

1
Ah tôi thấy! Tôi sẽ chỉnh sửa câu trả lời của mình để rút ngắn nó. Cảm ơn!
ibrahim mahrir

5

Võng mạc 0.8.2 , 83 byte

\d+
$*
 (1+:)
 12$*1$1
+`1:
:60$*
(1*) :\1(1*)(1*) \2
$3
:(1{60})*(1*)
$#1hr $.2min

Hãy thử trực tuyến! Liên kết bao gồm các trường hợp thử nghiệm. Giải trình:

\d+
$*

Chuyển đổi đầu vào thành unary.

 (1+:)
 12$*1$1

Thêm 12 giờ vào thời gian dừng.

+`1:
:60$*

Nhân số giờ với 60 và thêm vào phút.

(1*) :\1(1*)(1*) \2
$3

Trừ thời gian bắt đầu và thời gian nghỉ từ thời gian dừng.

:(1{60})*(1*)
$#1hr $.2min

Divmod by 60. (Lưu 5 byte cho định dạng đầu ra nhàm chán hơn.)



4

Python 3, 161 byte

Tôi biết điều này thậm chí sẽ không gần với nhỏ nhất, nhưng nó được đọc trong một tệp:

for l in open('t'):
    l=l[:-1].split(':')
    m=-int(l[0])*60+int(l[1][:2])+(int(l[1][3:])*60+720+int(l[2][:2])-int(l[2][2:]))
    print(f'{m//60}hr {m-(m//60*60)}min')

Tôi cảm thấy trớ trêu khi tạm dừng bảng thời gian của mình để làm điều này ...

Python 2.7, 133 byte

Cảm ơn những lời đề nghị trong các ý kiến! Chuyển sang python 2.7 lưu thêm một vài byte vì nó mặc định là chia số nguyên:

for l in open('t'):i,h,l=int,60,l[:-1].split(':');m=-i(l[0])*h+i(l[1][:2])+(i(l[1][3:])*h+720+i(l[2][:2])-i(l[2][2:]));print m/h,m%60

Cách tiếp cận tương tự với python3 là 135 byte do câu lệnh in và mặc định là phân chia float:

for l in open('t'):i,h,l=int,60,l[:-1].split(':');m=-i(l[0])*h+i(l[1][:2])+(i(l[1][3:])*h+720+i(l[2][:2])-i(l[2][2:]));print(m//h,m%60)

1
Bạn có thể tiết kiệm 4 byte bằng cách đặt i=intở đầu và thay đổi dòng thứ ba thànhm=-i(l[0])*60+i(l[1][:2])+(i(l[1][3:])*60+720+i(l[2][:2])-i(l[2][2:]))
DJMcMayhem

@DJMcMayhem Cảm ơn bạn! Tôi đang cố nghĩ cách đơn giản hóa những thứ đó ...
Ryan

2
Câu trả lời đầu tiên rất hay, chào mừng bạn đến với Câu đố lập trình & Golf Code! Để giúp chơi gôn một chút, bạn có thể lấy đầu vào từ STDIN, sử dụng map(int,l[:-1].split(':'))và thả nhiều chuyển đổi sang int, thu gọn mọi thứ thành một lớp lót bằng cách thay thế thụt lề bằng ;vv để tiết kiệm một vài byte. Ngoài ra, bạn có thể truy cập Mẹo để chơi gôn trong Python để biết một số thủ thuật gọn gàng hơn mà những người dùng khác đã phát hiện trong cuộc sống của người chơi gôn :).
Ông Xcoder

1
Ngoài ra, OP dường như ít hạn chế hơn về định dạng đầu ra , vì vậy tôi nghĩ print(m,m%60)sẽ đủ. (Cũng lưu ý việc sử dụng m%60thay thế m-(m//60*60))
Ông Xcoder

@ Mr.Xcoder Cảm ơn!
Ryan

4

C, 105 byte

a,b,c,d,e;f(){for(;scanf("%d:%d%d:%d%d",&a,&b,&c,&d,&e);)a=(12+c-a)*60+d-b-e,printf("%d:%d ",a/60,a%60);}

Hoàn toàn đơn giản. Hãy thử trực tuyến tại đây .

Ung dung:

a, b, c, d, e; // start hours, minutes; end hours, minutes; break - all implicitly int
f() { // function - return type is implicitly int (unused)
    for(; scanf("%d:%d%d:%d%d", &a, &b, &c, &d, &e) ;) // until EOF is hit, read line by line
        a = (12 + c - a) * 60 + d - b - e, printf("%d:%d,", a / 60, a % 60); // calculate the minutes and store, then output separated: "h m"
}

Đề xuất a,b,c,d;f(e)thay vì a,b,c,d,e;f();printf("%d:%d ",a/60,a%60))a=(12+c-a)*60+d-b-e;}thay vì;)a=(12+c-a)*60+d-b-e,printf("%d:%d ",a/60,a%60);
trần mèo

4

Ngôn ngữ Wolfram 125 119 111 byte

i=Interpreter;j=IntegerPart;Row@{j[t=(i["Time"][#2<>"pm"]-i["Time"][#])[[1]]-#3/60],"hr ",j[60Mod[t,1]],"min"}&

8 byte được lưu nhờ người dùng 202729

Thí dụ

Chữ viết tắt không được sử dụng ở đây, để làm cho việc theo logic dễ dàng hơn.

Row[{IntegerPart[
 t = (Interpreter["Time"][#2 <> "pm"] - 
      Interpreter["Time"][#])[[1]] - #3/60], "hr ",
IntegerPart[60 Mod[t,1]], "min"}] &["9:00", "4:12", 20]

6 giờ 51 phút

Interpreter["Time"][#2 <> "pm"] diễn giải như một thời điểm tham số thứ hai theo sau là "pm", cụ thể là trong trường hợp này là "4:12 pm", trả về một TimeObjecttương ứng với 4:12 chiều.

-Interpreter["Time"][# <> "am"])[[1]] - #3/60]. #3là tham số thứ ba, cụ thể là 20 phút. Dấu trừ sẽ trừ đi khoảng thời gian ăn trưa từ cuối giờ làm việc. Nó trả về kết thúc thời gian thay đổi đã điều chỉnh, nghĩa là kết thúc ca làm việc sẽ khiến người đó không được nghỉ trưa.

Interpreter["Time"][#] diễn giải như một lần tham số đầu tiên, trong trường hợp này, "9:00", trả về TimeObjecttương ứng với 9:00 sáng.

Trừ đi sự thay đổi bắt đầu từ kết thúc điều chỉnh của năng suất thời gian thay đổi t, khoảng thời gian được biểu thị bằng giờ. IntegerPart[t]trả về số giờ hoàn thành làm việc IntegerPart[60 Mod[t,1]], "min"}]trả lại số phút làm việc bổ sung.


Đúng. Cảm ơn. Lần đầu tiên tôi thấy Mod[x, 1]sử dụng.
DavidC

Lấy từ mẹo này (đã xóa) . / Trên thực tế mod 1 hành xử khác với phần phân số cho số âm. / Có Floorthể dùng cho IntegerPart?
dùng202729

Tầng trả về một kết quả không thể giải thích được -6hr 52mincho các giá trị mẫu tôi đã sử dụng. Tôi cần xem xét điều này để hiểu tại sao giá trị âm trong nhiều giờ (và rõ ràng là vài phút) được tạo ra.
DavidC

3

JavaScript, 83 byte 76 byte

s=>(r=s.match(/\d+/g),r=(r[2]-r[0]+12)*60-r[4]-r[1]+ +r[3],(r/60|0)+':'+r%60)

Chỉ cần thoát khỏi chức năng bên trong từ giải pháp bên dưới (Tôi đã nghĩ gì?). Thay đổi định dạng đầu ra là tốt.

Hãy thử trực tuyến!


OLD: JavaScript, 112 byte 111 byte 110 byte

s=>(t=(h,m,a)=>(a?12+h:h)*60+m,r=s.match(/\d+/g),r=t(+r[2],r[3]-r[4],1)-t(r[0],+r[1]),`${r/60|0}hr ${r%60}min`)

Giải trình:

Bên trong hàm chính, chúng ta bắt đầu bằng cách định nghĩa một hàm khác sẽ giúp chúng ta tính toán số phút của thời gian đưa ra, thêm 12 giờ vào tham số giờ nếu tham số thứ ba là đúng:

(hours, minutes, addTwelve) =>
    (addTwelve? hours + 12: hours) * 60 + minutes

Tiếp theo, chúng tôi chia chuỗi bằng một ' 'hoặc':' khớp các số bên trong chuỗi dẫn đến một mảng gồm tất cả các số trong chuỗi.

Sau đó, chúng tôi tính toán sự khác biệt của thời gian kết thúc và thời gian bắt đầu và trừ thời gian ăn trưa bằng cách sử dụng chức năng được xác định trước đó (chuyển đổi chuỗi thành số khi cần thiết).

Cuối cùng, chúng tôi tạo ra chuỗi kết quả: giờ là phần nguyên của r/60và phút là r%60.

Hãy thử trực tuyến!


@Jakob Tôi là người dùng codegolf mới. Tôi vẫn không biết mọi thứ hoạt động như thế nào quanh đây, kể cả TIO. Ngoài ra tôi đã hỏi trong bình luận này làm thế nào để tôi tiếp cận điều này bằng cách sử dụng javascript nhưng không ai trả lời.
ibrahim mahrir

@Jakob TIO đã sửa. Và tôi không sử dụng NodeJS, tôi đang sử dụng bảng điều khiển của trình duyệt. NodeJS đã được thêm vào bởi TIO.
ibrahim mahrir

Vẫn không chắc chắn phương thức nhập là hợp pháp (câu hỏi này không may là hạn chế), nhưng chúng tôi có thể cần một người chơi golf có kinh nghiệm hơn để đăng nhập. Nhưng cũng lưu ý rằng các chương trình cần hỗ trợ nhiều ngày dữ liệu đầu vào - thật không may, điều đó không được thực hiện rất rõ ràng trong mô tả.
Jakob

@Jakob Nếu nhiều ngày hơn nên được sử dụng làm đầu vào, tôi chỉ có thể làm cho hàm chấp nhận một mảng và sử dụng map: a=>a.map(...). Nó sẽ thêm 5 byte vào câu trả lời của tôi. Nhưng tôi vẫn đang chờ OP (hoặc bất cứ ai) trả lời bình luận của tôi.
ibrahim mahrir

Vì JavaScript thuần không có quyền truy cập vào tệp hoặc đầu vào tiêu chuẩn , tôi khuyên bạn nên sử dụng phương thức mặc định sử dụng dấu nhắc GUI: codegolf.meta.stackexchange.com/a/2459/79343
OOBalance 28/07/18

3

Python 2 , 100 byte

for I in open('x'):x,y,z,w,l=map(int,I.replace(':',' ').split());d=60*(12+z-x)+w-y-l;print d/60,d%60

Hãy thử trực tuyến!

Chương trình đầy đủ đọc nhiều dòng từ tệp văn bản, theo chỉ dẫn của OP. Một hàm chỉ phân tích một dòng sẽ tiết kiệm thêm 10 byte.


1
Đây cũng là cách dễ đọc hơn nỗ lực của tôi!
Ryan

3

Java 10, 194 191 byte

u->{var s=new java.util.Scanner(System.in).useDelimiter("\\D");for(int i,a[]=new int[5];;i=(12+a[2]-a[0])*60+a[3]-a[1]-a[4],System.out.println(i/60+":"+i%60))for(i=0;i<5;)a[i++]=s.nextInt();}

I / O là đau đớn trong Java. Chấm dứt bất thường khi không có dòng đầu vào tiếp theo để đọc. Hãy thử trực tuyến tại đây .

Ung dung:

u -> { // lambda taking a dummy input – we're not using it, but it saves a byte
var s = new java.util.Scanner(System.in).useDelimiter("\\D"); // we use this to read integers from standard input; the delimiter is any character that is not part of an integer
for(int i, a[] = new int[5]; ; // infinite loop; i will be used to loop through each line and to store the result in minutes between lines; a will hold the inputs
    i = (12 + a[2] - a[0]) * 60 + a[3] - a[1] - a[4], // after each line, calculate the result in minutes ...
    System.out.println(i / 60 + ":" + i % 60)) // ... and output the result in hours:minutes, followed by a newline
    for(i = 0; i < 5; ) // read the five integers on the current line ...
        a[i++] = s.nextInt(); // ... into the array
}


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.