Wie lange ist noch?

21

Wie lange ist noch?

Vor kurzem habe ich mit einem 5-Minuten-Timer auf meinem Handy Pizza gemacht. Als jemand hereinkam und mich fragte, wie lange ich noch Zeit hätte, war ich zunächst für einen Moment verwirrt, wie ich die Frage beantworten sollte. Sie sehen, wenn der Zeitgeber zum gegenwärtigen Zeitpunkt um 3:47 war, hätte sich die Zeit geändert, als ich laut 'Drei Minuten und siebenundvierzig Sekunden' vorgelesen hatte. Daher muss ich eine Zeit finden, die der Timer erreicht, sobald ich mit dem Auslesen fertig bin.

Dies ist Ihre Herausforderung: Diesen Prozess zu automatisieren. Wenn Sie eine Zeit in einem geeigneten Format (":" mit Trennzeichen oder als Argument für Minute und Sekunde) angeben, geben Sie die früheste Zeit ab diesem aktuellen Zeitpunkt aus, für deren Auslesen die gleiche Zeit erforderlich ist wie für den Zeitgeber zu. Wir gehen davon aus, dass das Auslesen jeder Silbe 1 Sekunde dauert.

Weitere Regeln

  • Sie müssen 'Minuten' und 'Sekunden' jeweils als zwei der Silben sowie ein 'und' dazwischen zählen.
  • Die Pizza braucht nie mehr als 59:59, um zu kochen.
  • '11 Minuten und 0 Sekunden 'ist nicht 10 Silben: Sie müssen zu '11 Minuten' (dh 5 Silben) vereinfachen. Gleiches gilt für Minuten: '0 Minuten und 7 Sekunden' werden ebenfalls nur als 4 Silben gezählt.
  • Ihr Programm kann die Ausgabe in einem beliebigen Format ausgeben: als Array von [minutes, seconds]oder sogar als <minutes> minutes and <seconds> seconds(normal ausgeschriebener Text).
  • Es gelten Standardlücken.
  • Das ist , also gewinnt die kürzeste Antwort in Bytes.

Testfälle

Alle Eingaben als (minutes, seconds)

(4, 47) = (4, 38) (Four MiNutes And ThirTy Eight SeConds - 9 syllables/seconds)
(1, 1) = (0, 56) (FifTy-Six SeConds - 5 syllables/seconds)
(59, 57) = (59, 46) (FifTy Nine Minutes And Forty Six SeConds - 11 syllables/seconds)
(0, 10) = null/error/0 (no positive answer)

Silbenzahlreferenz

Als Referenz ist hier die Anzahl der Silben in jeder Zahl bis zu 59 angegeben.

0,0 (does not need to be counted)
1,1
2,1
3,1
4,1
5,1
6,1
7,2
8,1
9,1
10,1
11,3
12,1
13,2
14,2
15,2
16,2
17,3
18,2
19,2
20,2
21,3
22,3
23,3
24,3
25,3
26,3
27,4
28,3
29,3
30,2
31,3
32,3
33,3
34,3
35,3
36,3
37,4
38,3
39,3
40,2
41,3
42,3
43,3
44,3
45,3
46,3
47,4
48,3
49,3
50,2
51,3
52,3
53,3
54,3
55,3
56,3
57,4
58,3
59,3
Geza Kerecsenyi
quelle
Wäre 4:37 für Ihren ersten Testfall auch eine gültige Ausgabe, da dies 10 Silben kosten würde?
Quinn
1
@Quinn, die Spezifikation besagt, dass wir den frühesten Zeitpunkt ausgeben sollen .
Shaggy
1
@ Shaggy whoops, also tut es danke - wenn ich meine Antwort aussortiere, denke ich, dass meine Pizza verbrannt sein wird
Quinn
Dürfen wir annehmen, dass die Eingabe aufgefüllt werden kann, dh 4 Minuten und 43 Sekunden könnten als "04:43" eingegeben werden?
Vedvart1,
1
@ Vedvart1 OK, das ist in Ordnung
Geza Kerecsenyi

Antworten:

4

JavaScript (ES6),  112 106  105 Byte

Eine kürzere Version basierend auf einem Vorschlag von @EmbodimentofIgnorance
6 weitere Bytes, die von @DaniilTutubalin gespeichert wurden

(minutes)(seconds)[minutes, seconds]0

m=>d=F=s=>m|s?(g=n=>n&&(n%10!=7)-7+(n-11?n<13?2:n<21|n%10<1:0))(m)+g(s)^~d?F(s?s-1:m--&&59,d=-~d):[m,s]:0

Probieren Sie es online!


JavaScript (ES6),  126  119 Bytes

(minutes)(seconds)[minutes, seconds]0

m=>d=F=s=>m|s?(g=n=>n&&2+(30774612>>2*n%(n>12?20:26)&3)+(n>12)+(n>19))(m)+g(s)+!!(m*s)^d?F(s?s-1:m--&&59,d=-~d):[m,s]:0

Probieren Sie es online!

Kommentiert

m =>                  // m = minutes
d =                   // d = delta in seconds between the initial time and the current time,
                      //     initialized to a non-numeric value (zero-ish)
F = s =>              // F is a recursive function taking s = seconds
  m | s ? (           // if either m or s is not 0:
    g = n =>          //   g is a helper function taking an integer n in [0..59]
      n &&            //     return 0 if n = 0
      2 + (           //     otherwise, start with 2 for either 'mi-nutes' or 'se-conds'
        30774612 >>   //     add the base number of syllables (0 to 3) corresponding to n
        2 * n %       //     using a bitmask of 13 entries x 2-bit:
                      //       12 11 10  9  8  7  6  5  4  3  2  1  0
                      //       01 11 01 01 01 10 01 01 01 01 01 01 00
        (n > 12 ? 20  //     using n MOD 10 if n is greater than 12
                : 26) //     or just n otherwise
        & 3           //     isolate the two least significant bits
      ) +             //   
      (n > 12) +      //     add 1 syllable for '-teen' or '-ty' if n is greater than 12
      (n > 19)        //     add 1 more syllable for 'x-ty' if n is greater than 19
  )(m) +              //   invoke g for the minutes
  g(s) +              //   invoke g for the seconds
  !!(m * s)           //   add 1 syllable for 'and' if both m and s are non-zero
  ^ d ?               //   if the result is not equal to the delta:
    F(                //     otherwise, do a recursive call:
      s ? s - 1       //       decrement s if it's not 0,
        : m-- && 59,  //       or decrement m and restart with s = 59
      d = -~d         //       increment the delta
    )                 //     end of recursive call
  :                   //   else:
    [m, s]            //     success: return [m, s]
:                     // else:
  0                   //   failure: return 0
Arnauld
quelle
Könnten Sie bitte eine Erklärung hinzufügen?
Geza Kerecsenyi
@GezaKerecsenyi Fertig :-)
Arnauld
Vielen Dank. Es war hauptsächlich der 30774612>>2*n%(n>12?20:26)&3Teil, über den ich verwirrt war.
Geza Kerecsenyi
1
g=x=>x&&(x%10==7)+(x==11?6:x<13?4:x<21|x%10<1?5:6)funktioniert möglicherweise (ungetestet, da das Internet nicht funktioniert und ich mein Telefon benutze)
Verkörperung der Ignoranz
1
@ DaniilTutubalin Cool. Ich habe ein weiteres Byte von dort gespeichert, indem ich g()das entgegengesetzte Ergebnis zurückgegeben und mit XOR'ing gearbeitet habe ~d.
Arnauld
2

Python 3 , 287 285 Bytes

m=int(input())
s=int(input())
y=lambda w:3+(w[-1]=='7')-(w[-1]=='0')-(w[0]in'01')*(1+(w[0]=='0'))+(w=='11')-(w=='12')
z=lambda m,s:(2+y(f'{m:02d}'))*(m!=0)+(2+y(f'{s:02d}'))*(s!=0)+(m!=0!=s)
q=lambda t: (m-(t+60-s-1)//60,(s-t)%60)
print([q(t) for t in range(s+60*m) if z(*q(t))==t][0])

Probieren Sie es online!

Es ist keine sehr clevere Lösung - es ist meist unproblematisch. Nimmt 'm: s' m und s als separate Eingänge (muss nicht aufgefüllt werden) und Ausgänge (m, s). Löst einen Fehler aus, wenn keine gültige Ausgabe vorliegt.

Das Programm ist stark darauf angewiesen, Boolesche Werte implizit auf 0 und 1 zu setzen. Die erste Zeile nimmt Eingaben entgegen. Die zweite Zeile definiert eine Lambda-Funktion y, die die Silben in einer Zahl angibt - sie nimmt eine Basis von 3 Silben an, addiert 1, wenn sie mit 7 endet, subtrahiert 1, wenn sie mit 0 endet, und subtrahiert 1, wenn sie in den 10er und ist 2, wenn es sich um eine einstellige Zahl handelt. Zwölf und elf werden am Ende manuell eingestellt. Die dritte Zeile ist ein Lambda für die Silben im gesamten Ausdruck. Schließlich gibt die vierte Zeile die Zeit nach t Sekunden an. Die fünfte Zeile ist die Ausgabe - sie erstellt ein Array aller Zeiten, die das Problem lösen, und gibt die erste aus.

EDIT 1: Dank Matthew Anderson in den Kommentaren wurden 2 Bytes abgeschnitten, indem die Eingaben separat genommen wurden.

Vedvart1
quelle
1
Wenn Sie Eingaben in zwei getrennten Zeilen vornehmen: m=int(input()) s=int(input())können Sie 2 Bytes sparen.
Matthew Anderson
1

Jelly , 46 Bytes

ḅḶbɗ60Ṛµ“÷ṢḣxE⁻Ṇ⁹ƬƝwɼỤṡl’ḃ4+2;0⁸ịS+ṬS$’)=JTị⁸Ḣ

Probieren Sie es online!

Ein monadischer Link, der die Zeit als [minutes, seconds]und die entsprechende Zeit als [minutes, seconds]oder in [seconds]weniger als einer Minute als Argument verwendet .

Nick Kennedy
quelle
0

CJam , 102 Bytes

60:X;q~\X*+:W_{;(__X%\X/{_196656821516111872\_A%K+e<_{(2*m>3&3.5+}{\;}?@}2*+i+\X*+_W=!2$0<-}g;_X%\X/S@

Probieren Sie es online!

Nur eine langweilige alte Binär-Nachschlagetabelle mit magischen Zahlen, hier nichts zu sehen.

JosiahRyanW
quelle