还剩多久?


21

还剩多久?

最近,我在手机上使用5分钟计时器制作披萨。当有人走进来问我还剩多久时,我一开始就如何回答这个问题感到困惑。您会发现,如果当前时间的计时器是3:47,那么当我大声读出“三分四十七秒”时,时间就会变了。因此,我需要找到一个计时器,正好在我将其读出后才能到达。

这是您的挑战:自动化此过程。给定时间以任何合适的格式(用“:”定界,或者作为分秒和第二个参数),输出从当前时刻开始的最早时间,这将花费与读取计时器相同的时间量至。我们假设每个音节需要1秒钟才能读出。

进一步规定

  • 您必须将“分钟”和“秒”分别算作两个音节,以及它们之间的“与”。
  • 披萨的烹饪时间不会超过59:59。
  • “ 11分零秒”不是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
@Quinn,规范指出我们应该输出最早的时间。
毛茸茸的

1
@Shaggy哎呀,所以它表示感谢-到我整理我的答案时,我认为我的披萨会被烧掉
Quinn

我们是否可以假定可以填充输入,即可以将4分43秒输入为“ 04:43”?
Vedvart1

1
@ Vedvart1好,很好
Geza Kerecsenyi

Answers:


4

的JavaScript(ES6), 112个106  105字节

基于@EmbodimentofIgnorance的建议的较短版本,由@DaniilTutubalin
保存的另外6个字节

(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

你能补充一个解释吗?
Geza Kerecsenyi

@GezaKerecsenyi完成。:-)
Arnauld

谢谢。这主要是30774612>>2*n%(n>12?20:26)&3我感到困惑的部分。
Geza Kerecsenyi

1
g=x=>x&&(x%10==7)+(x==11?6:x<13?4:x<21|x%10<1?5:6)可能会工作(由于Internet
断开

1
@DaniilTutubalin酷。我从那里保存了另一个字节,方法是g()返回相反的结果并与进行XOR运算~d
Arnauld

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

在线尝试!

这不是一个非常聪明的解决方案-主要是超前的。将'm: s'm 和s分别作为输入 (不需要填充)和输出(m,s)。如果没有有效的输出,则会引发错误。

该程序严重依赖于将布尔值隐式转换为0和1。第一行接受输入。第二行定义了一个lambda函数y,该函数以一个数字给出音节-它假定以3个音节为基数,如果以7结尾则加1,如果以7结尾则减1,如果以0结尾则减1,如果以10结尾则减1,并且如果是一位数字,则为2。最后手动调整十二和十一。第三行是整个表达式中音节的lambda。最后,第四行给出t秒后的时间。第五行是输出-它构建一个满足问题的所有时间的数组,并输出第一行。

编辑1:感谢Matthew Anderson的注释,通过分别处理输入减少了2个字节。


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]如果不到一分钟。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.