Tối ưu hóa báo động


28

Đồng hồ báo thức của tôi

Tôi là người Mỹ và đồng hồ báo thức (kỹ thuật số) của tôi cũng vậy. Để đặt báo thức, nó bắt đầu tại thời điểm trước đó. Nhấn nút giờ sẽ di chuyển nó lên một giờ và nhấn nút phút sẽ di chuyển nó lên một phút. Nhấn cả hai nút cùng lúc sẽ đặt lại vào nửa đêm (12:00 sáng) và được tính là hai lần nhấn nút.

Khi số giờ vượt quá giới hạn của chúng (12), nó sẽ đặt lại thành 1 và bật đèn AM / PM. Khi số phút vượt quá giới hạn của chúng (59), chúng đặt lại về 0, mà không ảnh hưởng đến giờ.

Nhiệm vụ

Nhiệm vụ của bạn là, đưa ra thời gian bắt đầu và thời gian mục tiêu, để xuất số lần nhấn nút tối ưu cần thiết để đặt báo thức của tôi theo thời gian đích.

Bạn có thể lấy đầu vào ở bất kỳ định dạng nào phù hợp với bạn nhất. Dữ liệu duy nhất mà chương trình của bạn cần là giờ và phút cho cả hai đầu vào. Điều đó có nghĩa là, ví dụ, bạn có thể lấy dữ liệu dưới dạng mili giây kể từ epoch và trích xuất giờ và phút, nhưng bạn không thể mã hóa bất cứ điều gì vào năm, tháng, giây, v.v. "Thời gian quân sự" (hoặc thời gian thường xuyên cho hầu hết thế giới), nhưng điều đó không thay đổi cách đồng hồ của tôi hoạt động.

Ví dụ

1:15 pm -> 2:30 am

Bạn có thể nhấn cả hai nút để đặt lại thành 12:00 sáng, sau đó tăng lên 2:30 sáng, đó sẽ là 2+2+30 = 34nhấn nút. Bạn cũng có thể tăng lên 2:30 sáng, đó sẽ là 13+15 = 28nhấn nút. Do đó, đầu ra của bạn là 28.

3:58 am -> 4:02 am

Bạn có thể thiết lập lại và tăng dần, đó sẽ là 2+4+2 = 8nhấn nút. Bạn cũng có thể tăng, đó sẽ là 1+4 = 5nhấn nút. Do đó, đầu ra của bạn là 5.

10:55 pm -> 1:00 am

Bạn có thể thiết lập lại và tăng dần, đó sẽ là 2+1 = 3nhấn nút. Bạn cũng có thể tăng, đó sẽ là 3+5=8nhấn nút. Do đó, đầu ra của bạn là 3.

1:00 am -> 1:59 pm

Bạn có thể đặt lại và tăng, nhưng đó sẽ là ba lần nhấn hơn là chỉ tăng. Do đó, đầu ra của bạn là 12+59 = 71.

Các trường hợp thử nghiệm

Current  Target   = Output
1:15pm   2:30am   = 28
3:58am   4:02am   = 5
10:55pm  1:00am   = 3
1:00am   1:59pm   = 71
12:00am  12:00am  = 0
6:51pm   12:00am  = 2
2:01pm   11:00pm  = 25
2:01pm   11:01pm  = 9
12:59am  12:01am  = 2
11:50am  12:00pm  = 11


13
Chúa ơi! Nhấn hai nút cũng sẽ đặt lại đồng hồ báo thức (châu Âu) của tôi thành 0:00 ... Tất cả những năm này đã nhấn nút quá nhiều lần ... O_o
Arnauld

8
"Thời gian quân sự (hoặc thời gian thường xuyên cho hầu hết thế giới)" ... thuật ngữ bạn đang tìm kiếm là "thời gian 24 giờ".
Jakob

12
@Jakob Không, thuật ngữ anh ấy tìm kiếm là "thời gian thường xuyên". Người Mỹ sử dụng thời gian không thường xuyên, ngày không thường xuyên, đơn vị không thường xuyên, v.v.
Neil

1
@StepHen Tôi đang ở Vương quốc Anh và không biết ý của bạn là "thời gian quân sự" cho đến khi Jakob giải thích. Thời gian 24 giờ có ý nghĩa hoàn hảo với tôi
Darren H

Câu trả lời:


5

Husk , 16 byte

§▼ṁ→(Σz%e24 60z-

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

Lấy các đối số dưới dạng hai danh sách [giờ, phút], cho thời gian bắt đầu và kết thúc, ở định dạng 24h.

Tôi khá hài lòng về việc tôi có thể chơi gôn này đến mức nào, tôi thấy thú vị về cách các đối số được quản lý trong thành phần chức năng này.

Hàm tính toán số lần nhấn phím chúng ta cần nếu không cho phép đặt lại là như sau:

Σz%e24 60z-
         z-    elementwise subtract the two times
 z%e24 60      take the hours difference modulo 24 and the minutes difference modulo 60
Σ              sum the two resulting numbers

Phần thú vị là vì phần còn lại của giải pháp này chỉ có thể hoạt động với một danh sách duy nhất là đối số, nên đối số này được áp dụng một phần cho đối số đầu tiên của toàn bộ chương trình, "ăn" nó và chỉ để lại đối số thứ hai hiển thị cho cả chính nó và phần còn lại của chương trình.

Tiếp theo, chúng tôi tính toán số lần nhấn phím chúng tôi cần nếu chúng tôi đặt lại thời gian về 0:00

ṁ→    take the sum of each element of the list increased by 1

Như đã nói trước đây, điều này chỉ hoạt động trên đối số thứ hai (lần cuối cùng) và tính toán hours+minutes+2, chỉ theo cách chơi gôn.

Cuối cùng, §▼là phần chuyển đối số thứ hai cho cả hai hàm và trả về kết quả nhỏ hơn của hai kết quả.


8

JavaScript (ES6), 73 56 54 52 50 byte

Sử dụng định dạng 24 giờ. Lấy đầu vào là 4 số nguyên biểu thị giờ & phút mỗi lần.

(g,l,h,m)=>Math.min(2+h+m,(h-g+24)%24+(m-l+60)%60)
  • 2 byte được lưu nhờ Arnauld .

Thử nó

Nhập thời gian ở định dạng 24 giờ, bằng :dấu phân cách.

o.innerText=(f=

(g,l,h,m)=>Math.min(2+h+m,(h-g+24)%24+(m-l+60)%60)

)(+(x=(i.value="01:00").split`:`)[0],+x[1],+(y=(j.value="13:59").split`:`)[0],+y[1]);oninput=_=>o.innerText=f(+(x=i.value.split`:`)[0],+x[1],+(y=j.value.split`:`)[0],+y[1])
label,input{font-family:sans-serif;font-size:14px;height:20px;line-height:20px;vertical-align:middle}input{margin:0 5px 0 0;width:100px;}
<label for=i>Current: </label><input id=i type=time><label for=j>Target: </label><input id=j type=time><pre id=o>


Giải trình

(Sẽ được cập nhật sớm.)

(g,l,h,m)=>

Anonymous chức năng lấy số nguyên như các đối số qua các thông số g, l, h& m, nơi g& llà, tương ứng, giờ & phút của thời gian hiện tại và h& mlà những giờ & phút của thời gian mục tiêu.

2+h+m

Đầu tiên, chúng tôi tính toán số lần nhấn nút là cần thiết nếu chúng tôi chỉ đặt lại đồng hồ, chỉ đơn giản là 2 (cho thiết lập lại) cộng với giờ mục tiêu và phút đích.

h-g+24*(h<g)

Tiếp theo, chúng tôi tính toán số lần nhấn nút là cần thiết để đạt được giờ mục tiêu. Chúng tôi làm điều này bằng cách trừ giờ hiện tại khỏi giờ mục tiêu. Tuy nhiên, nếu giờ hiện tại nhỏ hơn mục tiêu, điều này sẽ cung cấp cho chúng tôi một số âm để chúng tôi khắc phục điều đó bằng cách thêm 24 nhân bằng cách kiểm tra xem h<g(trả về một boolean nhưng được đặt ngầm thành số nguyên 1, nếu đúng hoặc 0sai Các hoạt động toán học.

+m-l+60*(m<l)

Chúng tôi sử dụng một công thức tương tự để tính toán số lần nhấn để có được từ phút hiện tại đến phút đích và thêm vào số lần nhấn đó.

Math.min()

Cuối cùng, chúng tôi nhận được tối thiểu 2 số để cho chúng tôi kết quả.


1
Bạn có thể làm (h-g+24)%24+(m-l+60)%60
Arnauld

7

Bình thường , 29 byte

Thử thách này rõ ràng không có lợi cho ngôn ngữ chơi gôn, đó là lý do tại sao nó quá dài. Mặt khác, điều này được cải thiện bởi thực tế là Pyth dựa trên Python, vì vậy chúng ta có thể lạm dụng mô đun âm của nó.

hS,+%-eQ@Q1 60%-@Q2hQ24+2s>Q2

Phòng thử nghiệm. Các số trong Pyth không hỗ trợ các số 0 hàng đầu.



3

C # (.NET Core) , 56 byte

(H,M,h,m)=>Math.Min(((h+24-H)%24)+((m+60-M)%60),(2+h+m))

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

Rất giống với câu trả lời Javascript. Bools trong C # không dễ dàng chuyển đổi thành số, vì vậy thay vì [diff]+24*(H<h)tôi đã làm ([diff]+24)%24điều đó thực sự làm điều tương tự.


Bạn có thể xóa dấu ngoặc đơn 2+h+mcho -2 byte.
Kevin Cruijssen

Tôi đã tạo một cổng câu trả lời của bạn trong Java 8 và nhận thấy rằng bạn có thể chơi thêm bốn byte bằng cách xóa thêm dấu ngoặc đơn, kết thúc bằng câu này(H,M,h,m)=>Math.Min((h+24-H)%24+(m+60-M%60),2+h+m)
Kevin Cruijssen

1
Bạn sẽ không phải làm nó System.Math.Minchứ?
LiefdeWen

3

Haskell, 41 byte

(a#b)c d=min(a+b+2)$mod(a-c)24+mod(b-d)60

Khá đơn giản. Lấy đầu vào là bốn đối số sử dụng thời gian 24 giờ: giờ kết thúc, phút kết thúc, giờ bắt đầu, phút bắt đầu.


2

Python 3 , 43 byte

lambda a,b,c,d:min((c-a)%24+(d-b)%60,2+c+d)

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

Nhập dưới dạng 4 số nguyên (giờ bắt đầu, phút bắt đầu, giờ kết thúc, phút cuối)


@StepHen Rất tiếc. Dễ dàng sửa chữa.
HyperNeutrino

Thất bại vì2 01 11 00 ? Trong câu trả lời của bạn, làm thế nào để bạn xác định xem thời gian là AMhay PM, nếu bạn không lấy đó làm đầu vào?
Ông Xcoder

@ Mr.Xcoder; Tôi nhận được 13đầu vào đó bằng TIO, điều này là chính xác (đặt lại + 11 <9 + 59).
Xù xì

2
%luôn luôn trả về một số nguyên dương bằng Python?
Xù xì

4
@Shaggy nó luôn trả về dấu của bên phải %. 1%24= 1, 1%-24= -23. Nó rất hữu ích cho câu hỏi này.
Stephen

2

Java 8, 54 50 byte

(h,m,H,M)->Math.min((H-h+24)%24+(M-m+60)%60,H+M+2)

Câu trả lời C # của @KamilDrakari (sau khi tôi đánh gôn 2 6 byte).

Giải trình:

Hãy thử nó ở đây.

(h,m,H,M)->       // Method with four integer parameter and integer return-type
  Math.min(       //  Return the lowest of the following two:
                  //   The hours:
   (H-h           //    Second hours - first hours inputs
       +24)       //    +24 so we won't have negative numbers
           %24    //    mod-24 to get the hours
   +              //   And add the minutes:
    (M-m          //    Second minutes - first minutes inputs
         +60)     //    +60 so we won't have negative numbers
             %60  //    mod-60 to get the minutes
    ,H+M          //  And compare it to the second hours + second minutes inputs
        +2)       //   +2 for the added +24 and +60 to get the positive modulo arguments

1

Perl 5 , 71 +2 (-ap) = 73 byte

($w,$x,$y,$z)=@F;$_=($r=2+$y+$z)>($c=($y-$w+24)%24+($z-$x+60)%60)?$c:$r

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

Đưa đầu vào ở định dạng 24 giờ (giờ quân sự), được phân tách bằng dấu cách, thời gian bắt đầu trước, thời gian kết thúc thứ hai: HH MM hh mm


1

Võng mạc , 106 byte

\d+
$*
 (1*):(1*)
 24$*1$1:60$*1$2#11$1$2
(1*):(1* )\1(1{24})?
$2
(1*) (1*):\1(1{60})?
$2
(1+)#(?!\1)

\G1

Hãy thử trực tuyến! Liên kết bao gồm các trường hợp thử nghiệm. Lấy đầu vào là thời gian hiện tại và mong muốn trong thời gian 24 giờ thông thường với một khoảng cách tách biệt hai lần. Giải trình:

\d+
$*

Chuyển đổi sang unary.

 (1*):(1*)
 24$*1$1:60$*1$2#11$1$2

Điều này làm hai điều; nó thêm 24 giờ và 60 phút vào giờ và phút mong muốn, và nó cũng thêm 2 vào tổng số giờ và phút mong muốn ban đầu, tức là số lần nhấn nút để đặt bằng cách đặt lại.

(1*):(1* )\1(1{24})?
$2

Trừ các giờ hiện tại khỏi số giờ mong muốn và trừ đi 24 mà chúng tôi đã thêm nếu có thể.

(1*) (1*):\1(1{60})?
$2

Tương tự cho các phút. Điều này cũng thêm hai kết quả với nhau.

(1+)#(?!\1)

Nếu số lần nhấn cần đặt trong thời gian hiện tại nhiều hơn số lần nhấn cần đặt bằng cách đặt lại, hãy xóa nó.

\G1

Chuyển đổi số còn lại đầu tiên trở lại thập phân.

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.