Eternal 2014 - PCG.SE New Year's Puzzle 2015

29

Entonces, ahora que es 2015, y un montón de respuestas del rompecabezas del año pasado ahora están comenzando a producir resultados no válidos , es hora de una pregunta sobre el número 2015.

Excepto ... ¿por qué? ¿No le gustaría que sus respuestas basadas en fechas al problema del año pasado fueran válidas? ¿Por qué no cambiamos nuestro calendario para que nunca sea 2015, y simplemente seguimos viviendo en 2014, para siempre jamás?

Definamos una nueva notación de fecha, llamada notación Eterna 2014 , de la siguiente manera:

  • Para las fechas 2014 y anteriores, las fechas serán las mismas que en el calendario gregoriano proleptico .
  • Para las fechas en los años 2015 y en adelante, el año se mantendrá en 2014, y el mes será el número que sería si el mismo ciclo mensual en 2014 continuara para siempre después del mes 12. Así 2015-02-08sería 2014-14-08, y 2020-12-31sería 2014-85-02. Tenga en cuenta que los días bisiestos no se contabilizan porque 2014 no es un año bisiesto.

Su tarea es construir un programa o función que tomará una fecha astronómica juliana como entrada y devolverá una cadena con la fecha correspondiente a esa fecha juliana en notación Eterna 2014, en formato YYYY-MM-DDo DD/MM/YYYY.

Puede suponer que el día juliano ingresado siempre será un número entero desde 1721426(1 de enero, 1) hasta 2914695(23 de enero de 3268) inclusive. Los años pueden contener ceros iniciales para rellenar con 4 dígitos o no, pero los meses y días siempre deben tener ceros iniciales para rellenar con dos dígitos (y los años pueden no contener ceros iniciales para rellenar con cualquier número de dígitos que no sean 4).

Aquí hay algunos ejemplos de entradas y sus salidas, en todos los formatos aceptables:

> 1721426
1-01-01
01/01/1
0001-01-01
01/01/0001

> 2086302
999-12-31
31/12/999
0999-12-31
31/12/0999

> 2456659
2014-01-01
01/01/2014

> 2456789
2014-05-11
11/05/2014

> 2457024
2014-13-01
01/13/2014

> 2457389
2014-25-01
01/25/2014

> 2469134
2014-411-07
07/411/2014

> 2567890
2014-3657-29
29/3657/2014

> 2914695
2014-15059-23
23/15059/2014

No puede utilizar ninguna biblioteca de procesamiento de fechas incorporada en su idioma. Todos los cálculos deben hacerse algorítmicamente dentro del propio código fuente del programa.

El programa más corto (en bytes) para lograr esto en cualquier idioma gana.

Joe Z.
fuente
3
Jaja, esta pregunta recibe 25 votos positivos justo cuando comienza el Winter Bash.
Joe Z.

Respuestas:

12

Python 2, 166 bytes

n=input()
d=m=y=1
M=([3]+[3,2]*3)*2
while n>1721426:
 n-=1;d+=1;M[2]=y%400<1or y%4<1<y%100
 if d>M[m%12]+28:m+=1;d=1
 if m>12<2014>y:y+=1;m=1
print'%02d/'*2%(d,m)+`y`

Esto recorre todos los días desde el 1 de enero, 1 (1721426) hasta la fecha dada, incrementando el día, mes y año actuales a medida que avanza. El último caso de prueba tarda aproximadamente un segundo en mi computadora.

La salida se imprime en el segundo formato:

01/01/1
31/12/999
23/15059/2014
grc
fuente
3

Avestruz 0.5.0 , 197 bytes

G~:J1401+4J*274227+146097/F3*4/F+38~+:f4*3+:e1461:p%4/F:g5*2+:h153:s%5/F1+:D;hs/F2+12:n%1+:M;ep/F4716-n2+M-n/F+:Y;{2014:Y;D365+:D;{M1-12%[31:x28x 30:yxyxxyxyx]=:dD<.{Dd-:D;M1+:M;}*}(}Y2014-*D"/M"/Y

Sin golf (ha):

G~:J;
4716:y;1401:j;2:m;12:n;4:r;1461:p;3:v;5:u;153:s;2:w;274277:B;38~:C;
Jj+4J*B+146097/F3*4/F+C+:f;
rf*v+:e;
ep%r/F:g;
ug*w+:h;
hs%u/F1+:D;
hs/Fm+n%1+:M;
ep/Fy-nm+M-n/F+:Y;
{
2014:Y;
D365+:D;
{
M1-12%[31 28 31 30 31 30 31 31 30 31 30 31]=:d
D<.{Dd-:D;M1+:M;}*
}(
}Y2014-*
D"/M"/Y

Estoy ... realmente agotado de toda la felicidad del Año Nuevo y lo que no. Por eso no he jugado mucho al golf. Puedo o no volver para mejorarlo más tarde.

Algoritmo de https://en.wikipedia.org/wiki/Julian_day#Gregorian_calendar_from_Julian_day_number

Pomo de la puerta
fuente
0

PHP (278)

Ejecutar en línea de comando usando php -R '<code>'. (La bandera cuenta como un personaje).

if(0<$N=($n=$argn-1721426)-735233){$n=$N%365+735233;$o=12*($N/365|0);}for($y=1+400*($n/146097|0)+100*(($n%=146097)/36524|0)+(($n%=36524)/1461<<2)+(($n%=1461)/365|0);($n%=365)>=$d=@++$m-2?30+($m+($m>>3)&1):29-($y%4||!($y%100)&&$y%400);)$n-=$d;printf("$y-%02d-%02d",$m+@$o,$n+1);

Versión más legible (ejecutar con nombre de archivo y sin -R):

<?php

// step 1: read the input and fix up 2014 dates
if (0 < $N = ($n = fgets(STDIN) - 1721426) - 735233) {
    $n = $N % 365 + 735233; // wrap around to 2014-01-01
    $o = 12 * ($N / 365 | 0); // compute month offset
}

for (

// step 2: extract year
$y = 1
    + 400 * ($n / 146097 | 0)
    + 100 * (($n %= 146097) / 36524 | 0)
    + (($n %= 36524) / 1461 << 2)
    + (($n %= 1461) / 365 | 0);

// step 3: extract month and day
($n %= 365) >= $d = @++$m - 2
    ? 30 + ($m + ($m >> 3) & 1)
    : 29 - ($y % 4 || !($y % 100) && $y % 400);

) $n -= $d;

// step 4: print date string, adding the month offset
// previously computed in step 1.
printf("$y-%02d-%02d", $m + @$o, $n + 1);
Por favor levantese
fuente
0

C (algo así como ... gcc lo permite) 183

Muchas advertencias por falta de estandarización y probablemente increíblemente inportable, pero hoy funciona en mi máquina.

y=1;m;d;main(n,a){for(n=atoi(a[1]);n-->1721426;)++d>((m%12<7?m%2==0:m%2!=0)?30:m%12-1?29:y%(y%100?4:400)?27:28)&&(++m,d=0,m>11&&y<2014)&&(++y,m=0);printf("%d-%02d-%02d\n",y,m+1,d+1);}

Utiliza el mismo algoritmo que la respuesta de Python 2 de @grc

El resultado después de compilar es

test2014 2086302
999-12-31

test2014 2456659
2014-01-01

test2014 2456789
2014-05-11

test2014 2457024
2014-13-01

test2014 2457389
2014-25-01

test2014 2469134
2014-411-07

test2014 2567890
2014-3657-29

test2014 2914695
2014-15059-23
Jerry Jeremiah
fuente