Optimización de alarma

28

Mi reloj despertador

Soy estadounidense, y también lo es mi despertador (digital). Para configurar la alarma, comienza en el momento en que era anteriormente. Al presionar el botón de la hora se mueve hacia arriba una hora, y al presionar el botón de los minutos se sube un minuto. Al presionar ambos botones al mismo tiempo, se restablece a la medianoche (12:00 a.m.) y cuenta como dos pulsaciones de botón.

Cuando las horas exceden su límite (12), se restablece a 1 y alterna la luz AM / PM. Cuando los minutos exceden su límite (59), se restablecen a 0, sin afectar las horas.

La tarea

Su tarea es, dada una hora de inicio y una hora objetivo, generar el número óptimo de pulsaciones de botones necesarias para configurar mi alarma en la hora objetivo.

Puede tomar información en el formato que más le convenga. Los únicos datos que su programa debería necesitar son horas y minutos, para ambas entradas. Eso significa que usted, por ejemplo, puede tomar los datos en milisegundos desde la época, y extraer las horas y minutos, pero no puede codificar nada en el año, mes, segundo, etc. Tenga en cuenta que si bien puede, por ejemplo, ingresar "hora militar" (u hora regular para la mayor parte del mundo), pero eso no cambia la forma en que funciona mi reloj.

Ejemplos

1:15 pm -> 2:30 am

Puede presionar ambos botones para restablecer a las 12:00 a.m., luego aumentar a las 2:30 a.m., que serían 2+2+30 = 34presionar botones. También puede aumentar a las 2:30 am, que serían 13+15 = 28presionar botones. Por lo tanto, su salida es 28.

3:58 am -> 4:02 am

Puede restablecer e incrementar, que serían 2+4+2 = 8presionar botones. También podría aumentar, que serían 1+4 = 5presionar botones. Por lo tanto, su salida es 5.

10:55 pm -> 1:00 am

Puede restablecer e incrementar, que serían 2+1 = 3presionar botones. También podría aumentar, que serían 3+5=8presionar botones. Por lo tanto, su salida es 3.

1:00 am -> 1:59 pm

Puede reiniciar e incrementar, pero eso sería tres prensas más que solo aumentar. Por lo tanto, su salida es 12+59 = 71.

Casos de prueba

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
fuente
Sandbox
Stephen
13
¡Santo cielo! Al presionar los dos botones, el reloj de alarma (europeo) también se restablece a las 0:00 ... Todos estos años pasaron presionando los botones demasiadas veces ... O_o
Arnauld
8
"tiempo militar (o tiempo regular para la mayor parte del mundo)" ... el término que está buscando es "tiempo de 24 horas".
Jakob
12
@Jakob No, el término que está buscando es "tiempo regular". Los estadounidenses usan tiempo irregular, fechas irregulares, unidades irregulares, etc., etc.
Neil
1
@StepHen Estoy en el Reino Unido y no tenía idea de lo que querías decir con "tiempo militar" hasta que Jakob lo explicó. El tiempo de 24 horas tiene mucho sentido para mí
Darren H

Respuestas:

5

Casco , 16 bytes

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

Pruébalo en línea!

Toma los argumentos como dos listas [horas, minutos], para la hora de inicio y finalización, en formato de 24 horas.

Estoy bastante contento con lo mucho que pude jugar este golf, me parece interesante cómo se manejan los argumentos en esta composición de funciones.

La función que calcula cuántas pulsaciones de teclas necesitamos si no se permite restablecer es la siguiente:

Σ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

La parte interesante es que, dado que el resto de esta solución solo puede funcionar con una sola lista como argumento, esta se aplica parcialmente al primer argumento de todo el programa, "comiéndola" y dejando solo el segundo argumento visible tanto para sí mismo como para él. El resto del programa.

A continuación, calculamos cuántas pulsaciones de teclas necesitamos si restablecemos el tiempo a 0:00

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

Como se dijo antes, esto opera solo en el segundo argumento (el tiempo final), y calcula hours+minutes+2, solo de una manera más golfista.

Finalmente, §▼es la parte que pasa el segundo argumento a ambas funciones y devuelve el menor de los dos resultados.

León
fuente
8

JavaScript (ES6), 73 56 54 52 50 bytes

Utiliza formato de 24 horas. Toma la entrada como 4 enteros que representan las horas y minutos de cada vez.

(g,l,h,m)=>Math.min(2+h+m,(h-g+24)%24+(m-l+60)%60)
  • 2 bytes guardados gracias a Arnauld .

Intentalo

Ingrese las horas en formato de 24 horas, con el :separador.

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>


Explicación

(Se actualizará en breve).

(g,l,h,m)=>

Función anónima teniendo los enteros como argumentos a través de parámetros g, l, hy m, donde gy lson, respectivamente, las horas y minutos de la hora actual y hY mson las horas y minutos de la hora de destino.

2+h+m

Primero, calculamos cuántas pulsaciones de botón son necesarias si solo reiniciamos el reloj, que es simplemente 2 (para el reinicio) más la hora objetivo y el minuto objetivo.

h-g+24*(h<g)

A continuación, calculamos cuántas pulsaciones de botón son necesarias para alcanzar la hora objetivo. Hacemos esto restando la hora actual de la hora objetivo. Sin embargo, si la hora actual es menor que el objetivo, esto nos dará un número negativo, por lo que rectificaremos al sumar 24 multiplicado al verificar si h<g(que devuelve un valor booleano pero se convierte implícitamente en entero 1, si es verdadero o 0si es falso por el Operaciones matemáticas.

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

Usamos una fórmula similar para calcular el número de prensas para llegar desde el minuto actual al minuto objetivo y agregarlo a las prensas de hora.

Math.min()

Finalmente, obtenemos el mínimo de los 2 números para darnos nuestro resultado.

Lanudo
fuente
1
Podrías hacer (h-g+24)%24+(m-l+60)%60?
Arnauld
7

Pyth , 29 bytes

Este desafío obviamente no beneficia los idiomas de golf, por eso es tan largo. Por otro lado, esto se mejora por el hecho de que Pyth está basado en Python, por lo que podemos abusar de su módulo negativo.

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

Banco de pruebas. Los números en Pyth no admiten ceros a la izquierda.

Sr. Xcoder
fuente
3

C # (.NET Core) , 56 bytes

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

Pruébalo en línea!

Muy similar a la respuesta de Javascript. Los bools en C # no se convierten fácilmente en números, por lo que, en lugar de hacerlo [diff]+24*(H<h), lo ([diff]+24)%24que efectivamente hace lo mismo.

Kamil Drakari
fuente
Puede eliminar el paréntesis alrededor 2+h+mde -2 bytes.
Kevin Cruijssen
Creé un puerto de su respuesta en Java 8 , y noté que puede jugar cuatro bytes adicionales eliminando más paréntesis, terminando con esto(H,M,h,m)=>Math.Min((h+24-H)%24+(m+60-M%60),2+h+m)
Kevin Cruijssen
1
¿No tendrías que hacerlo System.Math.Min?
LiefdeWen
3

Haskell, 41 bytes

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

Muy claro. Toma la entrada como cuatro argumentos usando el tiempo de 24 horas: hora final, minuto final, hora de inicio, minuto de inicio.

Silvio Mayolo
fuente
2

Python 3 , 43 bytes

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

Pruébalo en línea!

Ingrese como 4 enteros (hora de inicio, minuto de inicio, hora de finalización, minuto de finalización)

Hiperneutrino
fuente
@StepHen Whoops. Solución fácil
HyperNeutrino
Falla por2 01 11 00 ? En su respuesta, ¿cómo determina si es el momento AMo PMsi no lo toma como entrada?
Sr. Xcoder
@ Mr.Xcoder; Obtengo 13esa entrada usando el TIO, que es correcto (reinicio + 11 <9 + 59).
Shaggy
2
¿ %Siempre devuelve un número positivo en Python?
Shaggy
44
@Shaggy siempre devuelve el signo del lado derecho de la %. 1%24= 1, 1%-24= -23. Es muy útil para esta pregunta.
Stephen
2

Java 8, 54 50 bytes

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

Puerto de la respuesta C # de @KamilDrakari (después de jugar golf 2 6 bytes).

Explicación:

Pruébalo aquí

(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
fuente
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

Pruébalo en línea!

Toma datos en formato de 24 horas (hora militar), separados por espacios, hora de inicio primero, hora de finalización segundo: HH MM hh mm

Xcali
fuente
1

Retina , 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

Pruébalo en línea! El enlace incluye casos de prueba. Toma la entrada como tiempos actuales y deseados en un tiempo regular de 24 horas con un espacio que separa los dos tiempos. Explicación:

\d+
$*

Convierte a unario.

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

Esto hace dos cosas; agrega 24 horas y 60 minutos a las horas y minutos deseados, y también agrega 2 a la suma de las horas y minutos deseados originales, es decir, el número de pulsaciones de botón para establecer usando un reinicio.

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

Reste las horas actuales de las horas deseadas y reste las 24 que agregamos si podemos.

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

Del mismo modo para los minutos. Esto también agrega los dos resultados juntos.

(1+)#(?!\1)

Si el número de pulsaciones para configurar con la hora actual es mayor que el número de pulsaciones para configurar con un reinicio, elimínelo.

\G1

Convierta el primer número restante de nuevo a decimal.

Neil
fuente