Bước nhảy vọt cho giây nhuận!


28

Vì hôm nay đánh dấu dịp bước nhảy vọt thứ 26 từng xảy ra, thử thách của bạn sẽ là đưa ra ngày và giờ của mỗi giây nhảy vọt trong GMT hoặc UTC đã xảy ra cho đến nay, cũng như lần xảy ra hôm nay.

Đầu vào

Không có đầu vào.

Đầu ra

1972-06-30 23:59:60
1972-12-31 23:59:60
1973-12-31 23:59:60
1974-12-31 23:59:60
1975-12-31 23:59:60
1976-12-31 23:59:60
1977-12-31 23:59:60
1978-12-31 23:59:60
1979-12-31 23:59:60
1981-06-30 23:59:60
1982-06-30 23:59:60
1983-06-30 23:59:60
1985-06-30 23:59:60
1987-12-31 23:59:60
1989-12-31 23:59:60
1990-12-31 23:59:60
1992-06-30 23:59:60
1993-06-30 23:59:60
1994-06-30 23:59:60
1995-12-31 23:59:60
1997-06-30 23:59:60
1998-12-31 23:59:60
2005-12-31 23:59:60
2008-12-31 23:59:60
2012-06-30 23:59:60
2015-06-30 23:59:60

Quy tắc

Vì tôi nghi ngờ có nhiều tích hợp cho phép nhảy vọt, tôi sẽ cho phép chúng.

Sơ hở tiêu chuẩn là không được phép.

Mã ngắn nhất sẽ thắng.

Định dạng ngày phải có tháng không đệm và năm có 4 chữ số, cũng như thời gian quân sự và không gian ngăn cách thời gian với ngày. Đặt UTCở cuối là tùy chọn. Sự lựa chọn của bạn về dấu gạch ngang hoặc dấu gạch chéo.

EDIT: Đúng như dự đoán, điều này đã trở thành một thách thức mã hóa. Nếu chỉ mã hóa có thể khắc phục vấn đề nhảy vọt thứ hai, ... thì tất cả mã của chúng tôi sẽ thực tế hơn nhiều. Có lẽ chúng ta cần một số ý tưởng cho những thử thách thú vị hơn với những ứng dụng thực tế?


Là đầu ra cần thiết để có phân phối chính xác, hoặc nó có thể có bất kỳ phân phối nào miễn là có 26 ngày không?
Ismael Miguel

2
@IsmaelMiguel Họ cần theo thứ tự này.
mbomb007

Không có chủ đề, nhưng nhìn vào danh sách, tôi không biết tại sao chúng ta cần ít giây hơn những ngày này so với thế kỷ trước.
Ông Lister

@MrLister Xem bài viết Wikipedia được liên kết. Tôi nghĩ rằng nó có liên quan đến tốc độ quay thay đổi của Trái đất.
mbomb007

Câu trả lời:


25

CJam, 72 70 69 64 byte

26,"~g¼K&Béx¸¦­Ø"240bFbf{<1b2md\1972+'-@6X$4*-'-Z3$" 23:59:60"N}

Hãy thử trực tuyến trong trình thông dịch CJam .

Ý kiến

Chúng tôi bắt đầu bằng cách mã hóa mỗi bước nhảy vọt thứ hai là 2 * (Y - 1972) + D , trong đó D1 nếu xảy ra vào tháng 12 và 0 khác.

Mảng của tất cả các giây nhuận được mã hóa là:

[0 1 3 5 7 9 11 13 15 18 20 22 26 31 35 37 40 42 44 47 50 53 67 73 80 86]

Hãy gọi mảng này L .

Vì mảng theo thứ tự tăng dần, chúng ta có thể lưu trữ các khác biệt liên tiếp thay vì các số thực tế:

[1 2 2 2 2 2 2 2 3 2 2 4 5 4 2 3 2 2 3 3 3 14 6 7 6]

Coi mảng này là các chữ số của một số cơ sở 15, chúng ta có được số nguyên

19238985373462115979359619336

những chữ số trong cơ sở 240 (chuyển thành ký tự) là

~g¼K&Béx¸¦­Ø

26,             e# Push I := [0 ... 25].
"~g¼K&Béx¸¦­Ø"   e# Push the string from above.
240bFb          e# Convert from base 250 to base 15 to push L.
f{              e# For each J in I:
                e#   Push L.
  <             e#   Replace L with L[:J].
  1b            e#   Push the sum S of the integers in L[:J].
  2md           e#   Push (S / 2) and (S % 2).
  \1972+        e#   Add 1972 to (S / 2).
  '-@           e#   Push '-' and rotate (S % 2) on top.
  6X$4*-        e#   Compute (6 - 4 * (S % 2)).
  '-Z           e#   Push '-' and 3.
  3$            e#   Push a copy of (S % 2).
  " 23:59:60"   e#   Push that string.
  N             e#   Push a linefeed.
}

28
Cảm giác đó khi bạn đã tích hợp sẵn gần như hoàn toàn giải quyết vấn đề và tuy nhiên giải pháp thủ công trong CJam lại ngắn hơn.
Alex A.

9
@AlexA. Có một số tích hợp trong Mathicala mà tôi có thể thực hiện lại với số byte ít hơn trong Mathicala .
Martin Ender

@ MartinBüttner: Tàn bạo.
Alex A.

35

R, 78 75 byte

Được xây dựng, bạn nói gì? Tốt...

message(paste(as.Date(.leap.seconds)-1,"23:59:60\n"),"2015-06-30 23:59:60")

R có một biến tự động .leap.secondschứa ngày và thời gian của mỗi lần chèn giây thứ hai, được đưa ra theo giờ địa phương của hệ thống. Kể từ phiên bản R 3.2.0, điều này không bao gồm ngày hôm nay, vì vậy tôi đã thêm nó bằng tay.

Ungolfed + giải thích:

# Convert the datetime values to UTC dates. These will be a day past the
# expected output, so we can subtract 1 to get what we want.
dates <- as.Date(.leap.second) - 1

# Paste the UTC time and a newline onto the end of each date
datetimes <- paste(dates, "23:59:60\n")

# Print each time, including today, on its own line
message(datetimes, "2015-06-30 23:59:60")

Bạn có thể thử trực tuyến !


nếu bạn có thể gán "23:59:60" cho một biến, bạn có thể lưu một số ký tự
Không phải là Charles

1
@NotthatCharles: Tôi đã nghĩ về điều đó, nhưng phương pháp kết hợp chuỗi của R không đủ ngắn gọn để làm cho việc xây dựng ngày và thời gian ngày nay ngắn hơn. Cảm ơn cho đầu vào mặc dù!
Alex A.

24

HTML, 594 byte

1972-06-30 23:59:60<br>1972-12-31 23:59:60<br>1973-12-31 23:59:60<br>1974-12-31 23:59:60<br>1975-12-31 23:59:60<br>1976-12-31 23:59:60<br>1977-12-31 23:59:60<br>1978-12-31 23:59:60<br>1979-12-31 23:59:60<br>1981-06-30 23:59:60<br>1982-06-30 23:59:60<br>1983-06-30 23:59:60<br>1985-06-30 23:59:60<br>1987-12-31 23:59:60<br>1989-12-31 23:59:60<br>1990-12-31 23:59:60<br>1992-06-30 23:59:60<br>1993-06-30 23:59:60<br>1994-06-30 23:59:60<br>1995-12-31 23:59:60<br>1997-06-30 23:59:60<br>1998-12-31 23:59:60<br>2005-12-31 23:59:60<br>2008-12-31 23:59:60<br>2012-06-30 23:59:60<br>2015-06-30 23:59:60

¯ \ _ (ツ) _ /


6
@ Vioz- Câu hỏi này được gắn thẻ phức tạp kolmogorov và vì vậy đây là một câu trả lời hoàn toàn hợp pháp. Không có khả năng chiến thắng mặc dù ...
Chấn thương kỹ thuật số

10
@mlepage Đó là một trong những "sơ hở tiêu chuẩn".
Jacob Raihle

4
@Voitcus lưu trong tệp, mở trong trình duyệt. Đó là workingmã html
edc65

9
@ AntonyD'Andrea Vâng, vậy thì sao? Vailness không được yêu cầu trong các code golfthách thức.
edc65

5
@anatolyg BẠN KHÔNG vui vì [kolmogorov-độ phức tạp]
vijrox

11

C, 160 146 141 140 byte

Lần đầu tiên đăng bài, không chắc chắn "sơ hở tiêu chuẩn" là gì. Tôi có cảnh báo printf tất nhiên.

160 byte:

Ý tưởng ban đầu là mã hóa giây nhuận bằng cách sử dụng hai bit mỗi năm: một cho tháng Sáu và một cho tháng 12. Mã hóa được tiêu thụ một bit tại một thời điểm bởi vòng lặp while. Không có số nguyên 128 bit, vòng lặp while bên ngoài là cần thiết. Phần còn lại là tất cả các sổ sách kế toán và toán học. :-)

int main(){long long X=0x2495288454AAAB,Y=1972,Z=1;while(Y<2000){while(X){if(X&1)printf("%d-%02d-%d 23:59:60\n",Y,6*(2-Z),31-Z);Y+=Z^=1;X>>=1;}X=0x104082000;}}

141 byte:

Áp dụng các mẹo được đề xuất sẽ giảm xuống còn 146 byte. Sau đó, tôi tìm thấy một cách để đơn giản hóa điều kiện bên ngoài (từ Y <2000 đến chỉ Z), đưa nó xuống còn 141 byte. Rất gần với một tweet!

main(Z){long long X=0x2495288454AAAB,Y=1972;while(Z){while(X)X&1?printf("%d-%02d-%d 23:59:60\n",Y,12-6*Z,31-Z):1,Y+=Z^=1,X/=2;X=4362608640;}}

140 byte:

Tôi nhận thấy dấu gạch ngang trong ngày có thể được loại bỏ bằng cách làm cho ngày âm. Không thể làm điều đó với tháng cũng do số 0 trong tháng sáu. Nhưng ít nhất nó phù hợp với một tweet bây giờ!

main(Z){long long X=0x2495288454AAAB,Y=1972;while(Z){while(X)X&1?printf("%d-%02d%d 23:59:60\n",Y,12-6*Z,Z-31):1,Y+=Z^=1,X/=2;X=4362608640;}}

Phiên bản đẹp:

main(Z) {
    long long X = 0x2495288454AAAB, Y = 1972;
    while (Z) {
        while (X)
            X&1 ? printf("%d-%02d%d 23:59:60\n", Y, 12-6*Z, Z-31) : 1,
            Y += Z ^= 1,
            X /= 2;
        X = 4362608640;
    }
}

Phiên bản thưởng:

Tôi đã loại bỏ vòng lặp bên ngoài bằng cách dịch chuyển một số nguyên 64 bit sang một số nguyên khác, nhưng đó là 150 byte, do "dài không dấu" dài; nếu tôi có thể sử dụng cái gì đó như "uint64" thì nó sẽ là 138 byte.

main(Z) {
    unsigned long long Y = 1972, X = 0x2495288454AAAB, W = 8520720;
    while (X)
        X&1 ? printf("%d-%02d-%d 23:59:60\n", Y, 12-6*Z, 31-Z) : 1,
        Y += Z^= 1,
        X = X/2 | (W>>=1)<<63;
}

4
Chào mừng đến với PPCG. "Các sơ hở tiêu chuẩn" đề cập đến bài đăng này , nhưng nói chung nó chỉ có nghĩa là "sử dụng thông thường và không gian lận". :)
Martin Ender

1
Tôi nghĩ rằng sử dụng một forvòng lặp sẽ tiết kiệm một số byte. BTW, int main()-> main(). Bạn có thể thấy điều này rất hữu ích.
Spikatrix

Ngoài ra: X>>=1giống như X/=2, 6*(2-Z)giống như 12-6*Z4362608640ngắn hơn một byte so với 0x104082000. Phía inttrước main()là không cần thiết, và nếu bạn thay đổi main()thành main(Z)thì bạn có thể xóa khai báo Z=1.
squossish ossifrage

Giải pháp thực sự tốt đẹp - một điều khác cần suy nghĩ - bạn có thể thay đổi if(X&1)printf(...);với X&1?printf(...):1;việc tiết kiệm 1 byte
euanjt

và thay vì while(X){...}sử dụng dấu phẩy để bạn có thể xóa dấu ngoặc - while(X)X&1?printf("%d-%02d-%d 23:59:60\n",Y,6*(2-Z),31-Z):1,Y+=Z^=1,X>>=1;lưu thêm 2 byte
euanjt

9

Trăn 3, 91

Sử dụng mã hóa và định dạng chuỗi bằng Sp3000 , nhưng lưu trữ các giá trị trong đối tượng Python 3 byte chứ không phải là số ma thuật.

for n in b'()+-/1357:<>BGKMPRTWZ]kqx~':print('%d-%02d-3%d 23:59:60'%(1952+n/2,n%2*6+6,n%2))

Mã hóa chỉ cần 86 trong số 256 giá trị có thể có của một byte, do đó, một loạt các ký tự có thể in được sử dụng để làm cho nó trông đẹp hơn.


7

Brainfuck, 806

++++++++[>++++++>+++++++>+++++++>++++++>++++++>++++++>+++++++>++++++>++++++>++++++>++++>++++++>++++++>+++++++>+++++++>+++++++>+++++++>+++++++>++++++>+<<<<<<<<<<<<<<<<<<<<-]>+>+>->++>--->>-->--->+++>>>++>+++>++>--->+>++>-->>++[<]>[.>]<[<]>>>>>>+>---->>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>+>-------->>->++++>>>-[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>++[<]>[.>]<[<]>>>>++>>+>---->>>+[<]>[.>]<[<]>>>>++[<]>[.>]<[<]>>>+>---------[<]>[.>]<[<]>>>>++>>->++++>>>-[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+>>+>---->>>+[<]>[.>]<[<]>>>>++>>->++++>>>-[<]>[.>]<[<]>>>>+>>+>---->>>+[<]>[.>]<[<]>+>--------->--------->---[<]>[.>]<[<]>>>>+++[<]>[.>]<[<]>>>+>------>>->++++>>>-[<]>[.>]<[<]>>>>+++[<]>[.>]

Bạn có thể chạy nó trên trình thông dịch trực tuyến này.


6

Python 2, 111 104 byte

n=0x6697f252225354422533333330;y=1972
while n:print'%d-%02d-3%d 23:59:60'%(y,n%2*6+6,n%2);y+=n/2%8;n/=16

Mã hóa cơ sở và mã hóa cơ sở nhiều hơn.


5

GNU sed + ngày: 112

Các bản phân phối Linux phổ biến cũng có sẵn các bước nhảy vọt. Sử dụng GNU sed và ngày:

sed -n 's/^\([0-9]\+\).*/1899-12-31 \1sec/p' /usr/share/zoneinfo/leap-seconds.list|date -f- +"%Y-%m-%d 23:59:60"

GNU sed + ngày: 90

Bảo vệ một vài ký tự bằng cách cắt đường dẫn:

sed -n 's/^\([0-9]\+\).*/1899-12-31 \1sec/p' /u*/s*/z*/leap*|date -f- +'%Y-%m-%d 23:59:60'

GNU sed + ngày được điều chỉnh bởi Toby Speight: 84

Phiên bản golf sâu được đề xuất trong các ý kiến:

sed -nr 's/^([0-9]+).*/date -d "1899-12-31 \1sec" "+%F 23:59:60"/ep' /u*/s*/z*/leap*

Cảm ơn đã dạy tôi nơi để tìm dữ liệu bước nhảy vọt. Thật không may, date(GNU 8.23) của tôi hiển thị những thứ đó là giây đầu tiên của phút tiếp theo. Bạn đang sử dụng những gì hiểu được 60 phút?
Toby Speight

Với coreutils GNU, tôi đã nhận nó xuống đến 76, cạo byte với -rcờ, thay thế datevới những s///esửa đổi, và thay thế %Y-%m-%dbằng %Ftrong date: TZ = UTCsed -nr 's/^([0-9]+).*/date -d "1900-1-1 \1sec" "+%F %T"/ep' /u*/s*/z*/leap*
Toby Speight

Tôi biết tôi đã bỏ lỡ một cái gì đó. Có vẻ như không có cách nào để chỉ định điều này bằng tay, ít nhất là không tệ hơn hầu hết các giải pháp khác. Chúng ta hãy xem liệu ai đó nghĩ ra một số thư viện ngày để tìm hiểu những con số hỗ trợ chính xác những giây đó.
Jens Erat

Tôi đã đến đó bằng cách sử dụng 1899-12-31 \1seccho buổi hẹn hò và mã hóa 23:59:60theo thời gian:sed -nr 's/^([0-9]+).*/date -d "1899-12-31 \1sec" "+%F 23:59:60"/ep' /u*/s*/z*/leap*
Toby Speight

3

JavaScript ( ES6 ) 125

Dòng mới bên trong `` có ý nghĩa và được tính.

Để kiểm tra, hãy chạy đoạn trích bên dưới (chỉ là EcmaScript 6, chỉ dành cho Firefox)

alert([..."09:;=DEFIX[01234567?ABGJQS"].map((c,i)=>c.charCodeAt()+1924+(i>10?'-12-31':'-06-30')+' 23:59:60').sort().join`
`)


2

PHP, 198 byte

foreach([.5,1,2,3,4,5,6,7,8,9.5,10.5,11.5,13.5,16,18,19,20.5,21.5,22.5,24,25.5,27,34,37,40.5,43.5] as$d){$h=(int)$d-ceil($d);echo date("Y-m-d 23:59:60",mktime(0,0,0,-6*$h,31+$h,(int)$d+1972))."\n";}

Thật không may, tôi không biết nếu tôi có thể chèn \nvào chức năng ngày. Nếu vậy, đây là 3 byte ít hơn vì ."".


Bạn có thể tước cả hai (int)và loại bỏ một số khoảng trắng. Ngày ném một lỗi, nếu múi giờ mặc định không được đặt, hãy tắt tiếng với @. 187 byte:foreach([.5,1,2,3,4,5,6,7,8,9.5,10.5,11.5,13.5,16,18,19,20.5,21.5,22.5,24,25.5,27,34,37,40.5,43.5]as$d){$h=$d-ceil($d);echo@date("Y-m-d 23:59:60",mktime(0,0,0,-6*$h,31+$h,$d+1972))."\n";}
Octfx

2

Mã máy 8086 + DOS, 92 byte

Mã thập phân của mã:

BE 3A 01 B1 57 D1 E0 75 03 AD EB F9 72 09 50 BA
47 01 B4 09 CD 21 58 BB 50 01 81 77 FC 01 04 80
37 01 80 3F 31 74 10 83 EB 05 4B FE 07 80 3F 3A
75 05 C6 07 30 EB F3 E2 CC C3 AA 2A 77 B5 6A DD
DF B6 BE FF 7D BF 31 39 37 32 2D 30 36 2D 33 30
20 32 33 3A 35 39 3A 36 30 0D 0A 24

Để chạy, hãy viết 92 byte vào comtệp -file và chạy trong Windows 32 bit hoặc DOSBox.

Mã này sử dụng một bitmap với 87 bit, mỗi nửa năm một lần. Các bit được sắp xếp thành các nhóm 16, bắt đầu từ MSB.

Giải mã bitmap:

                 ; when the program starts, ax=0 (tested on DOSBox)
myloop:
    shl ax, 1    ; shift the MSB left into the carry flag
    jnz mywork   ; if some bits are left in the register, work normally
    lodsw        ; if all bits were shifted out, load the next 16 bits
    jmp myloop   ; and check the MSB again

Do cấu trúc của mã, một số bit bị mất trong quá trình giải mã, vì vậy tôi phải lặp lại chúng. Việc lặp lại này không làm phình to bitmap vì dù sao tôi cũng phải đệm 87 bit đến 96 bit.

Sau khi in (hoặc không in) bước nhảy vọt thứ hai, mã sẽ tăng ngày thêm nửa năm, sử dụng các thao tác trên mã ASCII của thông điệp đầu ra.

Mã nguồn (có thể được lắp ráp với tasm):

    mov si, offset mydata
    mov cl, 57h ; number of iterations

myloop:
    shl ax, 1   ; shift the MSB left into the carry flag
    jnz mywork  ; if some bits are left in the register, work normally
    lodsw       ; if all bits were shifted out, load the next 16 bits
    jmp myloop  ; and check the MSB again
mywork:
    jc myinc_date ; shifted bit 1? - skip printing the message

    push ax
    mov dx, offset mymsg
    mov ah, 9
    int 21h     ; print the message
    pop ax

myinc_date:
    mov bx, offset mymsg + 9 ; pointer to the middle of the message
    xor word ptr [bx - 4], 401h ; change month 06<->12
    xor byte ptr [bx], 1 ; change day 30<->31
    cmp byte ptr [bx], '1'
    je myloop_end ; if 31 December, no need to increase the year
    sub bx, 5 ; pointer beyond the last digit of the year

myinc_year:
    dec bx
    inc byte ptr [bx] ; increase the digit
    cmp byte ptr [bx], '0' + 10
    jne myloop_end ; if the digit was less than 9, done
    mov byte ptr [bx], '0' ; set the digit to 0
    jmp myinc_year ; continue increasing other digits

myloop_end:
    loop myloop
    ret ; terminate the program

; In the following bitmap, the spaces before some LSBs
; show that the least significant 1-bit and all
; following 0-bits are lost during decoding.
mydata:
    dw 02aaah ; 00101010101010     10
    dw 0b577h ; 101101010111011    1
    dw 0dd6ah ; 11011101011010     10
    dw 0b6dfh ; 101101101101111    1
    dw 0ffbeh ; 11111111101111     10
    dw 0bf7dh ; 101111110111110    1

mymsg:
    db '1972-06-30 23:59:60',13,10,'$'

Tôi muốn kiểm tra điều này, nhưng dường như tôi không thể tìm thấy một trình soạn thảo nào ở bất cứ đâu cho phép bạn dán hex và lưu nó vào một tệp nhị phân.
Ông Lister

@MrLister bất kỳ trình soạn thảo hex bình thường nào cũng nên làm điều đó cho bạn.
TheDoctor

1

Pyth - 88 84 byte

Chuyển đổi thành char để nén dữ liệu và lưu dữ liệu 06-30so với 12-31dữ liệu dưới dạng số nhị phân.

jbm++-2047ed?"-06-30"hd"-12-31"" 23:59:60"C,j33678243 2CM"KKJIHGFEDBA@><:9765421*'# 

(có một khoảng trống ở cuối)

Hãy thử nó ở đây trực tuyến .


1

Trăn 2, 123 121 116 114 111

Tôi đã xoay sở để có được nó khá ngắn, nhưng tôi không chắc nó có thể ngắn hơn bao nhiêu. Tôi đã thử sử dụng exec, nhưng định dạng trở nên quá tốn kém.

Tôi đã sử dụng mã hóa cơ sở 16 của bảng từ trang Wikipedia được liên kết.

Chỉnh sửa: Sử dụng mã hóa hex ngắn hơn cơ sở 36 (xem phiên bản ít chơi hơn.)

Hãy thử nó ở đây

n=0x410208002495288454aaab
for i in range(88):
    if n%2:print"%d-%02d-3%d 23:59:60"%(1972+i/2,i%2*6+6,i%2)
    n/=2

Ít chơi gôn hơn:

s=bin(int('WELD24ZDGIMBWWLFM',36))[2:]
for i in range(44):
    t,s=int(s[0]),s[1:]
    if t:print"%d-06-30 23:59:60"%(i+1972)
    t,s=int(s[0]),s[1:]
    if t:print"%d-12-31 23:59:60"%(i+1972)

1

C, 155 149 147 byte

Đây là một cách tiếp cận khác trong C, sử dụng chuỗi và chạy mã hóa độ dài. Không hoàn toàn ngắn gọn như giải pháp C khác của tôi, nhưng có lẽ nó có thể được cải thiện?

155 byte:

Sử dụng một chuỗi để giữ tháng / ngày.

main(Y){Y=1972;char*M="06-3012-31",*B="#@DGCDF7D3daTdS#!",b,c;while(b=*B++-33){c=b>>1&7;while(c--)printf("%d-%.5s 23:59:60\n",Y++,M+b%2*5);Y+=(b>>4&7)-1;}}

149 byte:

Loại bỏ chuỗi tháng / ngày.

main(Y){Y=1972;char*B="#@DGCDF7D3daTdS#!",b,c;while(b=*B++-33){c=b>>1&7;while(c--)printf("%d-%02d-%d 23:59:60\n",Y++,6+b%2*6,30+b%2);Y+=(b>>4&7)-1;}}

147 byte:

Loại bỏ việc khởi tạo năm.

main(Y){char*B="#@DGCDF7D3daTdS#!",b,c;while(b=*B++-33){c=b>>1&7;while(c--)printf("%d-%02d-%d 23:59:60\n",1971+Y++,6+b%2*6,30+b%2);Y+=(b>>4&7)-1;}}

144 byte:

Nếu tôi mã hóa lại bộ đệm để áp dụng số lần bỏ qua trước (không phải sau), thì tôi có thể sắp xếp lại các câu lệnh trong vòng lặp while, sử dụng toán tử dấu phẩy và loại bỏ dấu ngoặc, tiết kiệm 2 byte.

Tôi có thể lưu một byte khác bằng cách làm cho ngày âm (như trong giải pháp khác của tôi).

Đẹp:

main(Y) {
    char *B = "#@DGCDF7D3daTdS#!", // buffer of bytes encoding runs
         b, // current byte
         c; // current count
    while (b = *B++-33) { // get byte
        c = b>>1&7; // get count
        while (c--) printf("%d-%02d-%d 23:59:60\n", 1971+Y++, 6+b%2*6, 30+b%2); // run
        Y += (b>>4&7)-1; // skip years
    }
}

Giải trình:

Các lần chạy được mã hóa theo byte. Mỗi byte có một bit để cho biết đó là tháng 6 hay tháng 12, 3 bit cho số đếm độ dài, 3 bit cho số lần bỏ qua và 1 bit cao không sử dụng.

Số lần bỏ qua là số năm để bỏ qua sau khi chạy; nó được bù bằng -1 để cho phép hai giây nhảy vọt vào năm 1972. Độ dài là bao nhiêu năm trong một lần chạy; nó có thể có thể được bù bằng +1 nhưng hiện tại thì không.

Vì vậy, một byte có nghĩa là: "Làm LENGTH năm của JUNE (hoặc THÁNG 12) năm nhuận, sau đó bỏ qua SKIP-1 năm" trước khi chuyển sang byte tiếp theo.

Các byte được bù bởi 33 để làm cho chúng có thể đọc được và tránh mã hóa ưa thích.

Điều này có nghĩa là mặc dù chúng tôi có đủ số bit bỏ qua để bao gồm các năm 1998-2005, chúng tôi nằm ngoài phạm vi ASCII, vì vậy chúng tôi có thêm một độ dài bằng không. Ngoài ra, năm 1979 xuất hiện một mình vì chiều dài 1972-1979 là quá dài.

Có đủ bit trong byte, vì vậy những vấn đề đó cuối cùng có thể khắc phục được.


1

q / kdb +, 95 94 93 byte

asc 1_" "0:([]raze("DEFGHIJKSUV[^eh";"DMNOQXYZ]lo"){("d"$"m"$-12*95-6h$x)-y}'1 185;`23:59:60)

Giải trình

Đối với mỗi năm + 1 , mã hóa cho các năm kể từ năm 1905 dưới dạng ký tự ASCII, ví dụ:

1972 -> 1973 -> 68 -> D

6h$xlần lượt "D"trở lại để 68. Vì qkỷ nguyên ngày là 2000.01.01, chúng tôi trừ 95và thực hiện chuyển đổi số nguyên thành ngày "d"$"m"$-12*95-6h$x.

Lý do chúng tôi + 1 ở trên là để trừ đi số ngày kể từ đầu năm tới để có được năm thực tế là 31 tháng 12 hoặc 30 tháng 6, cụ thể là 1 hoặc 185 ngày. Do đó, "DEFGHIJKSUV[^eh"đại diện cho những năm có bước nhảy vọt thứ hai vào tháng 12 và "DMNOQXYZ]lo"cho những năm tháng sáu. Phép trừ ghép được thực hiện thông qua (a;b){x-y}'(c;d), ở đâu ablà năm sẽ được trừ theo cdsố ngày tương ứng.

" "0:([]...)chuẩn bị các kết quả để cung cấp cho chúng tôi định dạng chính xác, với một cảnh báo nhỏ rằng tiêu đề cột sẽ được tạo. 1_bỏ tiêu đề đó và cuối cùng áp dụng ascđể có được thứ tự chính xác.

chỉnh sửa : 'tái cơ sở' để trừ 95 năm thay vì 100 (lưu 1 ký tự).

chỉnh sửa 2 : sắp xếp lại vị trí của toán hạng bên trong hàm chuyển đổi số nguyên.


1

Con trăn, 204 201

e,g,h=0,1972,0
for i in range(1,27):e,g,h={2:1,9:2,10:1,12:2,15:1,16:2,17:1,20:2,21:1,22:7,23:3,24:4,25:3}.get(i,e),g+e,(h,1-h)[i in[2,10,14,17,20,21,22,25]];print`g`+("-06-30","-12-31")[h]+" 23:59:60"

Bạn có thể chơi với nó trên repl.it .

Chỉnh sửa: Đánh kỹ! Các câu trả lời nén là ngắn đáng kinh ngạc.


Đáng ngạc nhiên, PHP anwser của tôi ngắn hơn, sử dụng thuật toán tương tự. Tôi đã luôn mong đợi Python nhỏ gọn hơn. Có lẽ bạn có thể chơi nó nhiều hơn một chút?
Voitcus

Tôi sẽ xem qua một chút. Tôi nghĩ rằng tuyến đường tốt nhất là nén, và những người khác đã thực hiện điều đó
sudo rm -rf chém

0

PHP, 164 byte

foreach([.5,1,2,3,4,5,6,7,8,9.5,10.5,11.5,13.5,16,18,19,20.5,21.5,22.5,24,25.5,27,34,37,40.5,43.5]as$d){echo(ceil($d)+1971).($d%2?'-12-31':'-06-30')." 23:59:60\n";}

Đây chỉ là một vài sửa đổi về ý tưởng của @ Voitcus


0

Con trăn, 221 217

def d(x):
 q=x%10
 if x%2==0:
  p,r=q/2,"06-30"
 else:
  p,r=(q-1)/2,"12-31"
 return"%d%d-%s 23:59:60"%(p+197,x/10,r)
for x in [20,21,31,41,51,61,71,81,91,12,22,32,52,73,93,5,24,34,44,55,74,85,57,87,28,58]:print(d(x))

Một số thông tin chi tiết

Về cơ bản, d(x)giải nén một vectơ gồm 3 số nguyên từ một số nguyên 2 chữ số duy nhất. d(x)được xây dựng dưới dạng hàm nghịch đảo (trong khoảng thời gian 26 giây nhuận) c(v), lần lượt là hàm nén biến 3 cấp như (1998,12,31) thành một số như 85. Để lấy danh sách [20 , 21 ... 28,58] Tôi đã thiết kế một thuật toán khác để xác minh rằng hàm nén là tính từ trên miền. Đó là, tôi đã đảm bảo rằng chương trình sau không tạo ra các bản sao và tôi đã sử dụng đầu ra của nó làm danh sách chương trình ở trên.

dates = [(1972,06,30),
    (1972,12,31),
    (1973,12,31),
    (1974,12,31),
    (1975,12,31),
    (1976,12,31),
    (1977,12,31),
    (1978,12,31),
    (1979,12,31),
    (1981,06,30),
    (1982,06,30),
    (1983,06,30),
    (1985,06,30),
    (1987,12,31),
    (1989,12,31),
    (1990,12,31),
    (1992,06,30),
    (1993,06,30),
    (1994,06,30),
    (1995,12,31),
    (1997,06,30),
    (1998,12,31),
    (2005,12,31),
    (2008,12,31),
    (2012,06,30),
    (2015,06,30)]

def c(v):
    x = (v[0] % 10) * 10
    x += v[2] % 30
    x += 2 * (int(v[0] / 10) - 197)
    return x

for v in dates:
    print(c(v))

Hàm nén c(v)được thiết kế để mô phỏng bằng cách sử dụng sơ đồ rất đơn giản. Hãy lấy một ví dụ (1998,12,31).

  • Biểu thức (v [0]% 10) * 10 chọn các đơn vị của năm (ví dụ 1 9 9 8 -> 8) và biến nó thành chữ số thứ mười của đầu ra (bây giờ x = 80).
  • Chỉ có sự kết hợp hai tháng ngày trong đó điều thứ hai nhảy vọt xảy ra, vì vậy tôi quyết định sử dụng thành phần ngày để phân biệt giữa trường hợp 06,30 và trường hợp 12,31. Biểu thức v [2]% 30 là 0 nếu ngày là 30 và là 1 nếu ngày là 31. Trong ví dụ của chúng tôi, chúng tôi thêm 1 vào x (do đó, bây giờ x = 81).
  • Cuối cùng, tôi quan sát thấy câu đố này chỉ liên quan đến 5 thập kỷ; do đó nếu tôi ánh xạ thập kỷ đầu tiên (những năm bảy mươi) thành 0 và thập kỷ trước (những năm 2010) thành 4 thì tôi có thể làm những thứ tuyệt vời. Cụ thể hơn, nếu thay vì ánh xạ tới 0,1,2,3,4, tôi ánh xạ tới 0,2,4,6,8 Tôi có thể thêm giá trị này vào các đơn vị của x, do quy tắc trước đó là 0 hoặc 1. Vì vậy, cuối cùng chúng ta cũng có bước cuối cùng này không làm hỏng việc và chúng ta nhận ra rằng các đơn vị của trường hợp 06,30 là một trong 0,2,4,6,8 và các đơn vị của một 12,31 trường hợp là một trong 1,3,5,7,9. Do đó, bijection là rõ ràng. Trong ví dụ của chúng tôi, năm 1998 là trong thập kỷ thứ ba (70s-> 0, 80s-> 1, 90s-> 2) vì vậy chúng tôi thêm 2 * 2 = 4. Vậy ta được x = 85.

Tôi đã viết chương trình để xác minh rằng điều này là đúng, và sau đó tôi xác định d(x)là nghịch đảo của c(v). Trong ví dụ của chúng tôi, c ((1998,12,31)) là 85 và d (85) được in chính xác 1998-12-31 23:59:60.


1
Loại bỏ q=x%10và thay thế qvới x%10mọi nơi. Nó ngắn hơn. Tôi cũng đưa ra một mô tả hữu ích về một số môn đánh gôn bổ sung trong chương trình của bạn ở đây . Tôi khuyên bạn nên xem Mẹo chơi gôn trong trang Python .
mbomb007

Đây là môn đánh gôn , vì vậy bạn nên cố gắng rút ngắn độ dài của mã theo bất kỳ cách nào có thể.
mbomb007

-1

gzip, 114 byte

Hexdump:

Một chiều dài của nó

Tạo một tệp với các byte được mô tả ở trên.

Trích xuất bằng gunzip hoặc chương trình giải nén khác để lấy tệp mới có tên "l". Tập tin này chứa đầu ra mong muốn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.