Alarmoptimierung

28

Mein Wecker

Ich bin Amerikaner und mein (digitaler) Wecker auch. Um den Alarm einzustellen, startet er zu der Zeit, die er zuvor war. Durch Drücken der Stundentaste wird eine Stunde nach oben und durch Drücken der Minutentaste eine Minute nach oben verschoben. Wenn Sie beide Tasten gleichzeitig drücken, wird dies auf Mitternacht (00:00 Uhr) zurückgesetzt und als zwei Tastendrücke gezählt.

Wenn die Stunden ihre Obergrenze (12) überschreiten, wird sie auf 1 zurückgesetzt und das AM / PM-Licht wird umgeschaltet. Wenn die Minuten ihre Obergrenze (59) überschreiten, werden sie auf 0 zurückgesetzt, ohne die Stunden zu beeinflussen.

Die Aufgabe

Ihre Aufgabe ist es, anhand einer Startzeit und einer Zielzeit die optimale Anzahl von Tastendrücken auszugeben, die erforderlich sind, um meinen Alarm auf die Zielzeit einzustellen.

Sie können Eingaben in einem für Sie am besten geeigneten Format vornehmen. Die einzigen Daten, die Ihr Programm benötigen sollte, sind Stunden und Minuten für beide Eingaben. Das bedeutet, dass Sie zum Beispiel Daten seit der Epoche als Millisekunden annehmen und die Stunden und Minuten extrahieren, aber möglicherweise nichts in das Jahr, den Monat, die Sekunde usw. codieren "Militärzeit" (oder reguläre Zeit für den größten Teil der Welt), aber das ändert nichts an meiner Uhr.

Beispiele

1:15 pm -> 2:30 am

Sie können beide Tasten drücken, um auf 00:00 Uhr zurückzusetzen, und dann auf 02:30 Uhr erhöhen, was einem Drücken von 2+2+30 = 34Tasten entspricht. Sie können auch auf 2:30 vormittags aufsteigen, was ein 13+15 = 28Knopfdruck wäre . Daher ist Ihre Ausgabe 28.

3:58 am -> 4:02 am

Sie könnten zurücksetzen und inkrementieren, was ein 2+4+2 = 8Knopfdruck wäre . Sie könnten auch erhöhen, was ein 1+4 = 5Knopfdruck wäre . Daher ist Ihre Ausgabe 5.

10:55 pm -> 1:00 am

Sie könnten zurücksetzen und inkrementieren, was ein 2+1 = 3Knopfdruck wäre . Sie könnten auch erhöhen, was ein 3+5=8Knopfdruck wäre . Daher ist Ihre Ausgabe 3.

1:00 am -> 1:59 pm

Sie könnten zurücksetzen und inkrementieren, aber das wären drei Druckvorgänge mehr als nur inkrementieren. Daher ist Ihre Ausgabe 12+59 = 71.

Testfälle

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
quelle
Sandbox
Stephen
13
Heiliger Strohsack! Durch Drücken der beiden Tasten wird auch mein (europäischer) Wecker auf 0:00 zurückgesetzt ... All die Jahre, die ich damit verbracht habe, die Tasten zu oft zu drücken ... O_o
Arnauld
8
"Militärzeit (oder reguläre Zeit für den größten Teil der Welt)" ... der gesuchte Begriff ist "24-Stunden-Zeit".
Jakob
12
@ Jakob Nein, der Begriff, den er sucht, ist "reguläre Zeit". Amerikaner verwenden unregelmäßige Zeit, unregelmäßige Daten, unregelmäßige Einheiten usw. usw.
Neil
1
@StepHen Ich bin in Großbritannien und hatte keine Ahnung, was Sie unter "Militärzeit" verstehen, bis Jakob es erklärte. 24-Stunden-Zeit macht für mich vollkommen Sinn
Darren H

Antworten:

5

Schale , 16 Bytes

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

Probieren Sie es online!

Nimmt Argumente als zwei Listen [Stunden, Minuten] für Start- und Endzeit im 24-Stunden-Format.

Ich bin ziemlich glücklich darüber, wie viel Golf ich in diesem Fall spielen konnte. Ich finde es interessant, wie Argumente in dieser Zusammenstellung von Funktionen verwaltet werden.

Die Funktion, die berechnet, wie viele Tastendrücke erforderlich sind, wenn das Zurücksetzen nicht zulässig ist, lautet wie folgt:

Σ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

Der interessante Teil ist, dass, da der Rest dieser Lösung nur mit einer einzigen Liste als Argument arbeiten kann, diese teilweise auf das erste Argument des gesamten Programms angewendet wird, es "frisst" und nur das zweite Argument sowohl für sich selbst als auch für sich selbst sichtbar bleibt der Rest des Programms.

Als nächstes berechnen wir, wie viele Tastendrücke wir benötigen, wenn wir die Zeit auf 0:00 zurücksetzen

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

Wie bereits erwähnt, wird dies nur für das zweite Argument (das letzte Mal) ausgeführt und hours+minutes+2nur auf eine golferischere Weise berechnet .

Schließlich §▼ist dies der Teil, der das zweite Argument an beide Funktionen übergibt und das kleinere der beiden Ergebnisse zurückgibt.

Löwe
quelle
8

JavaScript (ES6), 73 56 54 52 50 Byte

Verwendet das 24-Stunden-Format. Nimmt die Eingabe als 4 Ganzzahlen, die die Stunden und Minuten jeder Zeit darstellen.

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

Versuch es

Geben Sie die Zeiten im 24-Stunden-Format mit dem :Trennzeichen ein.

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>


Erläuterung

(In Kürze zu aktualisieren.)

(g,l,h,m)=>

Anonyme Funktion der ganzen Zahlen als Argumente über die Parameter nehmen g, l, h& m, wo g& lsind jeweils die Stunden und Minuten der aktuellen Zeit und h& msind die Stunden und Minuten von der Zielzeit.

2+h+m

Zuerst berechnen wir, wie viele Tastendrücke erforderlich sind, wenn wir nur die Uhr zurücksetzen. Dies ist einfach 2 (für das Zurücksetzen) plus die Zielstunde und die Zielminute.

h-g+24*(h<g)

Als nächstes berechnen wir, wie viele Knopfdrücke erforderlich sind, um die Zielstunde zu erreichen. Dazu subtrahieren wir die aktuelle Stunde von der Zielstunde. Wenn die aktuelle Stunde jedoch kleiner als das Ziel ist, erhalten wir eine negative Zahl, sodass wir diese korrigieren, indem wir 24 multiplizieren, indem wir prüfen, ob h<g(was einen Booleschen Wert zurückgibt, aber implizit in eine Ganzzahl umgewandelt wird 1, wenn true oder 0wenn false vom mathematische Operationen.

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

Wir verwenden eine ähnliche Formel, um die Anzahl der Druckvorgänge von der aktuellen Minute zur Zielminute zu berechnen und diese zu den Stundenpressen hinzuzufügen.

Math.min()

Schließlich erhalten wir das Minimum der 2 Zahlen, um unser Ergebnis zu erhalten.

Zottelig
quelle
1
Könntest du tun (h-g+24)%24+(m-l+60)%60?
Arnauld
7

Pyth , 29 Bytes

Diese Herausforderung hat offensichtlich keinen Vorteil für die Golfsprachen, deshalb ist sie so lang. Andererseits wird dies durch die Tatsache verbessert, dass Python auf Python basiert, so dass wir dessen negativen Modul missbrauchen können.

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

Test Suite. Zahlen in Pyth unterstützen keine führenden Nullen.

Mr. Xcoder
quelle
3

C # (.NET Core) , 56 Byte

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

Probieren Sie es online!

Sehr ähnlich der Javascript-Antwort. Bools in C # konvertieren nicht einfach in Zahlen. Stattdessen habe [diff]+24*(H<h)ich das getan, ([diff]+24)%24was effektiv dasselbe bewirkt.

Kamil Drakari
quelle
Sie können die Klammer 2+h+mfür -2 Bytes entfernen .
Kevin Cruijssen
Ich habe erstellt einen Port Ihrer Antwort in Java 8 , und bemerkt , dass Sie können Golf weitere vier Bytes von mehr Klammern zu entfernen, endet mit diesem(H,M,h,m)=>Math.Min((h+24-H)%24+(m+60-M%60),2+h+m)
Kevin Cruijssen
1
Müsstest du es nicht schaffen System.Math.Min?
LiefdeWen
3

Haskell, 41 Bytes

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

Ziemlich einfach. Nimmt die Eingabe als vier Argumente unter Verwendung der 24-Stunden-Zeit auf: Endstunde, Endminute, Startstunde, Startminute.

Silvio Mayolo
quelle
2

Python 3 , 43 Bytes

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

Probieren Sie es online!

Eingabe als 4 Ganzzahlen (Startstunde, Startminute, Endstunde, Endminute)

HyperNeutrino
quelle
@StepHen Whoops. Einfache Lösung.
HyperNeutrino
Scheitert für2 01 11 00 ? Wie bestimmen Sie in Ihrer Antwort, ob die Zeit gekommen ist AModer PMob Sie dies nicht als Eingabe nehmen?
Mr. Xcoder
@ Mr.Xcoder; Ich bekomme 13für diesen Eingang den TIO, der korrekt ist (reset + 11 <9 + 59).
Shaggy
2
Gibt %in Python immer eine positive Zahl zurück?
Shaggy
4
@Shaggy liefert immer das Vorzeichen der rechten Seite des %. 1%24= 1, 1%-24= -23. Es ist sehr hilfreich für diese Frage.
Stephen
2

Java 8, 54 50 Bytes

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

Port von @KamilDrakaris C # Antwort (nachdem ich 2 6 Bytes golfen habe ).

Erläuterung:

Probieren Sie es hier aus.

(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
quelle
1

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

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

Probieren Sie es online!

Nimmt Eingaben im 24-Stunden-Format (Militärzeit) vor, getrennt durch Leerzeichen, Startzeit zuerst, Endzeit zweitens: HH MM hh mm

Xcali
quelle
1

Netzhaut , 106 Bytes

\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

Probieren Sie es online! Link enthält Testfälle. Übernimmt die Eingabe als aktuelle und gewünschte Zeit in regulären 24 Stunden, wobei die beiden Zeiten durch ein Leerzeichen voneinander getrennt sind. Erläuterung:

\d+
$*

In Unary konvertieren.

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

Dies macht zwei Dinge; Es addiert 24 Stunden und 60 Minuten zu den gewünschten Stunden und Minuten und 2 zu der Summe der ursprünglich gewünschten Stunden und Minuten, dh der Anzahl der Tastendrücke, die mit einem Reset eingestellt werden.

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

Subtrahieren Sie die aktuellen Stunden von den gewünschten Stunden und subtrahieren Sie die 24, die wir hinzugefügt haben, wenn wir können.

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

Ähnliches gilt für die Minuten. Dies addiert auch die beiden Ergebnisse.

(1+)#(?!\1)

Wenn die Anzahl der mit der aktuellen Zeit einzustellenden Pressen größer ist als die Anzahl der mit einem Reset einzustellenden Pressen, löschen Sie sie.

\G1

Wandle die erste verbleibende Zahl zurück in eine Dezimalzahl.

Neil
quelle