แล้วเราล่ะ


22

ฉันเป็นนักเดินทางข้ามเวลาและฉันหลงไหลไปตามกาลเวลา ฉันรักช่วงเวลาที่เข็มนาฬิกาผ่าน 12 หรือเมื่อฉันต้องพลิกไปที่หน้าถัดไปของปฏิทินของฉันหรือเมื่อทุกคนตะโกนว่า "สวัสดีปีใหม่!"

โปรดเขียนโปรแกรมให้ฉันเพื่อแสดงให้ฉันเห็นว่าฉันอยู่ในช่วงเวลาดังกล่าวจนถึงช่วงเวลาสุดท้ายเท่าไรในรูปแบบของแถบความคืบหน้า ตัวอย่างเช่นถ้าฉันบอกเวลาเป็น 09:12 ควรพิมพ์สิ่งนี้:

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

ถ้าฉันบอกว่าเดือนนี้คือเดือนพฤษภาคม 2525 มันควรจะพิมพ์สิ่งนี้:

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

ฉันพูดถึงฉันเป็นนักเดินทางข้ามเวลาหรือไม่? ฉันเดินทางไปที่ใดก็ได้ตั้งแต่มิลลิวินาทีแรกของ 0 AD ถึงมิลลิวินาทีสุดท้ายของ 9999 AD ดังนั้นโปรแกรมต้องจัดการวันที่และเวลาในช่วงนั้น ๆ

อินพุต

  • อินพุตจะอยู่ในรูปแบบใดรูปแบบหนึ่งต่อไปนี้:

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

    รูปแบบเหล่านี้เป็นรูปแบบเดียวที่จำเป็นต้องได้รับการจัดการ แต่ละส่วนจะมีจำนวนตัวเลขที่แสดงซึ่งหมายความว่าวินาทีเศษส่วนอาจมีศูนย์ต่อท้าย (เช่น.120ไม่เคย.12) นี่Tคือตัวอักษร "T" ตามตัวอักษรเพื่อกำหนดวันที่จากเวลา เวลาเปิดทำการตลอด 24 ชั่วโมง

  • เดือนและวันเป็นแบบ 1 (เพิ่มเติมในด้านล่างนี้)

  • อินพุตไม่ถูกต้องและไม่อยู่ในช่วงที่ต้องการ

  • ขึ้นอยู่กับดุลยพินิจของโปรแกรมเมอร์อินพุตอาจมีการขึ้นบรรทัดใหม่ต่อท้ายเดียว

คณิตศาสตร์บาร์ความคืบหน้า

โปรแกรมเกี่ยวข้องกับหน่วยที่มีนัยสำคัญน้อยที่สุดและที่สองน้อยที่สุดในอินพุตที่กำหนด ตัวอย่างเช่นหากอินพุทมีความแม่นยำระดับวัน (เช่น2016-12-14) แถบความคืบหน้าจะระบุสัดส่วนของวันในเดือนอินพุตที่ผ่านไปและสิ่งที่เหลืออยู่

แถบความคืบหน้าจะมี 20 หน่วย (ตัวอักษร) และสัดส่วนที่เป็นตัวแทนจะโค้งมนไปยังเพิ่มขึ้นใกล้เคียงกับ1 / 20 ตัวอย่างเช่นกำหนด2016-12-14T12:28แถบความคืบหน้าจะแสดงรอบ ( 28 / 60 × 20) = 9ของ 20 หน่วย "เต็มไป."

1 เดือนและวัน

แม้ว่าวันที่ 1 ธันวาคม (ตัวอย่าง) จะมี01ไว้2016-12-01เพื่อวัตถุประสงค์ในการคำนวณ แต่เป็นวันที่ 0 ของเดือนเนื่องจากหน่วยที่ถูกตัดทอนมีความหมายเป็นมิลลิวินาทีที่ 0 ของนาทีที่ 0 ของชั่วโมงที่ 0 ของวัน ในคำอื่น ๆ2016-12-01คือ0 / 31ของทางผ่านเดือนธันวาคมและ2016-12-02เป็น1 / 31และอื่น ๆ

ในทำนองเดียวกัน2016-01เป็นมิลลิวินาที 0 ของวันที่ 0 ของเดือนมกราคมดังนั้นในการคำนวณมันเป็น0 / 12ซึ่งหมายถึง2016-12เป็น11 / 12

ใช่นั่นหมายความว่าเดือนและวันจะไม่มีวันเติมแถบความคืบหน้าให้สมบูรณ์

ช่วงเวลาต่าง ๆ ของเดือนและปีอธิกสุรทิน

เดือนที่แตกต่างกันมีจำนวนวันแตกต่างกันและผลลัพธ์จะต้องสะท้อนถึงสิ่งนี้รวมถึงปีอธิกสุรทิน แถบความคืบหน้าสำหรับ 6 กุมภาพันธ์ 2017 จะแตกต่างจากแถบความคืบหน้าสำหรับ 6 กุมภาพันธ์ 2016 (หรือ 6 มกราคมของทั้งสองปี)

เบ็ดเตล็ด

  • เวลาเดินทางใช้ปฏิทินเกรโกเรียน TL; DR: ไม่มีกรณีพิเศษเช่นที่ขาดหายไปในวันที่ 1752 ข้อมูลที่ป้อนจะรวมวันที่ในปี 0 AD
  • นักเดินทางข้ามเวลาไม่สนใจการประหยัดเวลากลางวัน
  • โปรแกรมไม่จำเป็นต้องมีบัญชีสำหรับเผ่นวินาที แต่มันอาจ

เอาท์พุต

โปรแกรม (หรือฟังก์ชั่น) จะต้องพิมพ์ (หรือส่งคืนเป็นสตริง) แถบความคืบหน้า 20 ตัวอักขระในแนวนอนที่ "กรอก" เป็นเวลาที่ผ่านไปและ "เปิด" เป็นเวลาที่เหลืออยู่ จะต้อง "กรอก" จากซ้ายไปขวา

แถบความคืบหน้าจะต้องมีป้ายกำกับทางด้านซ้ายแสดงจุดเริ่มต้นของช่วงเวลาที่ถูกนับและอีกแถบทางด้านขวาแสดงจุดเริ่มต้นของช่วงเวลาถัดไปในรูปแบบเดียวกับอินพุต (แต่แสดงความแม่นยำเพียงสองหน่วย) สำหรับตัวอย่าง2016-12-14ผลลัพธ์ที่ถูกต้องของเราคือ:

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

นี่คือรูปแบบฉลากที่ถูกต้องสำหรับแต่ละช่วงเวลาที่เป็นไปได้:

  • เดือน: YYYY-MM
  • วันที่: MM-DD
  • ชั่วโมง: DDThh
  • นาที: hh:mm
  • วินาที: mm:ss
  • มิลลิวินาที: ss.sss

ไม่มีหน่วยเพิ่มเติมที่จะรวมอยู่ในฉลากและอาจไม่มีการละเว้น

บันทึกการส่งออก

  • หน่วย "เติมเต็ม" ของแถบความคืบหน้าจะแสดงเป็น#ตัวละคร "เปิด" -หน่วยจะแสดงโดย
  • จะต้องมีหนึ่งช่องว่างระหว่างแถบความคืบหน้าและแต่ละป้ายกำกับ
  • ช่องว่างนำหน้าหรือต่อท้ายและ / หรือขึ้นบรรทัดใหม่ต่อท้ายได้รับอนุญาต

การชนะ

นี่คือรหัสกอล์ฟรหัสที่สั้นที่สุดในหน่วยไบต์ชนะ ใช้กฎมาตรฐาน ช่องโหว่มาตรฐานต้องห้าม

ตัวอย่าง

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

4
เราต้องกังวลกับการกระโดดครั้งหรือไม่?
Riley

@Riley คำถามที่ดี ไม่
จอร์แดน

2
ฉันถือว่าการประหยัดเวลากลางวันถูกเพิกเฉยเนื่องจากไม่มีแบบฟอร์มมาตรฐานหรือไม่
CAD97

3
@ CAD97 คำถามที่ดี คุณถูก. DST นั้นซับซ้อนมากสำหรับนักท่องกาลเวลาดังนั้นเราจึงเพิกเฉย
Jordan

ตัวอย่าง "1899-12-31T23" ไม่ถูกต้องตามรายการรูปแบบการป้อนข้อมูลที่ให้เหมือนกันสำหรับ "1982-05-15T17" โปรดยืนยันข้อมูลการทดสอบของคุณ
เรือเหาะ

คำตอบ:


4

จาวาสคริปต์, 282 ไบต์

(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

ผ่านการทดสอบทั้งหมด

(
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

ฟังก์ชั่นทดสอบพิมพ์อะไรได้เลยเมื่อผ่านค่าที่ล้มเหลว

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

กรณีทดสอบ:

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

2
ฉันต้องเรียนรู้ภาษาใหม่ให้อยู่ในอันดับต้น ๆ ... มันกระชับมาก!
rexroni

3

Pyth, 213 ไบต์

รหัสแรกของฉันใน pyth! ดูเถิด:

+%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

รหัส pyth ของฉันอิงตามคำตอบแบบหลามก่อนหน้าของฉันอย่างใกล้ชิด นี่คือรุ่นที่ไม่ได้แต่งแต้มพร้อมความคิดเห็น:

"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+*20c-eKb@HlK.5
"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

การทดสอบหลายค่าสามารถทำได้อย่างง่ายดายโดยการวนรอบโค้ดและเพิ่มการขึ้นบรรทัดใหม่ไปยังจุดสิ้นสุด:

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"

จากนั้นฉันวิ่งcat testinput | pyth code.pyth > outputและdiff output testoutput หรือลองออนไลน์


2

Python 2, 371 ไบต์

ความท้าทายนี้ยากอย่างน่าประหลาดใจ! ดูเหมือนว่าฉันจะอายุต่ำกว่า 300 จนกว่าฉันจะจัดรูปแบบสตริงผลลัพธ์

ส่วนที่เจ๋งคือคำตอบของฉันไม่ได้ใช้แพ็คเกจวันที่

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.