또 무슨 요일이야?


10

내 웹 사이트에서 사용자는 생년월일 xx.xx.xx을 점으로 구분 된 두 자리 숫자 세 개 스타일로 입력합니다 . 불행히도, 사용자에게 정확히 어떤 형식을 사용해야하는지 잊어 버렸습니다. 내가 아는 것은 한 섹션은 한 달, 하나는 날짜, 한 섹션은 연도에 사용된다는 것입니다. 연도는 확실히 20 세기 (1900-1999)이므로 형식 31.05.75은을 의미 31 May 1975합니다. 또한 모든 사람들이 Gregorian 또는 Julian 달력을 사용한다고 가정합니다.

이제 난장판을 정리하기 위해 데이터베이스를 살펴보고 싶습니다. 가장 모호한 날짜, 즉 가능한 날짜 범위가 가장 큰 날짜를 가진 사용자를 다루면서 시작하고 싶습니다.

예를 들어, 날짜 08.27.53수단 27 August 1953중 하나 그레고리오 또는 율리우스 력한다. Julian 일정의 날짜는 13 일이 지났으므로 범위는 13 days.

대조적으로, 표기법 01.05.12은 가능한 많은 날짜를 나타낼 수 있습니다. 초기는 12 May 1901 (Gregorian)이고 최신은 1 May 1912 (Julian)입니다. 범위는 4020 days입니다.

규칙

  • 입력은 형식의 문자열 xx.xx.xx이며 각 필드는 두 자리 숫자이며 0으로 채워집니다.
  • 출력은 범위의 일 수입니다.
  • 입력이 항상 유효한 날짜라고 가정 할 수 있습니다.
  • 내장 날짜 또는 달력 기능을 사용할 수 없습니다.
  • 가장 짧은 코드 (바이트)가 이깁니다.

테스트 케이스

  • 01.00.31 => 12
  • 29.00.02=> 0(유일한 가능성은 29 February 1900 (Julian))
  • 04.30.00 => 13
  • 06.12.15 => 3291

가되어 5, May 1975있어야하는데 31st? 또한 윤년을 고려해야합니까?
Maltysen

@Maltysen 예, 수정되었습니다. 예.
Ypnypn

왜 21 세기에 없었을까요?
ElefantPhace

@ElefantPhace 규칙에 따르면 20 세기가 가정됩니다. 그렇지 않으면 최대 날짜가 없습니다.
Ypnypn

답변:


6

Pyth, 118 바이트

M++28@j15973358 4G&qG2!%H4FN.pmv>dqhd\0cz\.I&&&hN<hN13eN<eNhgFPNaYK+++*365JhtN/+3J4smghdJthNeNInK60aY-K+12>K60;-eSYhSY

온라인을 시도해보십시오 데모 또는 테스트 스위트를 .

줄리안 달력과 그레고리력에 대한 필요한 지식

Julian과 Gregorian Calendar는 매우 비슷합니다. 각 달력은 1 년을 12 개월로 나누며 각 기간은 28-31 일입니다. 한 달의 정확한 날짜는 [31, 28/29 (depends on leap year), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]입니다. 달력의 유일한 차이점은 윤년의 정의입니다. Julian Calendar에서 4로 나눌 수있는 해는 윤년입니다. 그레고리력은 좀 더 구체적입니다. 4로 나눌 수있는 모든 연도는 윤년으로, 100으로 나눌 수 있고 400으로 나눌 수없는 해를 제외하고는 윤년입니다.

따라서 20 세기에는 1 년만이 다릅니다. 1900 년은 Julian Calendar의 윤년이지만 Gregorian Calendar의 윤년은 아닙니다. 따라서 한 달력에는 존재하지만 다른 달력에는 존재하지 않는 유일한 날짜는 day 29.02.1900입니다.

윤년 정의가 다르기 때문에 Julian 캘린더의 날짜와 Gregorian 캘린더의 차이가 있습니다. 이전 날짜의 경우 12 일 차이, 이후 날짜의 29.02.1900경우 13 일 차이 29.02.1900.

단순화 된 의사 코드

Y = []  # empty list
for each permutation N of the input date:
   if N is valid in the Julian Calendar:
      K = number of days since 0.01.1900
      append K to Y
      if K != 60:  # 60 would be the 29.02.1900
         L = K - (12 if K < 60 else 13) 
         append L to Y
print the difference between the largest and smallest value in Y

자세한 코드 설명

첫 번째 부분 M++28@j15973358 4G&qG2!%H4은 함수를 정의합니다.이 함수 는 율리우스 력 으로 한 g(G,H)G의 일 수를 계산합니다 H.

M                            def g(G,H): return
      j15973358 4               convert 15973358 into base 4
     @           G              take the Gth element
  +28                           + 28
 +                &qG2!%H4      + (G == 2 and not H % 4)

그리고 다음 부분은 for 루프와 if입니다. N형식으로 해석 합니다 (month, year, day). 바이트를 절약하기 때문입니다.

FN.pmv>dqhd\0cz\.
             cz\.        split input by "."
    mv>dqhd\0            map each d of ^ to: eval(d[d[0]=="0":])
FN.p                     for N in permutations(^):

I&&&hN<hN13eN<eNhgFPN   
I                          if 
    hN                        month != 0
   &                          and
      <hN13                   month < 13
  &                           and
           eN                 day != 0
 &                            and
             <eNhgFPN         day < 1 + g(month,year):

aYK+++*365JhtN/+3J4smghdJthNeN
          JhtN                    J = year
     +*365J   /+3J4               J*365 + (3 + J)/4
    +              smghdJthN      + sum(g(1+d,year) for d in [0, 1, ... month-2])
   +                        eN    + day
  K                               K = ^
aYK                               append K to Y

InK60aY-K+12>K60            
InK60                             if K != 60:
     aY-K+12>K60                    append K - (12 + (K > 60)) to Y

;-eSYhSY
;          end for loop
 -eSYhSY   print end(sorted(Y)) - head(sorted(Y))

0

펄 5 , 294 바이트

sub f{map/(\d\d)(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])/             #1             
      &&$3<29+($2==2?!($1%4):2+($2/.88)%2)                        #2  
      &&($j{$_}=++$j+12)                                          #3
      &&$j!#1=60?$g{$_}=++$g:0,'000101'..'991231'if!%g;           #4
      pop=~/(\d\d).(\d\d).(\d\d)/;                                #5
      @n=sort{$a<=>$b}                                            #6
         grep$_,                                                  #7
         map{($j{$_},$g{$_})}                                     #8
         ("$1$2$3","$1$3$2","$2$1$3","$2$3$1","$3$1$2","$3$2$1"); #9
      $n[-1]-$n[0]}                                               #10

온라인으로 사용해보십시오!

공백, 줄 바꿈 및 주석이 제거 될 때 298 바이트

라인 1-4이 초기화 (하지 경우) %g%j값이 태양력과 이에 따라 12 월 31 일 1999 조경학과 1 일 1,900부터 계산 율리우스 일 번호입니다 해시.

5 행은 입력 날짜를 $ 1, $ 2 및 $ 3에 넣습니다.

9 행은 3 개의 입력 숫자에 대한 6 개의 순열을 모두 나열합니다.

8 행은 6을 그레고리력과 율리우스 일수의 두 숫자로 변환하지만 유효한 날짜 인 숫자 만 변환합니다.

7 행은 존재하지 않는 요일 번호를 필터링합니다.

6 행은 유효한 날짜 번호 목록을 가장 작은 것에서 가장 큰 것까지 정렬합니다.

10 행은 원하는 범위 인 마지막과 첫 번째 (최대 및 최소) 차이를 반환합니다.

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