我们到了吗?


22

我是一个时光旅行者,我迷恋时间的流逝。我特别喜欢钟针经过12时,翻动日历的下一页或所有人大喊“新年快乐”的那一刻。

请为我编写一个程序,以进度条的形式显示我从最后一刻到下一刻的距离。例如,如果我告诉它时间是09:12,它应该打印以下内容:

09:00 ####---------------- 10:00

如果我告诉它月份是1982年5月,则应打印以下内容:

1982-01 #######------------- 1983-01

我是否提到我是时光旅行者?我从0 AD的第一个毫秒到9999 AD的最后一个毫秒旅行到任何地方,因此程序需要处理该范围内的任何日期和时间。

输入项

  • 输入将采用以下格式之一:

    • YYYY-MM-DDThh:mm:ss.sss
    • YYYY-MM-DDThh:mm:ss
    • YYYY-MM-DDThh:mm
    • YYYY-MM-DDThh
    • YYYY-MM-DD
    • YYYY-MM

    这些是唯一需要处理的格式。每个部分将完全具有显示的数字位数,这意味着小数秒可能带有尾随零(例如.120,never .12)。该T是文字字母“T”划定从时间日期。小时是24小时制。

  • 月和日以1为基础(请参见下文)。

  • 无效和超出范围的输入无需处理。

  • 根据程序员的判断,输入可能只有一个尾随换行符。

进度条数学

程序与给定输入中的最低和第二最低有效单位有关。例如,如果输入具有日级精度(例如2016-12-14),则进度条将指示输入月份中已过的天数比例与剩余的天数比例。

进度条将具有20个单位(字符),并表示将被舍入到最近的增量比例1 / 20。例如,给定2016-12-14T12:28,所述进度条显示轮(28 / 60 ×20)= 9 20的单位“填充”。

从1开始的月份和日期

尽管(例如)12月1日01位于2016-12-01,但出于计算目的,它是该月的第0天,因为截断的单位表示该天的第0小时的第0分钟的第0毫秒。换句话说,2016-12-010 / 31的方式,通过腊和2016-12-021 / 31,等等。

同样地,2016-01是一月的第0天的第0毫秒,所以在计算中它是0 / 12,该装置2016-1211 / 12

是的,这意味着几个月和几天永远不会完全填满进度栏。

不同的月份持续时间和leap年

不同的月份有不同的天数,并且输出必须反映出这一点,包括leap年。2017年2月6日的进度条将与2016年2月6日(或两年的1月6日)的进度条不同。

  • 时光旅行者使用阳历阳历。TL; DR:没有特殊的情况,例如1752年失踪的日子。输入内容将包含公元0年的日期
  • 时间旅行者忽略了夏令时。
  • 该程序不需要考虑leap秒,但可以。

输出量

程序(或函数)必须打印(或以字符串形式返回)水平方向的20个字符的进度条,该进度条“填充”已过去的时间,“打开”以显示剩余的时间。它必须从左到右“填写”。

进度条的左侧必须有一个标签,显示正在计算的时间段的开始,右侧的标签必须显示与输入相同的格式(但仅显示两个精度单位)。对于我们的示例,2016-12-14有效输出为:

12-01 #########----------- 01-01

以下是每个可能期间的有效标签格式:

  • 月份: YYYY-MM
  • 天: MM-DD
  • 小时: DDThh
  • 分钟: hh:mm
  • 秒: mm:ss
  • 毫秒: ss.sss

标签中不能包含其他单位,并且任何内容都可以省略。

输出说明

  • 进度条的“填充”单位将由一个#字符表示。“开放”单位将以表示-
  • 进度栏和每个标签之间必须恰好有一个空格。
  • 允许前导或尾随空格和/或单个尾随换行符。

获奖

这是。以字节为单位的最短代码获胜。适用标准规则。禁止使用标准漏洞。

例子

Input                      Output
-----------------------    -------------------------------------
2016-12-12T12:17           12:00 ######-------------- 13:00
2016-12-12                 12-01 #######------------- 01-01
0000-01-01T00:00:00.000    00.000 -------------------- 01.000
0000-01-01T00:00           00:00 -------------------- 01:00
1899-12-31T23              31T00 ###################- 01T00
1899-12-31                 12-01 ###################- 01-01
1899-12                    1899-01 ##################-- 1900-01
1982-05-15T17:15           17:00 #####--------------- 18:00
1982-05-15T17              15T00 ##############------ 16T00
1982-05                    1982-01 #######------------- 1983-01
9999-12-31T23:59:59.999    59.000 #################### 00.000
9999-12                    9999-01 ##################-- 10000-01
2000-01-06                 01-01 ###----------------- 02-01
2000-02-06                 02-01 ###----------------- 03-01
2001-02-06                 02-01 ####---------------- 03-01
1742-09-10                 09-01 ######-------------- 10-01

4
我们是否需要担心leap秒?
莱利2016年

@Riley好问题。号
乔丹

2
我假设夏令时被忽略了,因为没有一种标准化的形式?
CAD97

3
@ CAD97好问题。你是对的。DST确实使时间旅行者的事情复杂化,因此我们将其忽略。
约旦

根据提供的输入格式列表,“ 1899-12-31T23”示例无效,与“ 1982-05-15T17”相同。请验证您的测试数据。
齐柏林飞艇

Answers:


4

JavaScript,282字节

(x,v=x.split(/\D/g),l=v.length-2,[a,b,c,d]=("10e5,01,-,12,01,-,"+new Date(v[0],v[1],0).getDate()+",00,T,24,00,:,60,00,:,60,000,.,1000").split`,`.slice(l*3,l*3+4),t=(v[l+1]-b)/d*20+.5|0,n=v[l],o=((n|0)+1)%a,r=l?('0'+o).slice(-2):o)=>n+c+b+' '+'#'.repeat(t)+'-'.repeat(20-t)+' '+r+c+b

通过所有测试

(
x,
v=x.split(/\D/g),
l=v.length-2,
[a,b,c,d]=("10e5,01,-,12,01,-,"+new Date(v[0],v[1],0).getDate()+",00,T,24,00,:,60,00,:,60,000,.,1000").split`,`.slice(l*3,l*3+4),
t=(v[l+1]-b)/d*20+.5|0,
n=v[l],
o=((n|0)+1)%a,
r=l?('0'+o).slice(-2):o
) =>n+c+b+' '+'#'.repeat(t)+'-'.repeat(20-t)+' '+r+c+b

测试功能不打印任何内容以表示合格,否则显示值。

function test(value,expected){
    if (f(value)!=expected)
    {
        console.log(value);
        console.log(f(value));
        console.log(expected);
     }
}

测试用例:

test('2016-12-12T12:17','12:00 ######-------------- 13:00')                 ;
test('2016-12-12','12-01 #######------------- 01-01')                       ;
test('0000-01-01T00:00:00.000','00.000 -------------------- 01.000')        ;
test('0000-01-01T00:00','00:00 -------------------- 01:00')                 ;
test('1899-12-31T23','31T00 ###################- 01T00')                    ;
test('1899-12-31','12-01 ###################- 01-01')                       ;
test('1899-12','1899-01 ##################-- 1900-01')                      ;
test('1982-05-15T17:15','17:00 #####--------------- 18:00')                 ;
test('1982-05-15T17','15T00 ##############------ 16T00')                    ;
test('1982-05','1982-01 #######------------- 1983-01')                      ;
test('9999-12-31T23:59:59.999','59.000 #################### 00.000')        ;
test('9999-12','9999-01 ##################-- 10000-01')                     ;
test('2000-01-06','01-01 ###----------------- 02-01')                       ;
test('2000-02-06','02-01 ###----------------- 03-01')                       ;
test('2001-02-06','02-01 ####---------------- 03-01')                       ;
test('1742-09-10','09-01 ######-------------- 10-01')                       ;

2
我必须学习一种新的语言才能达到此版本的最高水平……非常简洁!
rexroni

3

Pyth,213个字节

我在pyth中的第一个代码!看哪:

+%h=N:[d"%.4d"\-=Z"%.2d"\-Z\TZ\:Z\:Z\."%.3d")-*2lKr:w"[-T:.]"d7 3*2lKJ@K_2+@N1+%eN=b<lK4+d+*\#=Gs+*20c-eKb@=H[0^9T12?q2=k@K1+28+q0%=YhK4-q0%Y400q0%Y100+30%+k/k8 2 24 60 60 999)lK.5+*\--20G+d+%hN%+J1@H-lK1+@N1%eNb

我的pyth代码与我之前的python答案紧密相关。这是带有注释的非公开版本:

"K is the input, as a list of numbers"
Kr:w"[-T:.]"d7
"Y=year"
=YhK
"k=month"
=k@K1
"H = a list of denominators"
=H[0 ^9T 12 ?q2k+28+q0%Y4-q0%Y400q0%Y100 +30%+k/k8 2 24 60 60 999)
"J is the second-to-last number of the input"
J@K_2
"b is the +1 starting point for months and days"
=b<lK4
"G is the number of hashtags in the statusbar"
=Gs+*20c-eKb@HlK.5
"N is the formatted string"
=N:[d"%.4d"\-=Z"%.2d"\-Z\TZ\:Z\:Z\."%.3d")-*2lK3 *2lK
+%hNJ+@N1+%eNb+d+*\#G+*\--20G+d+%hN%+J1@H-lK1+@N1%eNb

通过循环代码并在末尾添加换行符,可以轻松地测试多个值:

Wp+%h=N:[d"%.4d"\-=Z"%.2d"\-Z\TZ\:Z\:Z\."%.3d")-*2lKr:w"[-T:.]"d7 3*2lKJ@K_2+@N1+%eN=b<lK4+d+*\#=Gs+*20c-eKb@=H[0^9T12?q2=k@K1+28+q0%=YhK4-q0%Y400q0%Y100+30%+k/k8 2 24 60 60 999)lK.5+*\--20G+d+%hN%+J1@H-lK1+@N1+%eNb"\n"

然后我跑了cat testinput | pyth code.pyth > outputdiff output testoutput 或者网上试了一下


2

Python 2,371字节

这项挑战异常困难!在我计算出输出字符串格式之前,似乎要不到300。

最酷的部分是我的答案不使用任何日期包:

import re
s=raw_input()
S=[int(i)for i in re.sub('[-T:.]',' ',s).split()]
l=len(S)
y,m=S[:2]
d=[0,20<<9,12,28+(y%4==0!=y%100)+(y%400==0)if m==2else 30+(m+m/8)%2,24,60,60,999]
a,n=S[-2:]
b=1-(1if l>3else 0)
h=int(20.*(n-b)/d[l]+.5)
x,y,z='- %.4d - %.2d - %.2d T %.2d : %.2d : %.2d . %.3d'.split()[l*2-3:l*2]
print x%a+y+z%b+' '+'#'*h+'-'*(20-h)+' '+x%((a+1)%d[l-1])+y+z%b
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.