Code Golf: вычислить дату православной пасхи

Задача

Рассчитать дату греческой православной Пасхи ( http://www.timeanddate.com/holidays/us/orthodox-easter-day ) воскресенье в данной Год (1900-2100) с использованием наименьшего количества символов.

Ввод - это просто год в форме «2010». Это не имеет значения, где вы получаете это (вход, Я имею в виду восточную Пасху.

Ссылка: http://en.wikipedia.org/wiki/Computus

25
задан 19 revs, 8 users 38% 28 August 2010 в 23:36
поделиться

12 ответов

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.

Примечание: не мое, но мне нравится

EDIT: я добавил количество символов с пробелами, но я не знаю, как интервалы работают в COBOL, поэтому я ничего не менял из оригинал. ~ vlad003

ОБНОВЛЕНИЕ: Я нашел, откуда ОП взял этот код: http://www.tek-tips.com/viewthread.cfm?qid=31746&page=112. Я ставлю это здесь, потому что автор этого заслуживает. ~ влад003

1
ответ дан 28 November 2019 в 21:36
поделиться

Java - 252 196 190 символов


  • Обновление 1: Первое algo был для западной григорианской Пасхи. Теперь исправлена ​​восточная юлианская Пасха. Сохранено 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);
 }
}
3
ответ дан 28 November 2019 в 21:36
поделиться
'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)
0
ответ дан 28 November 2019 в 21:36
поделиться

C#, 155 157 182 209 212 символов

класс 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 (и должен работать для дат в Мая).

  • убрана необязательная проверка на современные годы и добавление нуля в вывод
  • больше не ждите Пасхи в марте, потому что между 18:00 и 21:00 их нет
  • включена версия Python 2.3 (на данный момент самая короткая)
4
ответ дан 28 November 2019 в 21:36
поделиться

Mathematica

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

Вызов с

a[2010]

Выводом

4/4/2010

Я тоже: Не вижу смысла не использовать встроенные функции.

4
ответ дан 28 November 2019 в 21:36
поделиться

Я не собираюсь это реализовывать, но я хотел бы увидеть код, в котором код отправляет электронное письмо Папе Римскому, сканирует любой ответ, который возвращается для даты, и возвращает его.

Следует признать, что вызывающий процесс может быть заблокирован на некоторое время.

0
ответ дан 28 November 2019 в 21:36
поделиться

PHP CLI, № easter_date(), 125 символов

Действительно для дат с 13 марта 1900 г. по 13 марта 2100 г., теперь работает для майских Пасх

Код:

<?=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
4
ответ дан 28 November 2019 в 21:36
поделиться

JavaScript (196 символов)

Использование алгоритма Миуса Джулиана. Эта реализация предполагает, что год был указан действительным четырехзначным числом.

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)
2
ответ дан 28 November 2019 в 21:36
поделиться

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.
2
ответ дан 28 November 2019 в 21:36
поделиться

БАЗОВЫЙ, 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

Авторы и права: Астрономическое общество Южной Австралии

РЕДАКТИРОВАТЬ: я добавил количество символов, но я думаю, что многие пробелы могут быть удалены; Я не знаю Бейсика, поэтому не вносил никаких изменений в код. ~vlad003

0
ответ дан 28 November 2019 в 21:36
поделиться

C, 128 121 98 символов

Назад к алгоритму Миуса. Вычисление дня по юлианскому календарю, но с поправкой на григорианский (мне это все еще кажется наивным, но я не могу найти более короткую альтернативу).

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) действительно был бы необходим. Кроме того, для учета дат в мае m в алгоритме Миуса должно быть не менее 5, поэтому DoM больше 154, отсюда и деление.

Год указывается как количество аргументов вызова программы плюс один, т.е. для 1996 года вы должны предоставить аргументы 1995 года. Диапазона ARG_MAX на современных системах для этого более чем достаточно.

ПС. Вижу, Гейб пришел к той же реализации в Python 2.3, обойдя меня на один символ. Ой. :( ППС. Кто-нибудь смотрел табличный метод для 1800-2099?

Изменить. Сокращен ответ Гейба до 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)
1
ответ дан 28 November 2019 в 21:36
поделиться

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

Использует алгоритм Миуса. Принимает год в качестве аргумента командной строки, выдает Eastern easter. Это может быть однострочный текст, но он более читабелен при разделении...

Западная Пасха

(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

Использует анонимный алгоритм.

2
ответ дан 28 November 2019 в 21:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: