Подтвердить что ты не робот

Code Golf: рассчитать православную Пасху

Задача

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

Вход - это всего лишь год в форме "2010". Это не относится к тому, где вы его получаете (Input, CommandLineArgs и т.д.), Но он должен быть динамическим!

Вывод должен быть в форме day-month-year (скажем dd/mm/yyyy или d/m/yyyy)

Ограничения Нет стандартных функций, таких как Mathematica EasterSundayGreekOrthodox или PHP easter_date(), которые возвращают (не применимо gregorian) дата должна быть использована!

<сильные > Примеры

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

Количество кодов включает ввод/вывод (т.е. полную программу).

Edit: Я имею в виду Восточная дата Пасхи.

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

4b9b3361

Ответ 1

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 годами, реализация с использованием Анонимный григорианский алгоритм подходит.

Изменить: теперь 2005 правильно обрабатывается. Спасибо Марку за то, что он указал.

Изменить 2: улучшить обработку нескольких лет, спасибо за весь вход!

Редактировать 3: Должен работать в течение всех лет в радиусе действия. (Извините за захват Хуана.)

Ответ 3

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

Действует для дат с 13 марта 1900 по 13 марта 2100 года, теперь работает для Easters, которые падают в мае

код:

<?=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

С#, 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 (и должен работать для дат в мае).

  • удалена ненужная проверка на современные годы и нулевое заполнение на выходе
  • не ожидайте Easters в марте больше, потому что нет между 1800-2100
  • включена версия Python 2.3 (самая короткая до сих пор)

Ответ 5

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);
 }
}

Ответ 6

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.

Ответ 7

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

Использование алгоритм Meeus Julian. Эта реализация предполагает, что был дан действительный четырехзначный год.

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)

Ответ 8

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. Принимает год как аргумент командной строки, производит восточный пасхальный. Может быть однострочным, но он немного читабельнее, когда сплит...

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

(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

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

Ответ 9

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: я добавил счет char с пробелами, но я не знаю, как интервал работает в COBOL, поэтому я ничего не менял с оригинала. ~ Vlad003

UPDATE: Я нашел, где OP получил этот код: http://www.tek-tips.com/viewthread.cfm?qid=31746&page=112. Я просто помещаю это здесь, потому что автор этого заслуживает. ~ Vlad003

Ответ 10

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

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

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 в Meeus должен быть не менее 5, поэтому DoM больше 154, следовательно, деление.

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

PS. Я вижу, что Гейб пришел к той же реализации в Python 2.3, обогнав меня одним персонажем. Aw.:( 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)

Ответ 11

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

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

EDIT: я добавил счет char, но я думаю, что многие пробелы могут быть удалены; Я не знаю BASIC, поэтому я не вносил никаких изменений в код. ~ Vlad003

Ответ 12

'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)

Ответ 13

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

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

Ответ 14

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)

Ungolfed..ish

// 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)