Paskalya tarihini hesapla


13

İşleviniz veya programınız bir yıl olarak giriş yapmalı ve o yıl Paskalya'nın (Doğu Ortodoks Paskalya'sı değil) tarihini (Gregoryen takviminde) iade etmeli (veya yazdırmalıdır). Döndürülen tarih, ISO 8601'e göre biçimlendirilmelidir, ancak 9999'dan daha büyük yıllar ( 312013-04-05 veya 20010130 gibi ) desteklenmelidir ve yalnızca 1583'ten ( veya yıl) eşit veya daha büyük yıllarla çalışması gerekir . Gregoryen takviminin kabul edilmesi) ve 5701583'e eşit veya daha az yıllar (Paskalya tarihleri ​​dizisi kendini tekrar etmeye başladığı zaman).

Örnekler:

e(5701583) = 5701583-04-10
e(2013)    = 2013-03-31
e(1583)    = 1583-04-10
e(3029)    = 30290322
e(1789)    = 17890412
e(1725)    = 17250401

Paskalya tarihini iade etmek için yerleşik işlevlerin kullanımı sıkıcıdır ve bu nedenle izin verilmez. En kısa cevap (karakterlerle) kazanır.

Kaynaklar:


Bazı dillerin bunu yapmak için yerleşik bir işlevi olduğunu biliyor musunuz?
Peter Taylor

Gibi? Farkında olduğum tek şey PHP, ancak easter_date ve easter_days işlevleri oldukça sınırlı, easter_date sadece 1970'den sonraki yıllar için çalışıyor ve easter_days 1753'ten önceki yıllar için doğru gün sayısını döndürmüyor. Ama soruyu düzenleyeceğim bu tür işlevlerin kullanılmasına izin vermemek.
Fors


1
Yani bu Gregoryen ve Julian değil mi? Ayrıca Katolik değilim, "Katolik Geleneği" nedir?
jdstankosky

Yanıtlar:


3

GolfScript (85 karakter)

~:^100/.)3*4/.@8*13+25/-^19%.19*15+@+30%.@11/+29/23--.@-^.4/++7%97--^0@.31/100*\31%)+

Örnek kullanım:

$ golfscript.rb codegolf11132.gs <<<2013
20130331

Bunun, mevcut yanıtların çoğunda farklı bir algoritma kullandığını unutmayın. Spesifik olmak gerekirse, Sean Cheshire tarafından bağlanan kaynakta Lichtenberg'e atfedilen algoritmayı soru üzerine bir yorumda uyarladım .

Makul türleri (JavaScript'in numaraları değil) varsayarak ve * 31 + gün (0 gün gününü kullanarak) vermek için bir adaptasyonla orijinal algoritma

K = Y/100
M = 15 + (3*K+3)/4 - (8*K+13)/25
S = 2 - (3*K+3)/4
A = Y%19
D = (19*A+M) % 30
R = (D + A/11)/29
OG = 21 + D - R
SZ = 7 - (Y + Y/4 + S) % 7
OE = 7 - (OG-SZ) % 7
return OG + OE + 92

Ortak bir alt ifade çıkardım ve azaltmak için başka optimizasyonlar yaptım

K = y/100
k = (3*K+3)/4
A = y%19
D = (19*A+15+k-(8*K+13)/25)%30
G = 23+D-(D+A/11)/29
return 97+G-(G+y+y/4-k)%7

Bu yaklaşım, diğerinden (Al Petrofsky'nin 20-op algoritması) biraz daha aritmetik işlemlere sahiptir, ancak daha küçük sabitleri vardır; Yığın tabanlı olduğu için GolfScript'in ek parantezler hakkında endişelenmesine gerek yoktur ve optimize edilmiş mizanpajımdaki her bir ara değer tam olarak iki kez kullanıldığından, GolfScript'in yığında en üstteki üç öğeye kolay erişim sınırlamasına iyi uyum sağlar.


Küçük bir sorunu var, Paskalya tarihi 1 Nisan ve 10 Nisan arasında olduğunda, 1725041 gibi tarihleri ​​verir, 17250401'e dönmesi gerekir. Ancak farklı yaklaşım için iptal edildi!
Fors

@Fors, ayy. Şimdi düzeltildi.
Peter Taylor

5

Python 2 - 125 , 120 119 karakter

Bu Fors'ın utanmadan Python'a verdiği cevap .

y=input()
a=y/100*1483-y/400*2225+2613
b=(y%19*3510+a/25*319)/330%29
b=148-b-(y*5/4+a-b)%7
print(y*100+b/31)*100+b%31+1

Düzenle : print"%d-0%d-%02d"%(y,b/31,b%31+1)5 satır kaydedilecek son satır değiştirildi . Temsil ettiğim isterdim 10000olarak 1e4, ama bu bir çağrı gerektirecek kayan nokta üretecektir int.

Edit2 : Peter Taylor'a ondan nasıl kurtulacağını 10000ve 1 karakteri nasıl kurtardığını gösterdiği için teşekkürler .


1
Eğer bölünmüş Eğer 10000kadar 100*100senin kadar Horner forma son satırı koyabilirsiniz (y*100+b/31)*100+b%31+1. Önde gelen parantez, sonraki boşluğu kaldırmanıza izin verir printve 100genel olarak 1 karakterlik bir tasarruf için değişkenin üç örneğini çıkarabilirsiniz .
Peter Taylor

@PeterTaylor: Mükemmel öneri. Cevabım güncellendi.
Steven Rumbalski

Bir işlev yapabilir e(y)ve birkaç bayt kaydedebilirsiniz
sagiksp

4

PHP 154

YYYY-AA-GG yerine YYYYAAGG'ye geçersem 150 karakter.

<?$y=$argv[1];$a=$y/100|0;$b=$a>>2;$c=($y%19*351-~($b+$a*29.32+13.54)*31.9)/33%29|0;$d=56-$c-~($a-$b+$c-24-$y/.8)%7;echo$d>31?"$y-04-".($d-31):"$y-03-$d";

Satır Sonları ile:

<?
$y = $argv[1];
$a = $y / 100 |0;
$b = $a >> 2;
$c = ($y % 19 * 351 - ~($b + $a * 29.32 + 13.54) * 31.9) / 33 % 29 |0;
$d = 56 - $c - ~($a - $b + $c - 24 - $y / .8) % 7;
echo $d > 31 ? "$y-04-".($d - 31) : "$y-03-$d";

Kullanım hızı php easter.php 1997
:1997-03-30

Kullanım hızı php easter.php 2001
:2001-04-15


1
Büyük algoritma golf, büyük kod golf değil. 18 bayt doğrama özgürlüğünü aldım:<?=$y=$argv[1],"-0",3+$m=($d=56-($c=($y%19*351-~(($a=$y/100|0)*29.32+($b=$a>>2)+13.54)*31.9)/33%29)-~($a-$b+$c-24-$y/.8)%7)>>5,31*$m-$d;
Titus

Çıktı biçimini karşılayamıyor. Günün önde gelen sıfırı, gerektiğinde eksik. Örneğin 1725 yılı 1725-04-1yerine çıktı alır 1725-04-01.
Christoph

4

dc: 106 karakter

?[0n]smdndsy100/1483*ly400/2225*-2613+dsa25/319*ly19%3510*+330/29%sb148lb-5ly*4/la+lb-7%-d31/0nn31%1+d9>mp

Kullanımı:

> dc -e "?[0n]smdndsy100/1483*ly400/2225*-2613+dsa25/319*ly19%3510*+330/29%sb148lb-5ly*4/la+lb-7%-d31/0nn31%1+d9>mp"
1725
17250401
>

Bu, tüm yükler ve depolar yerine 'd' ve 'r' kullanılarak kısaltılabilmelidir.


3

C: 151148 karakter

y;a;b;main(){scanf("%d",&y);a=y/100*1483-y/400*2225+2613;b=(y%19*3510+a/25*319)/330%29;b=148-b-(y*5/4+a-b)%7;printf("%d-0%d-%02d\n",y,b/31,b%31+1);}

Ve aynı kod, ancak daha iyi biçimlendirilmiş:

#include <stdio.h>

int y, a, b;

int main() {
    scanf("%d", &y);

    a = y/100*1483 - y/400*2225 + 2613;
    b = (y%19*3510 + a/25*319)/330%29;
    b = 148 - b - (y*5/4 + a - b)%7;

    printf("%d-0%d-%02d\n", y, b/31, b%31 + 1);
}

Paskalya tarihini hesaplamak için korkutucu birçok algoritma vardır, ancak bunlardan sadece birkaçı kod golfü için çok uygundur.


3

JavaScript 162 156 145

function e(y){alert(y+"0"+((d=56-(c=(y%19*351-~((b=(a=y/100|0)>>2)+a*29.32+13.54)*31.9)/33%29|0)-~(a-b+c-24-y/.8)%7)>(f=31)?4:3)+(d-f>0&d-f<10?0:"")+(d>f?d-f:d))}

@ Jdstankosky'nin PHP çözümünden esinlenmiştir ... YYYYMMDD sonucu sağlar ...

Şimdi daraltıldı:

alert((y=prompt())+0+((d=56-(c=(y%19*351-~((b=(a=y/100|0)>>2)+a*29.32+13.54)*31.9)/33%29|0)-~(a-b+c-24-y/.8)%7)>(f=31)?4:3)+(d-f>0&d-f<10?0:"")+(d>f?d-f:d))

Şimdi girdi istiyor ... "0" değişmez dizgesini 0'a indirdi ve gevşek yazmanın benim avantajımla çalışmasına izin ver! :)

ES6'yı dikkate almak için daha da azaltıldı ...

e=y=>y+"0"+((d=56-(c=(y%19*351-31.9*~((b=(a=y/100|0)>>2)+29.32*a+13.54))/33%29|0)-~(a-b+c-24-y/.8)%7)>(f=31)?4:3)+(d-f>0&d-f<10?0:"")+(d>f?d-f:d)


2

APL 132

Bu algoritma, Paskalya'nın Mart ayının başlangıcına göre gün sayısını hesaplar. Tarih, soruda izin verilen şekilde YYYYAAGG biçiminde döndürülür:

E y                                                   
(a b)←⌊((3 8×⌊y÷100)+¯5 13)÷4 25                           
c←7|y+(⌊y÷4)-a-e←⌊d-((19×d←30|(227-(11×c)-a-b))+c←19|y)÷543
+/(10*4 2 0)×y,(3+i>31),(61⍴⍳31)[i←e+28-c] 

Orijinal test senaryolarının alınması:

      E 2013
20130331
      E 1583
15830410
      E 3029
30290322
      E 1789
17890412         

0

Fortran (GFortran) , 179 bayt

READ*,I
J=I/100*2967-I/400*8875+7961
K=MOD(MOD(I,19)*6060+(MOD(MOD(J/25,59),30)+23)*319-1,9570)/330
L=K+28-MOD(I*5/4+J+K,7)
WRITE(*,'(I7,I0.2,I0.2)')I,(L-1)/31+3,MOD(L-1,31)+1
END

Çevrimiçi deneyin!

İkinci kaynak bağlantısından "Emended Gregorian Easter" algoritmasını (Al Petrofsky) kullanır. Garip bir şekilde, 5701583 yılı (ve görünüşe göre, sadece bu yıl için) başarısız olur ve Paskalya'yı bir hafta önce tahmin eder. Tarihi YYYYYYYMMDDyedi basamaktan azsa, önde gelen boşluklarla tarihi formatta yazdı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.