Yine hangi tarih?


10

Web sitemde, kullanıcılar doğum tarihlerini stile girerler xx.xx.xx- noktalarla ayrılmış iki basamaklı üç sayı. Ne yazık ki, kullanıcılara tam olarak hangi formatın kullanılacağını söylemeyi unuttum. Tek bildiğim, bir bölümün ay için, bir bölümün tarih için ve bir bölümün de yıl için kullanılmasıdır. Yıl kesinlikle 20. yüzyılda (1900-1999), bu yüzden biçim 31.05.75anlamına gelir 31 May 1975. Ayrıca, herkesin Gregoryen veya Julian takvimini kullandığını varsayıyorum.

Şimdi, karışıklığı gidermek için veritabanımdan geçmek istiyorum. En belirsiz tarihleri, yani olası tarih aralığının en büyük olduğu kullanıcılarla ilgilenerek başlamak istiyorum.

Örneğin, tarih Gregoryen veya Julian takviminde 08.27.53anlamına gelir 27 August 1953. Julian takvimindeki tarih 13 gün sonra, bu nedenle aralık sadece 13 days.

Buna karşılık, gösterim 01.05.12birçok olası tarihe işaret edebilir. En erken 12 May 1901 (Gregorian)ve en sonuncusu 1 May 1912 (Julian). Aralık 4020 days.

kurallar

  • Girdi, xx.xx.xxher alanın iki basamaklı ve sıfır dolgulu olduğu biçimdeki bir dizedir .
  • Çıktı, aralıktaki gün sayısıdır.
  • Girişin her zaman geçerli bir tarih olacağını varsayabilirsiniz.
  • Yerleşik tarih veya takvim işlevlerini kullanamazsınız.
  • En kısa kod (bayt cinsinden) kazanır.

testcases

  • 01.00.31 => 12
  • 29.00.02=> 0(Tek olasılık 29 February 1900 (Julian))
  • 04.30.00 => 13
  • 06.12.15 => 3291

Olması 5, May 1975gerekiyor 31stmu? Ayrıca artık yılları hesaba katmamız gerekiyor mu?
Maltysen

@Maltysen Evet, düzeltildi. Evet.
Ypnypn

Neden 21. yüzyılda olamazdı?
ElefantPhace

@ElefantPhace Kurallar, 20. yüzyılın varsayıldığını belirtir; aksi takdirde maksimum tarih olmaz.
Ypnypn

Yanıtlar:


6

Pyth, 118 bayt

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

Çevrimiçi deneyin: Gösteri veya Test Suite .

Julian ve Gregoryen Takvimler hakkında gerekli bilgi

Julian ve Gregoryen Takvimi oldukça benzer. Her takvim bir yılı, her biri 28-31 gün içeren 12 aya böler. Bir aydaki kesin günler [31, 28/29 (depends on leap year), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]. Takvimler arasındaki tek fark, artık yıl tanımlarıdır. Julian Calendar'da her yıl 4'e bölünebilir bir sıçrama yılıdır. Gregoryen Takvimi biraz daha belirgindir. 4 ile bölünebilen herhangi bir yıl, 100 ile bölünebilen ve 400 ile bölünemeyen yıl hariç bir artık yıldır.

Yani 20. yüzyılda sadece bir yıl farklıdır. 1900 yılı, Julian Takvimi'nde bir sıçrama yılı, ancak Gregoryen Takvimi'nde bir sıçrama yılı değil. Yani bir takvimde var olan ancak diğer takvimde olmayan tek tarih gündür 29.02.1900.

Farklı artık yıl tanımı nedeniyle, Julian Takvimi ile Gregoryen Takvimi arasındaki bir tarih arasında bir fark vardır. Tarihinden önceki bir tarih için 12 günlük fark 29.02.1900ve sonrasındaki tarihler için 13 günlük fark 29.02.1900.

Basitleştirilmiş Sahte Kod

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

Detaylı Kod Açıklaması

İlk bölüm , Julian Takvimi'nde bir yılın ayındaki gün sayısını hesaplayan M++28@j15973358 4G&qG2!%H4bir işlevi tanımlar .g(G,H)GH

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)

Ve bir sonraki kısım sadece for döngüsü ve ifs. Ben yorumlamak o Bildirimi Nformatında (month, year, day). Sadece bayt kurtardığı için.

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

Perl 5 , 294 bayt

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

Çevrimiçi deneyin!

Boşluklar, satırlar ve yorumlar kaldırıldığında 298 bayt.

1-4 satırları , değerlerin Gregoryen ve Julian gün sayıları olduğu %gve yapılmadığı %jdurumlarda, 1 Ocak 1900 ile 31 Aralık 1999 tarihleri ​​arasında sayım yapar.

5. satır, giriş tarihini 1 TL, 2 TL ve 3 TL olarak koyar.

Satır 9, bu üç giriş numarasının altı permütasyonunun tümünü listeler.

Satır 8, bu altıyı her biri Gregoryen ve Jülyen günü sayıları olmak üzere iki sayıya dönüştürür, ancak yalnızca geçerli tarihler.

Satır 7 bunu sağlar, mevcut olmayan gün sayılarını filtreler.

6. Satır geçerli tarih numaralarının listesini en küçükten en büyüğe doğru sıralar.

10. satır daha sonra istenen aralık olan son ve ilk (max ve min) arasındaki farkı döndürür.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.