25

チャレンジ

ギリシア正教の復活祭 ( http://www.timeanddate.com/holidays/us/orthodox-easter-day ) の日付を、指定された年 (1900 ~ 2100 年) の日曜日を最小量の文字を使用して計算します。

入力は「2010」という形式の年です。どこで取得するか (Input、CommandLineArgs など) は関係ありませんが、動的でなければなりません!

出力は、日-月-年の形式にする必要があります (たとえばdd/mm/yyyy、 またはd/m/yyyy)

制限事項MathematicaEasterSundayGreekOrthodoxや PHP のなどeaster_date()、(該当するグレゴリオ暦ではない) 日付を自動で返す標準関数は使用しないでください。

2005 returns 1/5/2005
2006 returns 23/4/2006
2007 returns 8/4/2007
2008 returns 27/4/2008
2009 returns 19/4/2009
2010 returns 4/4/2010
2011 returns 24/4/2011
2012 returns 15/4/2012
2013 returns 5/5/2013
2014 returns 20/4/2014
2015 returns 12/4/2015

コード カウントには、入力/出力 (つまり、完全なプログラム) が含まれます。

編集:のイースターの日付 を意味します。

参照: http://en.wikipedia.org/wiki/Computus

4

14 に答える 14

9

Python ( 101 140 132 115 文字)

y=input()
d=(y%19*19+15)%30
e=(y%4*2+y%7*4-d+34)%7+d+127
m=e/31
a=e%31+1+(m>4)
if a>30:a,m=1,5
print a,'/',m,'/',y

これはMeeus Julian アルゴリズムを使用していますが、これは 1900 年から 2099 年の間しか機能しないため、Anonymous Gregorian アルゴリズムを使用した実装が間もなく登場します。

編集: 2005 年が適切に処理されるようになりました。それを指摘してくれたマークに感謝します。

編集 2: 数年間の処理の改善、すべての入力に感謝します!

編集 3: 範囲内のすべての年で機能するはずです。(フアン、乗っ取ってごめんなさい。)

于 2010-08-28T14:25:20.223 に答える
4

PHP CLI、いいえeaster_date()、125 文字

1900 年 3 月 13 日から 2100 年 3 月 13 日まで有効。

コード:

<?=date("d/m/Y",mktime(0,0,0,floor(($b=($a=(19*(($y=$argv[1])%19)+15)%30)+(2*($y%4)+4*$y%7-$a+34)%7+114)/31),($b%31)+14,$y));

呼び出し:

$ php codegolf.php 2010
$ php codegolf.php 2005

出力:

04/04/2010
01/05/2005

空白あり:

<?=date("d/m/Y", mktime(0, 0, 0, floor(($b = ($a = (19 * (($y = $argv[1]) % 19) + 15) % 30) + (2 * ($y % 4) + 4 * $y % 7 - $a + 34) % 7 + 114) / 31), ($b % 31) + 14, $y));

この反復は、PHP の代入処理のおかげで、もはや読むことができません。ほとんど関数型言語です!


完全を期すために、短いタグに依存しない以前の 127 文字のソリューションを次に示します。

コード:

echo date("d/m/Y",mktime(0,0,0,floor(($b=($a=(19*(($y=$argv[1])%19)+15)%30)+(2*($y%4)+4*$y%7-$a+34)%7+114)/31),($b%31)+14,$y));

呼び出し:

$ php -r 'echo date("d/m/Y",mktime(0,0,0,floor(($b=($a=(19*(($y=$argv[1])%19)+15)%30)+(2*($y%4)+4*$y%7-$a+34)%7+114)/31),($b%31)+14,$y));' 2010
$ php -r 'echo date("d/m/Y",mktime(0,0,0,floor(($b=($a=(19*(($y=$argv[1])%19)+15)%30)+(2*($y%4)+4*$y%7-$a+34)%7+114)/31),($b%31)+14,$y));' 2005
于 2010-08-28T06:12:09.370 に答える
4

マテマティカ

<<Calendar`;a=Print[#3,"/",#2,"/",#]&@@EasterSundayGreekOrthodox@#&

で呼び出す

a[2010]

出力

4/4/2010

私も:組み込み関数を使用しないことに意味がありません。

于 2010-08-28T04:19:18.907 に答える
4

C#、155 157 182 209 212文字

class P{static void Main(string[]i){int y=int.Parse(i[0]),c=(y%19*19+15)%30,d=c+(y%4*2+y%7*4-c+34)%7+128;System.Console.Write(d%31+d/155+"/"+d/31+"/"+y);}}

Python 2.3、97 文字

y=int(input())
c=(y%19*19+15)%30
d=c+(y%4*2+y%7*4-c+34)%7+128
print"%d/%d/%d"%(d%31+d/155,d/31,y)

これは Meeus Julian アルゴリズムも使用します (5 月の日付でも機能するはずです)。

  • 現代の不要なチェックと出力のゼロパディングを削除しました
  • 1800年から2100年の間にイースターがないので、3月にイースターを期待しないでください
  • 同梱の Python 2.3 バージョン (これまでで最短)
于 2010-08-28T07:02:02.730 に答える
3

Java - 252 196 190 文字


  • 更新 1:最初のアルゴは、西グレゴリオ暦のイースター用でした。現在は東ジュリアン イースターに修正されています。保存された 56 文字 :)

  • 更新 2:ゼロ パディングは必要ないようです。4文字節約。


class E{public static void main(String[]a){long y=new Long(a[0]),b=(y%19*19+15)%30,c=b+(y%4*2+y%7*4-b+34)%7+(y>1899&y<2100?128:115),m=c/31;System.out.printf("%d/%d/%d",c%31+(m<5?0:1),m,y);}}

改行あり

class E{
 public static void main(String[]a){
  long y=new Long(a[0]),
  b=(y%19*19+15)%30,
  c=b+(y%4*2+y%7*4-b+34)%7+(y>1899&y<2100?128:115),
  m=c/31;
  System.out.printf("%d/%d/%d",c%31+(m<5?0:1),m,y);
 }
}
于 2010-08-28T05:04:24.883 に答える
2

Tcl

東のイースター

(116文字)

puts [expr 1+[incr d [expr ([set y $argv]%4*2+$y%7*4-[
set d [expr ($y%19*19+15)%30]]+34)%7+123]]%30]/[expr $d/30]/$y

Meeus アルゴリズムを使用します。コマンド ライン引数として年を取り、East East Eastを生成します。ワンライナーかもしれませんが、分割すると少し読みやすくなります...

西部のイースター

(行に分割する前に 220 文字)

interp alias {} tcl::mathfunc::s {} set;puts [expr [incr 3 [expr {
s(2,(s(4,$argv)%100/4*2-s(3,(19*s(0,$4%19)+s(1,$4/100)-$1/4-($1-($1+8)/25+46)
/3)%30)+$1%4*2-$4%4+4)%7)-($0+11*$3+22*$2)/451*7+114}]]%31+1]/[expr $3/31]/$4

匿名アルゴリズムを使用します。

于 2010-08-28T15:00:19.993 に答える
2

Delphi 377 335 317 文字

単線:

var y,c,n,i,j,m:integer;begin Val(ParamStr(1),y,n);c:=y div 100;n:=y-19*(y div 19);i:=c-c div 4-(c-((c-17)div 25))div 3+19*n+15;i:=i-30*(i div 30);i:=i-(i div 28 )*(1-(i div 28)*(29 div(i+1))*((21 -n)div 11));j:=y+y div 4 +i+2-c+c div 4;j:=j-7*(j div 7);m:=3+(i-j+40 )div 44;Write(i-j+28-31*(m div 4),'/',m,'/',y)end.

フォーマット:

var
  y,c,n,i,j,m:integer;
begin
  Val(ParamStr(1),y,n);
  c:=y div 100;
  n:=y-19*(y div 19);
  i:=c-c div 4-(c-((c-17)div 25))div 3+19*n+15;
  i:=i-30*(i div 30);
  i:=i-(i div 28 )*(1-(i div 28)*(29 div(i+1))*((21 -n)div 11));
  j:=y+y div 4 +i+2-c+c div 4;j:=j-7*(j div 7);
  m:=3+(i-j+40 )div 44; 
  Write(i-j+28-31*(m div 4),'/',m,'/',y)
end.
于 2010-08-28T00:40:52.170 に答える
2

JavaScript (196 文字)

Meeus Julian アルゴリズムを使用します。この実装では、有効な 4 桁の年が指定されていることを前提としています。

y=~~prompt();d=(19*(y%19)+15)%30;x=d+(2*(y%4)+4*(y%7)-d+34)%7+114;m=~~(x/31);d=x%31+1;if(y>1899&&y<2100){d+=13;if(m==3&&d>31){d-=31;m++}if(m==4&&d>30){d-=30;m++}}alert((d<10?"0"+d:d)+"/0"+m+"/"+y)
于 2010-08-28T06:01:47.570 に答える
1

C 、12812198 文字

Meeusのアルゴリズムに戻ります。ジュリアンで1日を計算しますが、グレゴリオ暦に合わせて調整します(これはまだ私にはナイーブに思えますが、より短い代替案を見つけることができません)。

main(y,v){int d=(y%19*19+15)%30;d+=(y%4*2+y%7*4-d+34)%7+128;printf("%d/%d/%d",d%31+d/155,d/31,y);}

floor(d/31)実際に必要になるケースは見つかりませんでした。また、5月の日付を考慮するために、min Meeusのアルゴリズムは少なくとも5である必要があります。したがって、DoMは154より大きいため、除算されます。

年は、プログラム呼び出し引数の数に1を加えた数として提供されます。1996年には、1995年の引数を提供する必要があります。最新のシステムでのARG_MAXの範囲は、これには十分すぎるほどです。

PS。GabeがPython2.3で同じ実装になり、1文字上回っています。ああ。:( PPS。1800-2099の表形式の方法を見ている人はいますか?

編集-Gabeの回答を88文字に短縮:

y=input()
d=(y%19*19+15)%30
d+=(y%4*2+y%7*4-d+34)%7+128
print"%d/%d/%d"%(d%31+d/155,d/31,y)
于 2010-08-29T09:16:06.847 に答える
1

COBOL、1262 文字

WORKING-STORAGE SECTION.

01 V-YEAR       PIC S9(04) VALUE 2010.
01 V-DAY        PIC S9(02) VALUE ZERO.
01 V-EASTERDAY  PIC S9(04) VALUE ZERO.
01 V-CENTURY    PIC S9(02) VALUE ZERO.
01 V-GOLDEN     PIC S9(04) VALUE ZERO.
01 V-GREGORIAN  PIC S9(04) VALUE ZERO.
01 V-CLAVIAN    PIC S9(04) VALUE ZERO.
01 V-FACTOR     PIC S9(06) VALUE ZERO.
01 V-EPACT      PIC S9(06) VALUE ZERO.

PROCEDURE DIVISION

XX-CALCULATE EASTERDAY.

   COMPUTE V-CENTURY = (V-YEAR / 100) + 1
   COMPUTE V-GOLDEN= FUNCTION MOD(V-YEAR, 19) + 1
   COMPUTE V-GREGORIAN = (V-CENTURY * 3) / 4 - 12
   COMPUTE V-CLAVIAN
        = (V-CENTURY * 8 + 5) / 25 - 5 - V-GREGORIAN
   COMPUTE V-FACTOR
        = (V-YEAR * 5) / 4 - V-GREGORIAN - 10
   COMPUTE V-EPACT
   = FUNCTION MOD((V-GOLDEN * 11 + 20 + V-CLAVIAN), 30)

   IF V-EPACT = 24
      ADD 1 TO V-EPACT
   ELSE
      IF V-EPACT = 25
         IF V-GOLDEN > 11
            ADD 1 TO V-EPACT
         END-IF
      END-IF
   END-IF

  COMPUTE V-DAY = 44 - V-EPACT

  IF V-DAY < 21
     ADD 30 TO V-DAY
  END-IF

  COMPUTE V-DAY
  = V-DAY + 7 - (FUNCTION MOD((V-DAY + V-FACTOR), 7))

  IF V-DAY <= 31
     ADD 300 TO V-DAY GIVING V-EASTERDAY
  ELSE
     SUBTRACT 31 FROM V-DAY
     ADD 400 TO V-DAY GIVING V-EASTERDAY
  END-IF
  .
XX-EXIT.
   EXIT.

注:私のものではありませんが、私はそれが好きです

編集:スペースを含む文字数を追加しましたが、COBOLでスペースがどのように機能するかがわからないため、元のものから何も変更しませんでした。~vlad003

更新: OP がこのコードを取得した場所を見つけました: http://www.tek-tips.com/viewthread.cfm?qid=31746&page=112。著者がそれに値するので、私はこれをここに置いています。~vlad003

于 2010-08-27T13:03:30.110 に答える
0
'VB .Net implementation of:
'http://aa.usno.navy.mil/faq/docs/easter.php
Dim y As Integer = 2010
Dim c, d, i, j, k, l, m, n As Integer
c = y \ 100
n = y - 19 * (y \ 19)
k = (c - 17) \ 25
i = c - c \ 4 - (c - k) \ 3 + 19 * n + 15
i = i - 30 * (i \ 30)
i = i - (i \ 28) * (1 - (i \ 28) * (29 \ (i + 1)) * ((21 - n) \ 11))
j = y + y \ 4 + i + 2 - c + c \ 4
j = j - 7 * (j \ 7)
l = i - j
m = 3 + (l + 40) \ 44
d = l + 28 - 31 * (m \ 4)
Easter = DateSerial(y, m, d)
于 2010-08-28T11:42:05.420 に答える
0

Javascript 125 文字

これは 1900 ~ 2199 年を処理します。他の実装の中には、年2100を正しく処理できないものがあります。

y=prompt();k=(y%19*19+15)%30;e=(y%4*2+y%7*4-k+34)%7+k+127;m=~~(e/31);d=e%31+m-4+(y>2099);alert((d+=d<30||++m-34)+"/"+m+"/"+y)

アンゴルフ..っぽい

// get the year to check.
y=prompt();

// do something crazy.
k=(y%19*19+15)%30;

// do some more crazy...
e=(y%4*2+y%7*4-k+34)%7+k+127;

// estimate the month. p.s. The "~~" is like Math.floor
m=~~(e/31);

// e % 31 => get the day
d=e%31;
if(m>4){
    d += 1;
}
if(y > 2099){
   d += 1;
}

// if d is less than 30 days add 1
if(d<30){
   d += 1;
}
// otherwise, change month to May
// and adjusts the days to match up with May.
// e.g., 32nd of April is 2nd of May
else{
    m += 1;
    d = m - 34 + d;
}

// alert the result!
alert(d + "/" + m + "/" + y);

2399 までの日付の修正。
これを超える日付をアルゴリズムで計算する方法があると確信していますが、それを理解したくありません。

y=prompt();k=(y%19*19+15)%30;e=(y%4*2+y%7*4-k+34)%7+k+127;m=~~(e/31);d=e%31+m-4+(y<2200?0:~~((y-2000)/100));alert((d+=d<30||++m-34)+"/"+m+"/"+y)
于 2010-09-02T17:23:35.723 に答える
0

私はそれを実装するつもりはありませんが、コードが教皇に電子メールを送信し、返された回答をスキャンして日付を確認し、それを返すコードを見たいと思っています.

確かに、呼び出しプロセスはしばらくの間ブロックされる可能性があります。

于 2010-08-28T20:54:43.663 に答える
0

BASIC、973 文字

Sub EasterDate (d, m, y)

   Dim FirstDig, Remain19, temp    'intermediate results
   Dim tA, tB, tC, tD, tE          'table A to E results

   FirstDig = y \ 100              'first 2 digits of year
   Remain19 = y Mod 19             'remainder of year / 19

' calculate PFM date
   temp = (FirstDig - 15) \ 2 + 202 - 11 * Remain19

   Select Case FirstDig
      Case 21, 24, 25, 27 To 32, 34, 35, 38
         temp = temp - 1
      Case 33, 36, 37, 39, 40
         temp = temp - 2
   End Select
   temp = temp Mod 30

   tA = temp + 21
   If temp = 29 Then tA = tA - 1
   If (temp = 28 And Remain19 > 10) Then tA = tA - 1

'find the next Sunday
   tB = (tA - 19) Mod 7

   tC = (40 - FirstDig) Mod 4
   If tC = 3 Then tC = tC + 1
   If tC > 1 Then tC = tC + 1

   temp = y Mod 100
   tD = (temp + temp \ 4) Mod 7

   tE = ((20 - tB - tC - tD) Mod 7) + 1
   d = tA + tE

'return the date
   If d > 31 Then
      d = d - 31
      m = 4
   Else
      m = 3
   End If

End Sub

クレジット:南オーストラリア天文学会

編集:文字数を追加しましたが、多くのスペースを削除できると思います。私は BASIC を知らないので、コードを変更しませんでした。~vlad003

于 2010-08-27T13:08:04.323 に答える