Quanto tempo resta?

21

Quanto tempo resta?

Recentemente, eu estava fazendo pizza usando um timer de 5 minutos no meu telefone. Quando alguém entrou e me perguntou quanto tempo restava, fiquei confuso por um momento a respeito de como responder à pergunta. Veja bem, se o cronômetro no momento atual fosse às 3:47, quando eu lesse "Três minutos e quarenta e sete segundos" em voz alta, o tempo teria mudado. Portanto, preciso encontrar um tempo que o cronômetro atinja assim que terminar de lê-lo.

Este é o seu desafio: automatizar esse processo. Dado um tempo em qualquer formato apropriado (delimitado por ":" ou como um minuto e um segundo argumento), produza o tempo mais cedo a partir desse momento atual, que levaria uma quantidade igual de tempo para ser lido, pois o tempo seria necessário para que o cronômetro chegasse. para. Estamos assumindo que cada sílaba leva 1 segundo para ser lida.

Regras adicionais

  • Você deve contar 'minutos' e 'segundos' como duas sílabas cada, bem como um 'e' entre elas.
  • A pizza nunca leva mais do que 59:59 para cozinhar.
  • '11 minutos e 0 segundos 'não são 10 sílabas: você deve simplificar para '11 minutos' (ou seja, 5 sílabas). O mesmo acontece com os minutos: '0 minutos e 7 segundos' também são contados apenas como 4 sílabas.
  • Seu programa pode fornecer a saída em qualquer formato: uma matriz de [minutes, seconds], ou mesmo como <minutes> minutes and <seconds> seconds(texto normal escrito).
  • Aplicam-se brechas padrão.
  • Isso é , então a resposta mais curta em bytes vence.

Casos de teste

Todas as 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)

Referência de contagem de sílabas

Para referência, aqui está o número de sílabas em cada número até 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
fonte
Para o seu primeiro caso de teste, 4:37 também seria uma saída válida, pois isso levaria 10 sílabas para dizer?
Quinn
1
@Quinn, a especificação afirma que devemos produzir o mais cedo possível .
Shaggy
1
@ Shaggy whoops, por isso, obrigado - no momento em que eu resolver minha resposta, acho que minha pizza será queimada
Quinn
É permitido assumir que a entrada pode ser preenchida, ou seja, 4 minutos e 43 segundos podem ser inseridos como "04:43"?
Vedvart1 12/07
1
@ Vedvart1 OK, tudo bem
Geza Kerecsenyi

Respostas:

4

JavaScript (ES6),  112 106  105 bytes

Uma versão mais curta com base em uma sugestão de @EmbodimentofIgnorance Mais
6 bytes salvos por @DaniilTutubalin

(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

Experimente 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

Experimente online!

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
fonte
Você poderia adicionar uma explicação?
Geza Kerecsenyi 13/07
@GezaKerecsenyi Done. :-)
Arnauld
Obrigado. Foi principalmente a 30774612>>2*n%(n>12?20:26)&3parte que eu estava confuso.
Geza Kerecsenyi 13/07
1
g=x=>x&&(x%10==7)+(x==11?6:x<13?4:x<21|x%10<1?5:6)pode funcionar (não testado, pois a Internet está inoperante e usando meu telefone)
Modalidade de Ignorância
1
@DaniilTutubalin Cool. Salvei outro byte a partir daí, g()retornando o resultado oposto e usando o XOR ~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])

Experimente online!

Não é uma solução muito inteligente - é basicamente estrita. Toma 'm: s' s como entradas separadas (não precisam ser preenchidas) e saídas (m, s). Lança um erro se não houver saída válida.

O programa depende muito da conversão implícita de booleanos para 0 e 1. A primeira linha recebe entrada. A segunda linha define uma função lambda y que fornece as sílabas em um número - assume uma base de 3 sílabas e adiciona 1 se terminar em 7, subtrai 1 se termina em 0 e subtrai 1 se estiver nos 10 e 2 se estiver nos dígitos de um. Doze e onze são ajustados manualmente no final. A terceira linha é uma lambda para as sílabas em toda a expressão. Finalmente, a quarta linha indica o tempo após t segundos. A quinta linha é a saída - ela cria uma matriz de todos os momentos que satisfazem o problema e gera a primeira.

EDIT 1: Graças a Matthew Anderson nos comentários, foram eliminados 2 bytes retirando as entradas separadamente.

Vedvart1
fonte
1
Se você digitar duas linhas separadas:, m=int(input()) s=int(input())poderá salvar 2 bytes.
Matthew Anderson
1

Gelatina , 46 bytes

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

Experimente online!

Um link monádico tomando como argumento o tempo como [minutes, seconds]e retornando o momento apropriado para dizer como [minutes, seconds]ou [seconds]se menos de um minuto.

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

Experimente online!

Apenas uma velha mesa de pesquisa binária com número mágico, nada para ver aqui.

JosiahRyanW
fonte