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
Ответы
Ответ 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: Должен работать в течение всех лет в радиусе действия. (Извините за захват Хуана.)
Ответ 2
Математика
<<Calendar`;a=Print[#3,"/",#2,"/",#]&@@[email protected]#&
Вызвать
a[2010]
Выход
4/4/2010
Я тоже: Я не вижу смысла не использовать встроенные функции. p >
Ответ 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 символов
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)