Как долго осталось?

21

Как долго осталось?

Недавно я делал пиццу, используя 5-минутный таймер на моем телефоне. Когда кто-то вошел и спросил меня, как долго осталось, я сначала был озадачен тем, как ответить на вопрос. Видите ли, если бы таймер в текущий момент был в 3:47, то к тому времени, когда я зачитал вслух «Три минуты сорок семь секунд», время изменилось бы. Поэтому мне нужно найти время, таймер будет достичь только , как я дочитать его.

Это ваша задача: автоматизировать этот процесс. Если задано время в любом подходящем формате (с разделителем ":" или в качестве аргумента минуты и секунды), выведите самое раннее время из этого текущего момента, которое будет считываться равным количеством времени, которое потребовалось бы таймеру для получения к. Мы предполагаем, что каждый слог считывается за 1 секунду.

Дальнейшие правила

  • Вы должны считать «минуты» и «секунды» как два слога каждый, а также «и» между ними.
  • На приготовление пиццы никогда не уйдет больше 59:59.
  • «11 минут и 0 секунд» - это не 10 слогов: вы должны упростить до «11 минут» (то есть 5 слогов). То же самое касается минут: «0 минут и 7 секунд» также считается только 4 слогами.
  • Ваша программа может выдавать выходные данные в любом формате: массив [minutes, seconds]или даже как <minutes> minutes and <seconds> seconds(обычный текст выписан).
  • Применяются стандартные лазейки.
  • Это , поэтому выигрывает самый короткий ответ в байтах.

Контрольные примеры

Все входы как (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)

Счетчик слогов

Для справки, вот количество слогов в каждом числе до 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
Геза Кереченьи
источник
Для вашего первого контрольного примера 4:37 будет также допустимым выводом, так как для этого потребуется 10 слогов?
Куинн
1
@ Quin, спецификация утверждает, что мы должны вывести самое раннее время.
лохматый
1
@ Shaggy упс, так что это делает спасибо - к тому времени, как я разберу свой ответ, я думаю, что моя пицца будет сожжена
Куинн
Можно ли предположить, что ввод может быть дополнен, то есть 4 минуты и 43 секунды могут быть введены как «04:43»?
Vedvart1
1
@ Vedvart1 Ладно, все в порядке
Геза Кереченьи

Ответы:

4

JavaScript (ES6),  112 106  105 байт

Более короткая версия, основанная на предложении @EmbodimentofIgnorance еще
6 байтов, сохраненных @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

Попробуйте онлайн!


JavaScript (ES6),  126  119 байт

(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

Попробуйте онлайн!

комментарии

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
источник
Не могли бы вы добавить объяснение?
Геза Кереченьи
@GezaKerecsenyi Готово. :-)
Арно
Спасибо. Это была в основном та 30774612>>2*n%(n>12?20:26)&3часть, в которой я был смущен.
Геза Кереценый
1
g=x=>x&&(x%10==7)+(x==11?6:x<13?4:x<21|x%10<1?5:6)может работать (не проверено, так как интернет не работает и использует мой телефон)
Embodiment of Ignorance
1
@DaniilTutubalin Круто. Я сохранил еще один байт, g()вернув противоположный результат и выполнив операцию XOR ~d.
Арно
2

Python 3 , 287 285 байт

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])

Попробуйте онлайн!

Это не очень умное решение - это в основном striaghtforward. Принимает m: s и m как отдельные входы (не нужно дополнять) и выходные данные (m, s). Выдает ошибку, если нет правильного вывода.

Программа в значительной степени опирается на неявное приведение логических значений к 0 и 1. Первая строка принимает ввод. Вторая строка определяет лямбда-функцию y, которая задает слоги в числе - она ​​принимает базу из 3 слогов, затем добавляет 1, если она заканчивается на 7, вычитает 1, если она заканчивается на 0, и вычитает 1, если она находится в 10 и 2, если это в одной цифре. Двенадцать и одиннадцать настраиваются вручную в конце. Третья строка - лямбда для слогов во всем выражении. Наконец, четвертая строка дает время после t секунд. Пятая строка - это выход - она ​​строит массив всех времен, которые решают проблему, и выводит первую.

РЕДАКТИРОВАТЬ 1: Благодаря Мэтью Андерсон в комментариях, 2 байта были сбриты, принимая входные данные отдельно.

Vedvart1
источник
1
Если вы берете ввод в две отдельные строки:, m=int(input()) s=int(input())вы можете сохранить 2 байта.
Мэтью Андерсон
1

Желе , 46 байт

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

Попробуйте онлайн!

Монадическая ссылка, принимающая в качестве аргумента время [minutes, seconds]и возвращающая подходящее время, чтобы сказать как [minutes, seconds]или [seconds]меньше минуты.

Ник Кеннеди
источник
0

CJam , 102 байта

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@

Попробуйте онлайн!

Просто скучная старая двоичная справочная таблица с магическими числами, здесь нечего смотреть.

JosiahRyanW
источник