Optymalizacja alarmu

28

Mój budzik

Jestem Amerykaninem, podobnie jak mój (cyfrowy) budzik. Aby ustawić alarm, rozpoczyna się w momencie, w którym był wcześniej. Naciśnięcie przycisku godziny powoduje przesunięcie go o jedną godzinę w górę, a naciśnięcie przycisku minuty powoduje przesunięcie go o jedną minutę w górę. Wciśnięcie obu przycisków jednocześnie resetuje je do północy (12:00) i liczy się jako naciśnięcie dwóch przycisków.

Gdy godziny przekroczą limit (12), resetuje się do 1 i przełącza lampkę AM / PM. Gdy minuty przekroczą limit (59), resetują się do 0, bez wpływu na godziny.

Zadanie

Twoim zadaniem jest, biorąc pod uwagę czas rozpoczęcia i czas docelowy, wygenerowanie optymalnej liczby naciśnięć przycisków potrzebnych do ustawienia mojego alarmu na czas docelowy.

Możesz wprowadzać dane w dowolnym formacie, który najbardziej Ci odpowiada. Jedyne dane, których Twój program powinien potrzebować, to godziny i minuty dla obu danych wejściowych. Oznacza to, że na przykład możesz brać dane jako milisekundy od epoki i wyodrębniać godziny i minuty, ale nie możesz niczego zakodować w roku, miesiącu, drugim itd. Pamiętaj, że chociaż możesz na przykład wprowadzać dane za pomocą „czas wojskowy” (lub zwykły czas dla większości świata), ale to nie zmienia sposobu działania mojego zegara.

Przykłady

1:15 pm -> 2:30 am

Możesz nacisnąć oba przyciski, aby zresetować do godziny 12:00, a następnie zwiększyć ją do 2:30, co byłoby 2+2+30 = 34naciśnięciem przycisku. Możesz także zwiększyć czas do 2:30, co byłoby 13+15 = 28naciśnięciem przycisku. Dlatego twój wynik to 28.

3:58 am -> 4:02 am

Możesz zresetować i zwiększyć, co byłoby 2+4+2 = 8naciśnięciem przycisku. Możesz także zwiększać, czyli naciskać 1+4 = 5przyciski. Dlatego twój wynik to 5.

10:55 pm -> 1:00 am

Możesz zresetować i zwiększyć, co byłoby 2+1 = 3naciśnięciem przycisku. Możesz także zwiększać, czyli naciskać 3+5=8przyciski. Dlatego twój wynik to 3.

1:00 am -> 1:59 pm

Możesz resetować i zwiększać, ale byłoby to o trzy kolejne naciśnięcia więcej niż zwiększanie. Dlatego twój wynik to 12+59 = 71.

Przypadki testowe

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
Stephen
źródło
Piaskownica
Stephen
13
O kurczę! Naciśnięcie dwóch przycisków powoduje zresetowanie mojego (europejskiego) budzika również do 0:00 ... Wszystkie te lata spędziłem naciskając przyciski zbyt wiele razy ... O_o
Arnauld
8
„czas wojskowy (lub zwykły czas dla większości świata)” ... termin, którego szukasz, to „czas 24-godzinny”.
Jakob,
12
@Jakob Nie, termin, którego szuka, to „regularny czas”. Amerykanie używają nieregularnego czasu, nieregularnych dat, nieregularnych jednostek itp.
Neil
1
@StepHen Jestem w Wielkiej Brytanii i nie miałem pojęcia, co masz na myśli przez „czas wojskowy”, dopóki Jakob tego nie wyjaśnił. 24-godzinny czas ma dla mnie idealny sens
Darren H

Odpowiedzi:

5

Łuska , 16 bajtów

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

Wypróbuj online!

Traktuje argumenty jako dwie listy [godziny, minuty] dla godziny rozpoczęcia i zakończenia w formacie 24-godzinnym.

Bardzo się cieszę z tego, jak bardzo mogłem zagrać w golfa. Ciekawe jest, w jaki sposób argumenty są zarządzane w tym składzie funkcji.

Funkcja, która oblicza, ile naciśnięć klawiszy potrzebujemy, jeśli resetowanie nie jest dozwolone, jest następująca:

Σ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

Interesujące jest to, że ponieważ reszta tego rozwiązania może działać tylko z jedną listą jako argumentem, ta część zostaje częściowo zastosowana do pierwszego argumentu całego programu, „jedząc” go i pozostawiając tylko drugi argument widoczny zarówno dla siebie, jak i reszta programu.

Następnie obliczamy, ile naciśnięć klawiszy potrzebujemy, jeśli zresetujemy czas do 0:00

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

Jak powiedziano wcześniej, działa to tylko na podstawie drugiego argumentu (czasu ostatecznego) i oblicza hours+minutes+2, po prostu w golfistyczny sposób.

Wreszcie §▼jest część, która przekazuje drugi argument do obu funkcji i zwraca mniejszy z dwóch wyników.

Lew
źródło
8

JavaScript (ES6), 73 56 54 52 50 bajtów

Używa formatu 24-godzinnego. Pobiera dane wejściowe jako 4 liczby całkowite reprezentujące godziny i minuty za każdym razem.

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

Spróbuj

Wprowadź godziny w formacie 24-godzinnym, używając :separatora.

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>


Wyjaśnienie

(Wkrótce zostanie zaktualizowany.)

(g,l,h,m)=>

Funkcja anonimowość przy liczby całkowite jako argumenty za pomocą parametrów g, l, hi m, w którym gi lsą odpowiednio godziny i minuty aktualnego czasu i hi msą godziny i minut czasu docelowego.

2+h+m

Najpierw obliczamy, ile naciśnięć przycisków jest potrzebnych, jeśli po prostu zresetujemy zegar, który jest po prostu 2 (dla resetu) plus docelowa godzina i docelowa minuta.

h-g+24*(h<g)

Następnie obliczamy, ile naciśnięć przycisków potrzeba, aby osiągnąć docelową godzinę. Robimy to, odejmując bieżącą godzinę od godziny docelowej. Jeśli jednak bieżąca godzina jest mniejsza niż docelowa, da nam to liczbę ujemną, więc korygujemy to, dodając 24 pomnożone przez sprawdzenie, czy h<g(co zwraca wartość logiczną, ale jest domyślnie rzutowane na liczbę całkowitą 1, jeśli jest prawdą lub 0jeśli jest fałszem przez operacje matematyczne.

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

Używamy podobnej formuły, aby obliczyć liczbę naciśnięć, aby przejść od bieżącej minuty do minuty docelowej i dodać ją do naciśnięć godzinowych.

Math.min()

Wreszcie otrzymujemy minimum 2 liczby, które dają nam nasz wynik.

Kudłaty
źródło
1
Można zrobić (h-g+24)%24+(m-l+60)%60?
Arnauld,
7

Pyth , 29 bajtów

To wyzwanie oczywiście nie jest korzystne dla języków golfowych, dlatego jest tak długie. Z drugiej strony poprawia to fakt, że Pyth jest oparty na Pythonie, więc możemy nadużywać jego ujemnego modułu.

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

Pakiet testowy. Liczby w Pyth nie obsługują zer wiodących.

Pan Xcoder
źródło
5

Galaretka , 19 bajtów

_⁵%24µ+⁴_⁶%60µ«³+⁴¤

Wypróbuj online!

Wprowadź 4 liczby całkowite (godzina końcowa, minuta końcowa, godzina początkowa, minuta początkowa)

HyperNeutrino
źródło
1
i.stack.imgur.com/mYVF7.jpg
ETHproductions
@ETHproductions ಠ_ಠ
HyperNeutrino
3

C # (.NET Core) , 56 bajtów

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

Wypróbuj online!

Bardzo podobny do odpowiedzi Javascript. Bools w C # nie przekształcają się łatwo w liczby, więc zamiast tego [diff]+24*(H<h)zrobiłem to, ([diff]+24)%24co robi to samo.

Kamil Drakari
źródło
Możesz usunąć nawias wokół 2+h+m-2 bajtów.
Kevin Cruijssen,
Utworzyłem port z twoją odpowiedzią w Javie 8 i zauważyłem, że możesz (H,M,h,m)=>Math.Min((h+24-H)%24+(m+60-M%60),2+h+m)
zagrać w
1
Nie musiałbyś tego robić System.Math.Min?
LiefdeWen,
3

Haskell, 41 bajtów

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

Całkiem proste. Pobiera dane wejściowe jako cztery argumenty przy użyciu 24-godzinnego czasu: godzina zakończenia, minuta zakończenia, godzina rozpoczęcia, minuta rozpoczęcia.

Silvio Mayolo
źródło
2

Python 3 , 43 bajty

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

Wypróbuj online!

Wprowadź 4 liczby całkowite (godzina początkowa, minuta początkowa, godzina końcowa, minuta końcowa)

HyperNeutrino
źródło
@StepHen Ups. Łatwa naprawa.
HyperNeutrino,
Nie działa2 01 11 00 ? W swojej odpowiedzi, jak określić, czy jest czasAM lub PM, jeśli nie ma to jak wejście?
Pan Xcoder,
@ Mr.Xcoder; Dostaję 13to wejście za pomocą TIO, co jest poprawne (reset + 11 <9 + 59).
Kudłaty
2
Czy %zawsze zwraca liczbę dodatnią w Pythonie?
Kudłaty
4
@ Shaggy zawsze zwraca znak prawej strony %. 1%24= 1, 1%-24= -23. Jest to bardzo pomocne w przypadku tego pytania.
Stephen
2

Java 8, 54 50 bajtów

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

Port odpowiedzi C # @KamilDrakari (po tym, jak grałem w golfa 2 6 bajtów).

Wyjaśnienie:

Wypróbuj tutaj.

(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
Kevin Cruijssen
źródło
1

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

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

Wypróbuj online!

Pobiera dane w formacie 24-godzinnym (czas wojskowy), oddzielone spacjami, czas rozpoczęcia pierwszy, czas zakończenia drugi: GG MM GG mm

Xcali
źródło
1

Siatkówka , 106 bajtów

\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

Wypróbuj online! Link zawiera przypadki testowe. Pobiera dane wejściowe jako bieżące i pożądane czasy w regularnym czasie 24-godzinnym z odstępem oddzielającym dwa razy. Wyjaśnienie:

\d+
$*

Konwertuj na unary.

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

To robi dwie rzeczy; dodaje 24 godziny i 60 minut do pożądanych godzin i minut, a także dodaje 2 do sumy oryginalnych pożądanych godzin i minut, tj. liczby naciśnięć przycisków, które należy ustawić za pomocą resetu.

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

Odejmij bieżące godziny od żądanych godzin i odejmij 24, które dodaliśmy, jeśli możemy.

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

Podobnie dla minut. To dodaje również dwa wyniki razem.

(1+)#(?!\1)

Jeśli liczba naciśnięć, które należy ustawić przy użyciu bieżącego czasu, jest większa niż liczba naciśnięć, które należy ustawić za pomocą resetu, usuń go.

\G1

Przekształć pierwszą pozostałą liczbę z powrotem na dziesiętną.

Neil
źródło