우리는 아직?


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

    이들은 처리해야하는 유일한 형식입니다. 각 부분은 정확하게 표시되는 자릿수를 갖습니다. 이는 소수 초에 후행 0이있을 수 있음을 의미합니다 (예 : .120never .12). 는 T시간에서 날짜를 구분 리터럴 문자 "T"입니다. 시간은 24 시간제입니다.

  • 월과 일은 1을 기준으로합니다 (자세한 내용은 아래 참조).

  • 유효하지 않은 범위를 벗어난 입력은 처리 할 필요가 없습니다.

  • 프로그래머의 재량에 따라 입력에 단일 줄 바꿈 개행이있을 수 있습니다.

진행률 표시 줄 수학

이 프로그램은 주어진 입력에서 최소 및 두 번째 중요 단위와 관련이 있습니다. 예를 들어 입력에 일 수준의 정밀도가있는 경우 (예 :2016-12-14 :)가있는 경우 진행률 표시 줄에 입력 월의 일 비율과 남은 일 비율이 표시됩니다.

진행률 표시 줄에는 20 단위 (문자)가 있으며 표시되는 비율은 120 의 가장 가까운 단위로 반올림됩니다 . 예를 들어, 2016-12-14T12:28진행률 표시 줄에 Round ( 2860 × 20) = 20 개 중 9 개가 "filled"로 표시됩니다.

1 기반 월 및 일

년 12 월 1 일 (예를 들어)하지만 012016-12-01계산의 목적을 위해, 절단 단위 오늘의 0 번째 시간의 0 번째 분의 0 번째 밀리 초를 의미 있기 때문에, 달의 0 번째 날입니다. 즉, 2016-12-010 / 31 에서 December까지 방해하고 2016-12-02있다 1 / 31 , 등등.

마찬가지로, 2016-01이렇게 계산에서는 월의 제 0 일의 제 0 밀리 초 0 / 12 하는 수단 2016-1211 / 12 .

그렇습니다. 달과 일이 진행률 표시 줄을 완전히 채우지 않을 것입니다.

다른 달 기간과 윤년

달마다 다른 일수가 있으며 윤년을 포함하여 출력에이를 반영해야합니다. 2017 년 2 월 6 일 진행률 표시 줄은 2016 년 2 월 6 일 (또는 두 해의 1 월 6 일) 진행률 표시 줄과 다릅니다.

여러 가지 잡다한

  • 시간 여행자는 그레고리력 달력을 사용합니다 . TL; DR : 1752 년 누락 된 날 과 같은 특별한 경우는 없습니다 . AD 0 년의 날짜를 입력합니다
  • 시간 여행자는 일광 절약 시간을 무시합니다.
  • 이 프로그램은 윤초를 설명 할 필요는 없지만 가능할 수 있습니다.

산출

프로그램 (또는 함수)은 시간이 경과하면 "채우고"남은 시간은 "열림"으로 표시되는 가로 방향의 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
윤초에 대해 걱정해야합니까?
Riley

@Riley 좋은 질문입니다. 호
요르단

2
표준화 된 양식이 없기 때문에 일광 절약이 무시된다고 가정합니다.
CAD97

3
@ CAD97 좋은 질문입니다. 당신이 올바른지. DST는 실제로 시간 여행자들을 복잡하게 만들므로 무시합니다.
Jordan

"1899-12-31T23"예제는 제공된 입력 형식 목록에 따라 유효하지 않으며 "1982-05-15T17"과 동일합니다. 테스트 데이터를 확인하십시오.
zeppelin

답변:


4

자바 스크립트, 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 답변을 기반으로합니다. 주석이 달린 ungolfed 버전은 다음과 같습니다.

"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 > output하고 diff output testoutput 또는 온라인으로보십시오 .


2

파이썬 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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.