Otimização de alarme

28

Meu despertador

Sou americano e meu despertador (digital) também. Para definir o alarme, ele inicia no momento em que estava anteriormente. Pressionar o botão da hora aumenta uma hora e pressionar o botão dos minutos aumenta um minuto. Pressionar os dois botões ao mesmo tempo o redefine para meia-noite (12:00) e conta como dois botões pressionados.

Quando as horas excedem o limite (12), ele é redefinido para 1 e alterna a luz AM / PM. Quando os minutos excedem o limite (59), eles são redefinidos para 0, sem afetar as horas.

A tarefa

Sua tarefa é, dada a hora de início e a hora prevista, produzir o número ideal de pressionamentos de botões necessários para definir meu alarme para a hora prevista.

Você pode receber informações no formato que melhor lhe convier. Os únicos dados que seu programa precisa são horas e minutos, para ambas as entradas. Isso significa que você, por exemplo, pode levar dados em milissegundos desde a época e extrair as horas e os minutos, mas você não pode codificar nada para o ano, mês, segundo, etc. Observe que enquanto você pode, por exemplo, inserir usando "horário militar" (ou horário regular para a maior parte do mundo), mas isso não muda o funcionamento do meu relógio.

Exemplos

1:15 pm -> 2:30 am

Você pode pressionar os dois botões para redefinir para 12:00 e depois aumentar para 2:30, o que seria 2+2+30 = 34pressionamento de botão. Você também pode aumentar para 2h30, o que seria 13+15 = 28pressionar o botão. Portanto, sua saída é 28.

3:58 am -> 4:02 am

Você pode redefinir e incrementar, o que seria 2+4+2 = 8pressionar o botão. Você também pode incrementar, o que seria 1+4 = 5pressionar o botão. Portanto, sua saída é 5.

10:55 pm -> 1:00 am

Você pode redefinir e incrementar, o que seria 2+1 = 3pressionar o botão. Você também pode incrementar, o que seria 3+5=8pressionar o botão. Portanto, sua saída é 3.

1:00 am -> 1:59 pm

Você poderia redefinir e incrementar, mas seriam mais três impressoras do que apenas incrementar. Portanto, sua saída é 12+59 = 71.

Casos de teste

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
fonte
Sandbox
Stephen
13
Caralho! Pressionando os dois botões não repor o meu despertador (europeu) para 0:00 assim ... Todos esses anos passou pressionando os botões muitas vezes ... O_o
Arnauld
8
"horário militar (ou horário regular para a maior parte do mundo)" ... ... o termo que você procura é "horário de 24 horas".
Jakob
12
@ Jakob Não, o termo que ele procura é "horário regular". Os americanos usam o tempo irregular, datas irregulares, unidades irregulares, etc. etc.
Neil
1
@StepHen Estou no Reino Unido e não tinha ideia do que você quis dizer com "tempo militar" até Jakob explicar. O tempo de 24 horas faz todo o sentido para mim
Darren H

Respostas:

5

Casca , 16 bytes

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

Experimente online!

Recebe argumentos como duas listas [horas, minutos], para as horas de início e término, no formato 24h.

Estou muito feliz com o quanto consegui jogar golfe, acho interessante como os argumentos são gerenciados nessa composição de funções.

A função que calcula quantas teclas são necessárias se a redefinição não for permitida é a seguinte:

Σ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

A parte interessante é que, como o restante dessa solução pode funcionar apenas com uma única lista como argumento, essa é aplicada parcialmente ao primeiro argumento de todo o programa, "comendo" e deixando apenas o segundo argumento visível para si e para o o resto do programa.

Em seguida, calculamos quantas teclas são necessárias se redefinirmos o horário para 0:00

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

Como dito anteriormente, isso opera apenas no segundo argumento (o tempo final) e calcula hours+minutes+2, apenas de uma maneira mais eficiente.

Finalmente, §▼é a parte que passa o segundo argumento para ambas as funções e retorna o menor dos dois resultados.

Leo
fonte
8

JavaScript (ES6), 73 56 54 52 50 bytes

Usa o formato de 24 horas. Recebe a entrada como 4 números inteiros, representando as horas e minutos de cada vez.

(g,l,h,m)=>Math.min(2+h+m,(h-g+24)%24+(m-l+60)%60)
  • 2 bytes economizados graças ao Arnauld .

Tente

Digite os horários no formato de 24 horas, com o :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>


Explicação

(A ser atualizado em breve.)

(g,l,h,m)=>

Anonymous função tendo os números inteiros como argumentos através de parâmetros g, l, h& m, onde g& lsão, respectivamente, as horas e minutos do tempo corrente e h& msão as horas e minutos do tempo de destino.

2+h+m

Primeiro, calculamos quantos pressionamentos de botão são necessários se apenas redefinirmos o relógio, que é simplesmente 2 (para redefinir) mais a hora e o minuto alvo.

h-g+24*(h<g)

Em seguida, calculamos quantos pressionamentos de botão são necessários para atingir a hora desejada. Fazemos isso subtraindo a hora atual da hora prevista. No entanto, se a hora atual for menor que a meta, isso nos dará um número negativo, portanto, retificaremos isso adicionando 24 multiplicado verificando se h<g(que retorna um booleano, mas é implicitamente convertido em número inteiro 1, se verdadeiro ou 0falso pelo operações matemáticas.

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

Usamos uma fórmula semelhante para calcular o número de prensas para ir do minuto atual ao minuto alvo e adicionamos isso às prensas da hora.

Math.min()

Finalmente, obtemos o mínimo dos 2 números para nos dar o resultado.

Shaggy
fonte
1
Você poderia fazer (h-g+24)%24+(m-l+60)%60?
Arnauld
7

Pitão , 29 bytes

Obviamente, esse desafio não beneficia os idiomas do golfe, por isso é tão longo. Por outro lado, isso é aprimorado pelo fato de Pyth ser baseado em Python, para que possamos abusar de seu módulo negativo.

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

Suíte de teste. Os números em Pyth não suportam zeros à esquerda.

Mr. Xcoder
fonte
5

Geléia , 19 bytes

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

Experimente online!

Entrada como 4 números inteiros (hora final, minuto final, hora inicial, minuto inicial)

HyperNeutrino
fonte
1
i.stack.imgur.com/mYVF7.jpg
ETHproductions
@ETHproductions ಠ_ಠ
HyperNeutrino
3

C # (.NET Core) , 56 bytes

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

Experimente online!

Muito parecido com a resposta Javascript. Bools em C # não se convertem facilmente em números, então, ao invés de [diff]+24*(H<h)eu, o ([diff]+24)%24que efetivamente faz a mesma coisa.

Kamil Drakari
fonte
Você pode remover os parênteses em torno 2+h+mde -2 bytes.
Kevin Cruijssen
Eu criei uma porta de sua resposta em Java 8 , e notei que você pode golfe mais quatro bytes, removendo mais parêntese, terminando com isso(H,M,h,m)=>Math.Min((h+24-H)%24+(m+60-M%60),2+h+m)
Kevin Cruijssen
1
Você não teria que fazer isso System.Math.Min?
precisa saber é o seguinte
3

Haskell, 41 bytes

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

Bem direto. Recebe entrada como quatro argumentos usando o tempo de 24 horas: hora final, minuto final, hora inicial, minuto inicial.

Silvio Mayolo
fonte
2

Python 3 , 43 bytes

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

Experimente online!

Entrada como 4 números inteiros (hora de início, minuto de início, hora final, minuto final)

HyperNeutrino
fonte
@StepHen Whoops. Correção fácil.
HyperNeutrino
Não consegue2 01 11 00 ? Na sua resposta, como você determina se é a hora AMou PMse não considera isso como entrada?
Mr. Xcoder
@ Mr.Xcoder; Eu recebo 13essa entrada usando o TIO, que está correto (redefinir + 11 <9 + 59).
Shaggy
2
Será %sempre retornar um número positivo em Python?
Shaggy
4
@ Shaggy sempre retorna o sinal do lado direito do %. 1%24= 1, 1%-24= -23. É muito útil para esta pergunta.
Stephen
2

Java 8, 54 50 bytes

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

Porto da resposta C # de @KamilDrakari (depois de jogar 2 6 bytes).

Explicação:

Experimente aqui.

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

Experimente online!

Recebe entrada no formato de 24 horas (hora militar), separado por espaços, primeira hora de início e segunda hora de término: HH MM hh mm

Xcali
fonte
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

Experimente online! O link inclui casos de teste. Recebe a entrada como o tempo atual e o desejado em 24 horas, com um espaço separando os dois tempos. Explicação:

\d+
$*

Converta para unário.

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

Isso faz duas coisas; adiciona 24 horas e 60 minutos às horas e minutos desejados e também adiciona 2 à soma das horas e minutos originais desejados, ou seja, o número de botões pressionados para definir usando uma redefinição.

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

Subtraia as horas atuais das horas desejadas e subtraia as 24 que adicionamos, se pudermos.

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

Da mesma forma para os minutos. Isso também adiciona os dois resultados.

(1+)#(?!\1)

Se o número de prensas a serem definidas usando o horário atual for maior que o número de prensas a serem definidas usando uma redefinição, exclua-o.

\G1

Converta o primeiro número restante de volta em decimal.

Neil
fonte