Eternal 2014 - Puzzle Tahun Baru PCG.SE 2015

29

Jadi, sekarang ini tahun 2015, dan banyak jawaban dari teka - teki tahun lalu sekarang mulai menghasilkan output yang tidak valid , saatnya untuk pertanyaan yang melibatkan angka 2015.

Kecuali ... mengapa? Tidakkah Anda menyukainya jika jawaban berbasis tanggal Anda untuk masalah tahun lalu tetap valid? Mengapa kita tidak mengubah kalender kita sehingga tidak pernah 2015, dan kita terus hidup di tahun 2014, selamanya?

Mari kita tentukan notasi tanggal baru, yang disebut notasi Eternal 2014 , sebagai berikut:

  • Untuk tanggal 2014 dan sebelumnya, tanggalnya akan sama dengan di kalender Gregorian yang subur .
  • Untuk tanggal di tahun 2015 dan seterusnya, tahun akan tetap 2014, dan bulan akan menjadi jumlah itu akan menjadi jika siklus bulan yang sama di 2014 akan terus berlanjut melewati 12 bulan. Jadi 2015-02-08akan 2014-14-08, dan 2020-12-31akan 2014-85-02. Perhatikan bahwa hari kabisat tidak diperhitungkan karena 2014 bukan tahun kabisat.

Tugas Anda adalah untuk membangun program atau fungsi yang akan mengambil tanggal astronomi Julian sebagai input dan mengembalikan string dengan tanggal yang sesuai dengan tanggal Julian dalam notasi Eternal 2014, dalam format YYYY-MM-DDatau salah satu DD/MM/YYYY.

Anda dapat mengasumsikan bahwa hari Julian yang dimasukkan akan selalu berupa bilangan bulat dari 1721426(1 Januari, 1) hingga 2914695(23 Januari 3268) inklusif. Tahun dapat berisi nol mengarah ke pad ke 4 digit atau tidak, tetapi bulan dan hari harus selalu memiliki nol mengarah ke pad ke dua digit (dan tahun mungkin tidak mengandung nol mengarah ke pad ke sejumlah digit selain dari 4).

Berikut adalah beberapa contoh input dan outputnya, dalam semua format yang dapat diterima:

> 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

Anda tidak dapat menggunakan perpustakaan pemrosesan tanggal bawaan dalam bahasa Anda. Semua perhitungan harus dilakukan secara algoritmik dalam kode sumber program itu sendiri.

Program terpendek (dalam byte) untuk mencapai ini dalam bahasa apa pun menang.

Joe Z.
sumber
3
Haha, pertanyaan ini mendapat 25 upvotes tepat saat Bash Musim Dingin dimulai.
Joe Z.

Jawaban:

12

Python 2, 166 byte

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`

Ini berputar setiap hari mulai 1 Januari 1 (1721426) hingga tanggal yang ditentukan, menambah hari, bulan, dan tahun saat ini. Kasing tes terakhir memakan waktu sekitar satu detik di komputer saya.

Output dicetak dalam format kedua:

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

Burung unta 0.5.0 , 197 byte

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

Tidak disatukan (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

Aku ... benar-benar lelah dari semua kebahagiaan Tahun Baru dan apa yang tidak. Itu sebabnya saya belum bermain golf sebanyak ini. Saya mungkin atau mungkin tidak kembali untuk membuatnya lebih baik nanti.

Algoritma dari https://en.wikipedia.org/wiki/Julian_day#Gregorian_calendar_from_Julian_day_number

Gagang pintu
sumber
0

PHP (278)

Jalankan pada baris perintah menggunakan php -R '<code>'. (Bendera dihitung sebagai satu karakter.)

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 yang lebih mudah dibaca (jalankan menggunakan nama file dan tanpa -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);
Tolong berdiri
sumber
0

C (semacam ... gcc memungkinkan) 183

Banyak peringatan untuk ketidakstabilan dan mungkin sangat tidak dapat dipercaya, tetapi ini bekerja pada komputer saya hari ini.

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

Ini menggunakan algoritma yang sama dengan jawaban Python 2 oleh @ grc

Output setelah kompilasi adalah

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
sumber