¿Cuánto tiempo queda?

21

¿Cuánto tiempo queda?

Recientemente, estaba haciendo pizza usando un temporizador de 5 minutos en mi teléfono. Cuando alguien entró y me preguntó cuánto tiempo me quedaba, al principio me confundí por un momento sobre cómo responder la pregunta. Verá, si el temporizador en el momento actual fuera a las 3:47, para cuando hubiera leído en voz alta 'Tres minutos y cuarenta y siete segundos', el tiempo habría cambiado. Por lo tanto, necesito encontrar un momento en que el temporizador llegue justo cuando termine de leerlo.

Este es su desafío: automatizar este proceso. Dado un tiempo en cualquier formato apropiado (":" delimitado, o como un minuto y un segundo argumento), genera el tiempo más temprano desde ese momento actual, lo que tomaría la misma cantidad de tiempo que el temporizador para obtener a. Suponemos que cada sílaba tarda 1 segundo en leerse.

Reglas adicionales

  • Debe contar 'minutos' y 'segundos' como dos de las sílabas cada una, así como un 'y' entre ellas.
  • La pizza nunca tomará más de 59:59 para cocinar.
  • '11 minutos y 0 segundos 'no son 10 sílabas: debe simplificar a '11 minutos' (es decir, 5 sílabas). Lo mismo ocurre con los minutos: '0 minutos y 7 segundos' también solo se cuenta como 4 sílabas.
  • Su programa puede dar la salida en cualquier formato: una matriz de [minutes, seconds], o incluso como <minutes> minutes and <seconds> seconds(texto normal escrito).
  • Se aplican lagunas estándar.
  • Este es el , por lo que la respuesta más corta en bytes gana.

Casos de prueba

Todas las entradas como (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)

Referencia de recuento de sílabas

Como referencia, aquí están el número de sílabas en cada número hasta 59.

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
fuente
Para su primer caso de prueba, ¿4:37 también sería una salida válida, ya que tomaría 10 sílabas para decir?
Quinn
1
@Quinn, la especificación establece que deberíamos emitir la primera hora.
Shaggy
1
@Shaggy whoops, así que gracias - para cuando resuelvo mi respuesta, creo que mi pizza se quemará
Quinn
¿Podemos suponer que la entrada se puede rellenar, es decir, 4 minutos y 43 segundos se pueden ingresar como "04:43"?
Vedvart1
1
@ Vedvart1 OK, está bien
Geza Kerecsenyi

Respuestas:

4

JavaScript (ES6),  112 106  105 bytes

Una versión más corta basada en una sugerencia de @EmbodimentofIgnorance
6 bytes más guardados por @DaniilTutubalin

(minutes)(seconds)[minutes, seconds]0 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

Pruébalo en línea!


JavaScript (ES6),  126  119 bytes

(minutes)(seconds)[minutes, seconds]0 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

Pruébalo en línea!

Comentado

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
fuente
¿Podría por favor agregar una explicación?
Geza Kerecsenyi
@GezaKerecsenyi Hecho. :-)
Arnauld
Gracias. Era sobre todo la 30774612>>2*n%(n>12?20:26)&3parte por la que estaba confundido.
Geza Kerecsenyi
1
g=x=>x&&(x%10==7)+(x==11?6:x<13?4:x<21|x%10<1?5:6)podría funcionar (no probado ya que Internet está caído y usando mi teléfono)
Encarnación de la ignorancia
1
@DaniilTutubalin Cool. Salvé otro byte desde allí al g()devolver el resultado opuesto y hacer XOR con ~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])

Pruébalo en línea!

No es una solución muy inteligente, en su mayoría es muy estricta. Toma 'm: s' mys como entradas separadas (no necesita ser rellenado), y salidas (m, s). Lanza un error si no hay salida válida.

El programa se basa en gran medida en convertir implícitamente los booleanos a 0 y 1. La primera línea toma entrada. La segunda línea define una función lambda y que da las sílabas en un número: asume una base de 3 sílabas, luego suma 1 si termina en 7, resta 1 si termina en 0 y resta 1 si está en los 10 y 2 si está en un solo dígito. Doce y once se ajustan manualmente al final. La tercera línea es una lambda para las sílabas en toda la expresión. Finalmente, la cuarta línea da el tiempo después de t segundos. La quinta línea es la salida: crea una matriz de todas las veces que satisfacen el problema y genera la primera.

EDITAR 1: Gracias a Matthew Anderson en los comentarios, se recortaron 2 bytes tomando las entradas por separado.

Vedvart1
fuente
1
Si toma la entrada en dos líneas separadas: m=int(input()) s=int(input())puede guardar 2 bytes.
Matthew Anderson
1

Jalea , 46 bytes

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

Pruébalo en línea!

Un enlace monádico que toma como argumento el tiempo como [minutes, seconds]y devuelve el tiempo apropiado para decir como [minutes, seconds]o [seconds]menos de un minuto.

Nick Kennedy
fuente
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@

Pruébalo en línea!

Solo una vieja y aburrida tabla binaria de números mágicos, nada que ver aquí.

JosiahRyanW
fuente