language-agnostic code-golf rosetta-stone

language agnostic - Código de golf: Calcular la fecha de Pascua ortodoxa



language-agnostic code-golf (14)

C, 128 121 98 caracteres

De vuelta al algoritmo de Meeus. Cálculo del día en Julian, pero ajuste para Gregorian (esto todavía me parece ingenuo, pero no puedo encontrar una alternativa más corta).

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

No he encontrado un caso en el que realmente se necesitara floor(d/31) . Además, para tener en cuenta las fechas de mayo, la m en el algoritmo de Meeus debe ser al menos 5, por lo tanto, el DoM es mayor que 154, por lo tanto, la división.

El año se proporciona como el número de argumentos de invocación del programa más uno, es decir. Para 1996 debes aportar los argumentos de 1995. La gama de ARG_MAX en los sistemas modernos es más que suficiente para esto.

PD. Veo que Gabe ha llegado a la misma implementación en Python 2.3, superándome por un personaje. Ah :( PPS. ¿Alguien está mirando un método tabular para 1800-2099?

Editar - Acortó la respuesta de Gabe a 88 caracteres:

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)

El reto

Calcule la fecha de la Pascua ortodoxa griega ( http://www.timeanddate.com/holidays/us/orthodox-easter-day ) el domingo de un año determinado (1900-2100) utilizando la menor cantidad de caracteres.

La entrada es solo un año en el formulario ''2010''. No es relevante donde lo obtengas (Input, CommandLineArgs, etc.) ¡pero debe ser dinámico!

La salida debe estar en la forma día-mes-año (por ejemplo, dd/mm/yyyy o d/m/yyyy )

Restricciones ¡ No se deben usar funciones estándar, como easter_date() Mathematica o easter_date() PHP, que devuelven la fecha (no aplicable gregorian) automática!

Ejemplos

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

El conteo de códigos incluye entrada / salida (es decir, programa completo).

Edit: me refiero a la fecha de Pascua del este .

Referencia: http://en.wikipedia.org/wiki/Computus


COBOL, 1262 caracteres

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.

Nota: No es mía, pero me gusta.

EDIT: Agregué un recuento de caracteres con espacios, pero no sé cómo funciona el espaciado en COBOL, así que no cambié nada del original. ~ vlad003

ACTUALIZACIÓN: he encontrado dónde el OP obtuvo este código: http://www.tek-tips.com/viewthread.cfm?qid=31746&page=112 . Solo estoy poniendo esto aquí porque el autor lo merece. ~ vlad003


Tcl

Pascua oriental

(116 caracteres)

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

Utiliza el algoritmo de Meeus. Toma el año como argumento de línea de comando, produce Eastern easter. Podría ser de una sola línea, pero es un poco más legible cuando se divide ...

Pascua occidental

(220 caracteres antes de dividir sobre líneas)

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

Utiliza el algoritmo anónimo.


BASIC, 973 caracteres

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

Crédito: Sociedad Astronómica de Australia del Sur

EDITAR: Agregué un recuento de caracteres pero creo que se podrían eliminar muchos espacios; No sé BASIC, así que no hice ningún cambio en el código. ~ vlad003


C #, 155 157 182 209 212 caracteres

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 caracteres

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)

Esto también usa el algoritmo Meeus Julian (y debería funcionar para las fechas de mayo).

  • eliminado ya no es necesario comprobar para los años modernos y cero relleno en la salida
  • No esperes más a los Easters en marzo porque no hay ninguno entre 1800-2100
  • Incluye la versión de Python 2.3 (la más corta hasta ahora)

Delphi 377 335 317 caracteres

Linea sola:

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.

Formateado:

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.


Java - 252 196 190 caracteres

  • Actualización 1: El primer algo fue para Western Gregorian Easter. Arreglado a Eastern Julian Easter ahora. Guarda 56 caracteres :)

  • Actualización 2: Parece que no se requiere relleno de cero. Guarda 4 caracteres.

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

Con nuevas líneas

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


JavaScript (196 caracteres)

Utilizando el algoritmo Meeus Julian . Esta implementación asume que se dio un año válido de cuatro dígitos.

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)


Javascript 125 caracteres

Esto manejará los años 1900 - 2199. Algunas de las otras implementaciones no pueden manejar el año 2100 correctamente.

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

Una solución para las fechas hasta 2399.
Estoy seguro de que hay una manera de calcular fechas de forma algorítmica más allá de esto, pero no quiero averiguarlo.

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)


Matemática

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

Invocar con

a[2010]

Salida

4/4/2010

Yo también: no veo el punto de no usar funciones integradas .


PHP CLI, no easter_date() , 125 caracteres

Válido para las fechas del 13 de marzo de 1900 al 13 de marzo de 2100, ahora funciona para Easters que caen en mayo

Código:

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

Invocación:

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

Salida:

04/04/2010 01/05/2005

Con espacios en blanco:

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

Esta iteración ya no es legible gracias al manejo de tareas por parte de PHP. ¡Es casi un lenguaje funcional!

Para completar, aquí está la solución anterior de 127 caracteres que no se basa en etiquetas cortas:

Código:

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

Invocación:

$ 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


Python ( 101 140 132 115 caracteres)

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

Este utiliza el algoritmo Meeus Julian, pero como este solo funciona entre 1900 y 2099, una implementación que usa el algoritmo gregoriano anónimo se está implementando.

Edición: Ahora 2005 se maneja adecuadamente. Gracias a Mark por señalarlo.

Edición 2: Mejor manejo de algunos años, ¡gracias por todos los comentarios!

Edit 3: Debería funcionar para todos los años en rango. (Perdón por haberlo secuestrado Juan.)


No lo voy a implementar, pero me gustaría ver uno en el que el código envíe un correo electrónico al Papa, escanee cualquier respuesta que regrese para una fecha y la devuelva.

Es cierto que el proceso de llamada puede estar bloqueado por un tiempo.


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