Apakah kita sudah sampai?

22

Saya seorang penjelajah waktu, dan saya terobsesi dengan perjalanan waktu. Saya sangat suka saat-saat ketika jarum jam melewati 12, atau ketika saya bisa beralih ke halaman berikutnya dari kalender saya, atau ketika semua orang berteriak "Selamat Tahun Baru!"

Tolong tuliskan bagi saya sebuah program untuk menunjukkan kepada saya seberapa jauh saya dari saat seperti terakhir ke yang berikutnya, dalam bentuk progress bar. Misalnya, jika saya katakan pukul 09:12, maka harus dicetak ini:

09:00 ####---------------- 10:00

Jika saya katakan bulan ini adalah bulan Mei 1982, itu harus dicetak:

1982-01 #######------------- 1983-01

Apakah saya menyebutkan saya penjelajah waktu? Saya melakukan perjalanan ke mana saja dari milidetik pertama 0 M hingga milidetik terakhir 9999 M, sehingga program perlu menangani tanggal dan waktu dalam rentang itu.

Memasukkan

  • Input akan berada dalam salah satu format berikut:

    • YYYY-MM-DDThh:mm:ss.sss
    • YYYY-MM-DDThh:mm:ss
    • YYYY-MM-DDThh:mm
    • YYYY-MM-DDThh
    • YYYY-MM-DD
    • YYYY-MM

    Ini adalah satu-satunya format yang perlu ditangani. Setiap bagian akan memiliki jumlah digit yang ditampilkan, yang berarti detik pecahan mungkin memiliki angka nol (misalnya .120, tidak pernah .12). Ini Tadalah huruf literal "T" yang membatasi tanggal dari waktu. Jam berada pada jam 24 jam.

  • Bulan dan hari berbasis 1 (lebih lanjut tentang ini di bawah).

  • Input yang tidak valid dan di luar jangkauan tidak perlu ditangani.

  • Sesuai kebijaksanaan programmer, input mungkin memiliki satu baris tambahan.

Kemajuan matematika bar

Program ini berkaitan dengan unit paling sedikit dan paling sedikit kedua dalam input yang diberikan. Misalnya, jika input memiliki tingkat presisi hari (misalnya 2016-12-14), bilah kemajuan akan menunjukkan proporsi hari dalam bulan input yang telah berlalu dibandingkan yang tersisa.

Progress bar akan memiliki 20 unit (karakter) dan proporsi diwakili akan dibulatkan ke kenaikan terdekat dari 1 / 20 . Misalnya, diberikan 2016-12-14T12:28, bilah progres akan menunjukkan Putaran ( 2860 × 20) = 9 dari 20 unit "terisi."

Bulan dan hari berbasis 1

Meskipun hari 1 Desember (misalnya) sudah 01dalam 2016-12-01, untuk tujuan perhitungan itu adalah hari ke-0 dalam sebulan, karena unit terpotong menyiratkan milidetik ke-0 pada menit ke-0 dari menit ke-0 dari jam ke-0 pada hari itu. Dengan kata lain, 2016-12-01adalah 0 / 31 dari jalan sampai Desember dan 2016-12-02merupakan 1 / 31 , dan seterusnya.

Demikian juga, 2016-01adalah milidetik 0 hari 0 Januari, sehingga dalam perhitungan itu adalah 0 / 12 , yang berarti 2016-12adalah 11 / 12 .

Ya, itu berarti bulan dan hari tidak akan pernah sepenuhnya mengisi bilah kemajuan.

Durasi bulan dan tahun kabisat yang berbeda

Bulan yang berbeda memiliki jumlah hari yang berbeda dan hasilnya harus mencerminkan hal ini — termasuk tahun kabisat. Bilah progres untuk 6 Februari 2017 akan berbeda dari bilah progres untuk 6 Februari 2016 (atau 6 Januari di kedua tahun tersebut).

Lain-lain

  • Pelancong waktu menggunakan kalender Gregorian yang subur . TL; DR: Tidak ada kasus khusus seperti hari yang hilang pada 1752 . Input akan mencakup tanggal pada tahun 0 M
  • Pelancong waktu mengabaikan penghematan siang hari.
  • Program ini tidak diharuskan untuk menghitung detik kabisat, tetapi mungkin saja.

Keluaran

Program (atau fungsi) harus mencetak (atau mengembalikan sebagai string) bilah kemajuan 20-karakter yang berorientasi horizontal yang "diisi" untuk waktu yang telah berlalu dan "terbuka" untuk waktu yang tersisa. Itu harus "mengisi" dari kiri ke kanan.

Bilah kemajuan harus memiliki label di sebelah kiri yang menunjukkan awal periode yang dihitung dan yang lain di sebelah kanan menunjukkan awal periode berikutnya, dalam format yang sama dengan input (tetapi hanya menunjukkan dua unit presisi). Sebagai contoh, 2016-12-14output yang valid adalah:

12-01 #########----------- 01-01

Berikut adalah format label yang valid untuk masing-masing periode yang mungkin:

  • Bulan: YYYY-MM
  • Hari: MM-DD
  • Jam: DDThh
  • Menit: hh:mm
  • Detik: mm:ss
  • Milidetik: ss.sss

Tidak ada unit tambahan yang dapat dimasukkan dalam label, dan tidak ada yang dapat dihilangkan.

Catatan keluaran

  • Unit "diisi" progress bar akan diwakili oleh #karakter. "Buka" unit akan diwakili oleh -.
  • Harus ada tepat satu ruang antara bilah kemajuan dan setiap label.
  • Ruang depan atau belakang dan / atau baris baru tunggal diperbolehkan.

Kemenangan

Ini adalah . Kode terpendek dalam byte menang. Aturan standar berlaku. Celah standar dilarang.

Contohnya

Input                      Output
-----------------------    -------------------------------------
2016-12-12T12:17           12:00 ######-------------- 13:00
2016-12-12                 12-01 #######------------- 01-01
0000-01-01T00:00:00.000    00.000 -------------------- 01.000
0000-01-01T00:00           00:00 -------------------- 01:00
1899-12-31T23              31T00 ###################- 01T00
1899-12-31                 12-01 ###################- 01-01
1899-12                    1899-01 ##################-- 1900-01
1982-05-15T17:15           17:00 #####--------------- 18:00
1982-05-15T17              15T00 ##############------ 16T00
1982-05                    1982-01 #######------------- 1983-01
9999-12-31T23:59:59.999    59.000 #################### 00.000
9999-12                    9999-01 ##################-- 10000-01
2000-01-06                 01-01 ###----------------- 02-01
2000-02-06                 02-01 ###----------------- 03-01
2001-02-06                 02-01 ####---------------- 03-01
1742-09-10                 09-01 ######-------------- 10-01
Jordan
sumber
4
Apakah kita harus khawatir tentang detik kabisat?
Riley
@Riley Pertanyaan bagus. Tidak.
Jordan
2
Saya menganggap Daylight Savings diabaikan, karena tidak ada satu bentuk standar?
CAD97
3
@ CAD97 Pertanyaan bagus. Anda benar. DST benar-benar menyulitkan para pelancong waktu sehingga kami mengabaikannya.
Jordan
Contoh "1899-12-31T23" tidak valid sesuai dengan daftar format input yang disediakan, sama dengan "1982-05-15T17". Harap verifikasi data pengujian Anda.
zeppelin

Jawaban:

4

JavaScript, 282 byte

(x,v=x.split(/\D/g),l=v.length-2,[a,b,c,d]=("10e5,01,-,12,01,-,"+new Date(v[0],v[1],0).getDate()+",00,T,24,00,:,60,00,:,60,000,.,1000").split`,`.slice(l*3,l*3+4),t=(v[l+1]-b)/d*20+.5|0,n=v[l],o=((n|0)+1)%a,r=l?('0'+o).slice(-2):o)=>n+c+b+' '+'#'.repeat(t)+'-'.repeat(20-t)+' '+r+c+b

Lewati semua tes

(
x,
v=x.split(/\D/g),
l=v.length-2,
[a,b,c,d]=("10e5,01,-,12,01,-,"+new Date(v[0],v[1],0).getDate()+",00,T,24,00,:,60,00,:,60,000,.,1000").split`,`.slice(l*3,l*3+4),
t=(v[l+1]-b)/d*20+.5|0,
n=v[l],
o=((n|0)+1)%a,
r=l?('0'+o).slice(-2):o
) =>n+c+b+' '+'#'.repeat(t)+'-'.repeat(20-t)+' '+r+c+b

Fungsi tes tidak mencetak apa-apa untuk lulus, nilai untuk gagal.

function test(value,expected){
    if (f(value)!=expected)
    {
        console.log(value);
        console.log(f(value));
        console.log(expected);
     }
}

Kasus uji:

test('2016-12-12T12:17','12:00 ######-------------- 13:00')                 ;
test('2016-12-12','12-01 #######------------- 01-01')                       ;
test('0000-01-01T00:00:00.000','00.000 -------------------- 01.000')        ;
test('0000-01-01T00:00','00:00 -------------------- 01:00')                 ;
test('1899-12-31T23','31T00 ###################- 01T00')                    ;
test('1899-12-31','12-01 ###################- 01-01')                       ;
test('1899-12','1899-01 ##################-- 1900-01')                      ;
test('1982-05-15T17:15','17:00 #####--------------- 18:00')                 ;
test('1982-05-15T17','15T00 ##############------ 16T00')                    ;
test('1982-05','1982-01 #######------------- 1983-01')                      ;
test('9999-12-31T23:59:59.999','59.000 #################### 00.000')        ;
test('9999-12','9999-01 ##################-- 10000-01')                     ;
test('2000-01-06','01-01 ###----------------- 02-01')                       ;
test('2000-02-06','02-01 ###----------------- 03-01')                       ;
test('2001-02-06','02-01 ####---------------- 03-01')                       ;
test('1742-09-10','09-01 ######-------------- 10-01')                       ;
Grax32
sumber
2
Saya harus belajar bahasa baru untuk menjadi versi teratas ... ini sangat ringkas!
rexroni
3

Pyth, 213 byte

Kode pertama saya di pyth! Melihat:

+%h=N:[d"%.4d"\-=Z"%.2d"\-Z\TZ\:Z\:Z\."%.3d")-*2lKr:w"[-T:.]"d7 3*2lKJ@K_2+@N1+%eN=b<lK4+d+*\#=Gs+*20c-eKb@=H[0^9T12?q2=k@K1+28+q0%=YhK4-q0%Y400q0%Y100+30%+k/k8 2 24 60 60 999)lK.5+*\--20G+d+%hN%+J1@H-lK1+@N1%eNb

Kode pyth saya berdasarkan dari jawaban python saya sebelumnya. Berikut adalah versi yang tidak diklik dengan komentar:

"K is the input, as a list of numbers"
Kr:w"[-T:.]"d7
"Y=year"
=YhK
"k=month"
=k@K1
"H = a list of denominators"
=H[0 ^9T 12 ?q2k+28+q0%Y4-q0%Y400q0%Y100 +30%+k/k8 2 24 60 60 999)
"J is the second-to-last number of the input"
J@K_2
"b is the +1 starting point for months and days"
=b<lK4
"G is the number of hashtags in the statusbar"
=Gs+*[email protected]
"N is the formatted string"
=N:[d"%.4d"\-=Z"%.2d"\-Z\TZ\:Z\:Z\."%.3d")-*2lK3 *2lK
+%hNJ+@N1+%eNb+d+*\#G+*\--20G+d+%hN%+J1@H-lK1+@N1%eNb

Menguji banyak nilai dengan mudah dilakukan dengan membuat loop kode, dan menambahkan cetakan baris baru sampai akhir:

Wp+%h=N:[d"%.4d"\-=Z"%.2d"\-Z\TZ\:Z\:Z\."%.3d")-*2lKr:w"[-T:.]"d7 3*2lKJ@K_2+@N1+%eN=b<lK4+d+*\#=Gs+*20c-eKb@=H[0^9T12?q2=k@K1+28+q0%=YhK4-q0%Y400q0%Y100+30%+k/k8 2 24 60 60 999)lK.5+*\--20G+d+%hN%+J1@H-lK1+@N1+%eNb"\n"

Lalu saya berlari cat testinput | pyth code.pyth > outputdan diff output testoutput Atau mencobanya secara online .

rexroni
sumber
2

Python 2, 371 byte

Tantangan ini ternyata sangat sulit! Sepertinya saya akan berusia di bawah 300 sampai saya berhasil memformat string output.

Jenis bagian yang keren adalah bahwa jawaban saya tidak menggunakan paket tanggal:

import re
s=raw_input()
S=[int(i)for i in re.sub('[-T:.]',' ',s).split()]
l=len(S)
y,m=S[:2]
d=[0,20<<9,12,28+(y%4==0!=y%100)+(y%400==0)if m==2else 30+(m+m/8)%2,24,60,60,999]
a,n=S[-2:]
b=1-(1if l>3else 0)
h=int(20.*(n-b)/d[l]+.5)
x,y,z='- %.4d - %.2d - %.2d T %.2d : %.2d : %.2d . %.3d'.split()[l*2-3:l*2]
print x%a+y+z%b+' '+'#'*h+'-'*(20-h)+' '+x%((a+1)%d[l-1])+y+z%b
rexroni
sumber