Tìm chủ nhật cuối cùng trong mỗi tháng của một năm nhất định


21

Các giải pháp F # được biết đến bên trong 140 ký tự và đây là vấn đề về Mã Rosetta .

Kết quả bắt buộc trên thiết bị xuất chuẩn hoặc trong một biến chuỗi cho năm đầu vào 2014:

2014-01-26 2014-02-23 2014-03-30 2014-04-27 2014-05-25 2014-06-29 2014-07-27 2014-08-31 2014-09-28 2014-10-26 2014-11-30 2014-12-28

Như đã yêu cầu, cho năm 1900:

1900-01-28 1900-02-25 1900-03-25 1900-04-29 1900-05-27 1900-06-24 1900-07-29 1900-08-26 1900-09-30 1900-10-28 1900-11-25 1900-12-30

Và năm 2000:

2000-01-30 2000-02-27 2000-03-26 2000-04-30 2000-05-28 2000-06-25 2000-07-30 2000-08-27 2000-09-24 2000-10-29 2000-11-26 2000-12-31

Đặt ra vì ngày dường như mang lại sự khó xử trong hầu hết các ngôn ngữ. Hơn cả việc cho phép các thư viện ngày, tôi hy vọng sẽ nhìn thấy chúng! Nhưng nếu bên ngoài ngôn ngữ cơ sở, hãy khai báo bằng tên của bài đăng (ví dụ: NodaTime của C # + Jon Skeet).

Làm rõ:

  • Năm phạm vi 1900 đến 3015
  • Lịch Gregorian
  • Nếu nó có vấn đề khác, bất cứ điều gì là thông thường đối với Vương quốc Anh / Luân Đôn.
  • Một chương trình thực hiện chuyển đổi dòng lệnh hoặc stdin là tốt, tạo ra kết quả cho thiết bị xuất chuẩn
  • Một hàm lấy một giá trị trong năm và trả về một chuỗi cũng tốt.

Tiêu chuẩn loại trừ . Mong các giải pháp APL, J, K và xem một số thư viện ngày mới.


@ Sp3000 - 1752 có thể đặc biệt khó xử :-)
ossifrage squeamish 16/12/14

@ MartinBüttner: Vui lòng sử dụng các thư viện ngày, đã chỉnh sửa câu hỏi để yêu cầu mọi người khai báo những người họ sử dụng với ngôn ngữ.
Phil H

1
Bạn nên chỉ định phạm vi năm là đầu vào hợp lệ và cân nhắc về việc áp dụng Gregorian. (Tức là nếu phạm vi năm bao gồm bất kỳ trước năm 1930 thì bạn nên chỉ định rằng lịch Gregorian nên được sử dụng cho toàn bộ phạm vi, bất kể miền địa phương; hoặc đầu ra có thể thay đổi theo miền địa phương; hoặc bạn nên đưa ra ngày cắt trước đó lịch Julian nên được sử dụng và các trường hợp thử nghiệm trong ba năm xung quanh việc chuyển đổi).
Peter Taylor

1
@squeamishossifrage: Tôi đã giới hạn nó vào năm 1900 và Gregorian, vì tôi muốn tránh một dự án nghiên cứu để thiết lập thông số kỹ thuật ...
Phil H

1
@ Adám: Xin lỗi vì đã khiến bạn chờ đợi quá lâu để trả lời :) Vâng thực sự.
Phil H

Câu trả lời:


1

APL Dyalog với cal từ dfns , 19 byte

Muộn còn hơn không!

Nhắc nhở cho năm, trả về danh sách ngày ở định dạng md yyyy .

⎕{⍺⍵,2↑⊢⌿cal⍺⍵}¨⍳12

nhắc về đầu vào số và để đó là đối số bên trái cho

{... hàm ẩn danh (được tìm thấy bên dưới) được áp dụng cho từng

⍳12 các số từ 1 đến 12 (tháng)

Hàm ẩn danh ở trên như sau:

⍺⍵, đưa ra các đối số trái và phải (tức là năm và tháng) để

2↑ hai nhân vật đầu tiên của

⊢⌿ hàng dưới cùng của

cal lịch cho

⍺⍵ đối số trái và đối số phải (năm và tháng)

Dùng thử trực tuyến:

  1. Quay trở lại trang này sau khi nhấp vào đây để nhập calvà các phụ thuộc của nó.

  2. Nhấn vào đây để chạy các trường hợp thử nghiệm.


Rất tốt. Đã hy vọng cho một thư viện APL hiểu ngày tháng có nghĩa là gì, nhưng cal là hợp lý!
Phil H

@PhilH ngàyngày ?
Adám

1
@PhilH Ngoài ra còn có không gian tên Ngày từ MiServer.
Adám

1
@PhilH Và các nguyên thủy nhuộm của APL + - < = làm việc với các đối tượng ngày .Net .
Adám

7

Hồng ngọc, 91 + 6 = 97

#!ruby -prdate
$_=(Date.new(y=$_.to_i)...Date.new(y+1)).select(&:sunday?).chunk(&:mon).map{|k,v|v[-1]}*' '

Hoạt động khá tốt. select(&:sunday?)là đẹp, và đáng ngạc nhiên, *' 'tất cả các định dạng của chính nó.


Thủ đoạn hay! Bạn có thể lưu thêm ba ký tự bằng cách sử dụng chunkthay vì group_by.
Cristian Lupascu

Vì vậy, tôi có thể, tốt đẹp.
lịch sử

6

Bash 4.x + ncal, 57

Nếu dấu phân cách dòng mới là OK thay vì khoảng trắng, thì chúng ta có thể loại bỏ -nchuyển đổi và dấu cách từ dấu cách echo. Và tôi đoán nó vẫn sẽ hoạt động mà không có shebang, vì vậy tôi cũng loại bỏ nó:

for i in {01..12};{ echo "$1-$i-`ncal $i $1|tail -c-3`";}

Tập lệnh gốc (73 byte):

#!/bin/bash
for i in {01..12};{ echo -n "$1-$i-`ncal $i $1|tail -c-3` ";}

Sử dụng:

$ bash sundays.sh 2014
2014-01-26
2014-02-23
2014-03-30
2014-04-27
2014-05-25
2014-06-29
2014-07-27
2014-08-31
2014-09-28
2014-10-26
2014-11-30
2014-12-28
$

Lưu ý: Các phiên bản Bash trước 4.0 sẽ bỏ qua các số 0 đứng đầu trong các tháng. Điều này có thể được sửa chữa bằng việc thêm 5 ký tự bằng cách thay đổi {01..12}thành `seq -w 1 12)`. Ngoài ra, tail -c-3có thể gây ra sự cố trên một số hệ thống trong đó đầu ra ncalbao gồm các khoảng trắng ở cuối, nhưng tôi không biết bất kỳ hệ thống nào.


1
Sự khác biệt có thực sự liên quan đến Darwin, không chỉ là phiên bản Bash? Đã được thêm vào Bash 4.0 (mặc dù có một số lỗi trong đó sau). Dù sao, 1 nhân vật vẫn có thể được tha bằng cách sử dụng `…`thay vì thói quen tốt $(…).
manatwork 16/12/14

À, có thể. Darwin nói rằng nó sử dụng phiên bản 3.2.53; Debian đang sử dụng 4.1.5.
squossish ossifrage

@manatwork PS Chỉ cần chú ý bình luận của bạn về back-tick. Bắt tốt, cảm ơn!
squossish ossifrage

Tôi không nghĩ bạn cần tính #!/bin/bashcác mục đích của việc chơi gôn.
Chấn thương kỹ thuật số

@DigitalTrauma Điều đó thật tốt. Có vẻ như tôi có thể sử dụng ngắt dòng thay vì khoảng trắng. Xuống tới 57 byte ngay bây giờ :-)
ossifrage squeamish 17/12/14

6

IBM DFSORT, 11 3 dòng 71, 72 hoặc 80 ký tự

 OPTION COPY 
 OUTFIL REPEAT=12,OVERLAY=(5:SEQNUM,2,ZD,5,2,1,8,Y4T,LASTDAYM,TOJUL=Y4T*
 ,9,7,Y4T,ADDDAYS,+1,TOJUL=Y4T,1:16,7,Y4T,PREVDSUN,TOGREG=Y4T(-),12X) 

Hai câu trả lời với định dạng đầu ra cột đã đứng trước thử thách của thời gian. Điều đó mang lại cho tôi một "vòng lặp", loại, trong đó trên OUTFIL REPEAT = sao chép bản ghi hiện tại nhiều lần.

Kỹ thuật khác nhau để đạt được giá trị, có vẻ dài hơn nhưng ngắn hơn vì tôi không thể tìm ra bất kỳ cách vô điều kiện nào để xử lý bản ghi thứ 12 trong năm sau và biến nó thành phương tiện có điều kiện bao gồm IFTHEN=(WHEN=, hai lần và một số nội dung khác. Đạt được sự thay đổi (đầu tháng là cách đơn giản nhất để làm điều đó) mất rất nhiều trên các vòng xuyến (yêu cầu cú pháp cụ thể).

Điều này sử dụng chức năng sẵn có (tất cả các chức năng trong DFSORT đều có sẵn) để tìm ngày cuối cùng của tháng. Sau đó thêm một ngày (chức năng) để đến đầu tháng sau và sử dụng chức năng PREVDSUN để lấy Chủ nhật trước đó (sẽ luôn là Chủ nhật cuối cùng của tháng trước, như trước).

Khi biến năm (đầu vào) thành một ngày hợp lệ, số thứ tự hai chữ số được sử dụng cho tháng và giá trị đó cũng được sao chép cho cả ngày, vì điểm bắt đầu không quan trọng miễn là hợp lệ, như chúng ta sau ngày cuối cùng của tháng đầu tiên: 5,2ngắn hơn C'01'.

Đây là chi tiết:

TÙY CHỌN SAO CHÉP - sao chép tệp đầu vào vào đầu ra

OUTFIL - để cho phép nhiều tệp đầu ra, với lựa chọn và định dạng khác nhau, tạo báo cáo được định dạng. Được sử dụng trong sở thích ngắn hơn INRECvì sử dụng REPEAT=.

REPEAT = 12 - tạo ra 12 bản sao của mỗi bản ghi. Trong ví dụ này, chỉ có thể có một bản ghi đầu vào (không giống như phiên bản trước) vì SEQNUM.

5: - bắt đầu từ cột 5 trong hồ sơ.

SEQNUM, 2, ZD - số thứ tự, mặc định bắt đầu ở một, hai chữ số, "thập phân được khoanh vùng" (đối với dấu không dấu, chúng sẽ giống như ký tự).

1,8 - sao chép byte 1 cho chiều dài 8 đến vị trí hiện tại (9). Điều này là do Y4T cần phải xem 8, nếu không, một định dạng ngày khác sẽ được sử dụng.

Y4T - ngày định dạng ccyymmdd (do số 8 ngay trước nó).

LASTDAYM - Ngày cuối cùng của tháng (cũng có thể là Tuần, Quý và Năm).

TOJUL = - chuyển đổi ngày đầu ra cho các hàm ngày (TOJUL là một ký tự nhỏ hơn TOGREG)

9,7 - bây giờ là 7, Y4T sẽ là CCYYDĐD.

ĐỊA CHỈ - thêm một số ngày, tự động điều chỉnh nếu đi vào tháng / năm tiếp theo (cũng có thể là ĐỊA CHỈ và THÊM)

PREVDSUN - ngày Julian đến, Chủ nhật trước được đặt, TOGREG để có được định dạng đầu ra chính xác, với bộ tách biệt "-" (có thể là bất cứ thứ gì bạn thích làm dấu phân cách)

12X - khoảng trống để dọn dẹp mớ hỗn độn đã cho phép chúng tôi làm điều đó một cách ngắn gọn như vậy

Đầu ra từ năm 2014, là:

2014-01-26
2014-02-23
2014-03-30
2014-04-27
2014-05-25
2014-06-29
2014-07-27
2014-08-31
2014-09-28
2014-10-26
2014-11-23
2014-12-28

Một cái gì đó được yêu cầu để nói với SORT phải làm gì. Không có mặc định. OPTION COPYlà ngắn nhất, SORT FIELDS=COPYtương đương nhưng dài hơn.

Bản thân công việc được thực hiện lần này OUTFIL(để cho phép sử dụng REPEAT). Mã làm việc được cho là bất kỳ 160 (2 * 80), 144 (2 * 72), 140 (72 + 69) hoặc 138 (70 + 68) (không bao gồm các khoảng trống hàng đầu, tiếp tục bắt buộc và khoảng trống theo sau).

Cho rằng người nhận sẽ phải biết họ đang làm gì, tôi nghĩ rằng tôi có thể nói rằng mã DFSORT để liệt kê Chủ nhật cuối cùng của mỗi tháng cho bất kỳ năm nào từ năm 1900 (sẽ chạy từ năm 0001, nhưng tôi tránh nghiên cứu như tốt) lên đến 9999 (mặc dù DFSORT hỗ trợ số năm lên tới 9999, giải pháp trước đó sẽ không hoạt động vào năm 9999 kể từ ngày thứ 12 đi vào năm sau) có thể được Tweet.

Tại sao mã quá dài, nếu có các hàm inbuilt đặc biệt?

Định nghĩa trường là phù du. Một trường chỉ được xác định là một vị trí cụ thể trong dữ liệu (là bản ghi) để sử dụng ngay lập tức. Nói cách khác, các trường không được xác định như vậy, nhưng được xác định cho mỗi lần sử dụng và chỉ để sử dụng. Các hàm ngày cần phải biết (trong số nhiều) định dạng ngày được sử dụng cho nguồn và đầu ra phải ở định dạng ngày, do đó phải được chỉ định.

Bây giờ chúng ta có một ngày Julian .... TBC?


 OPTION COPY 
 INREC OVERLAY=(1,4,C'0201',1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8*
 ,94:C'1',89:1,4,ZD,ADD,+1,ZD,LENGTH=4,14:C'3',22:C'4',30:C'5',38:C'6',*
 46:C'7',54:C'8',62:C'9',69:C'10',77:C'11',85:C'12',127:X,89,8,Y4T,PREV*
 DSUN,TOGREG=Y4T(-),116:X,81,8,Y4T,PREVDSUN,TOGREG=Y4T(-),105:X,73,8,Y4*
 T,PREVDSUN,TOGREG=Y4T(-),94:X,65,8,Y4T,PREVDSUN,TOGREG=Y4T(-),83:X,57,*
 8,Y4T,PREVDSUN,TOGREG=Y4T(-),72:X,49,8,Y4T,PREVDSUN,TOGREG=Y4T(-),61:X*
 ,41,8,Y4T,PREVDSUN,TOGREG=Y4T(-),50:X,33,8,Y4T,PREVDSUN,TOGREG=Y4T(-),*
 39:X,25,8,Y4T,PREVDSUN,TOGREG=Y4T(-),28:X,17,8,Y4T,PREVDSUN,TOGREG=Y4T*
 (-),17:X,09,8,Y4T,PREVDSUN,TOGREG=Y4T(-),1:1,8,Y4T,PREVDSUN,TOGREG=Y4T*
 (-),11:X,18,120,6X) 

Cần một số JCL

//LASTSUNG EXEC PGM=SORT 
//SYSOUT   DD SYSOUT=* 
//SORTOUT  DD SYSOUT=* 
//SYSIN    DD * 

Và một tệp đầu vào (một dòng khác của JCL và ba mục dữ liệu trong luồng):

//SORTIN DD *
2014 
1900 
2000 

Sản xuất:

2014-01-26 2014-02-23 2014-03-30 2014-04-27 2014-05-25 2014-06-29 2014-07-27 2014-08-31 2014-09-28 2014-10-26 2014-11-30 2014-12-28
1900-01-28 1900-02-25 1900-03-25 1900-04-29 1900-05-27 1900-06-24 1900-07-29 1900-08-26 1900-09-30 1900-10-28 1900-11-25 1900-12-30
2000-01-30 2000-02-27 2000-03-26 2000-04-30 2000-05-28 2000-06-25 2000-07-30 2000-08-27 2000-09-24 2000-10-29 2000-11-26 2000-12-31

Sẽ thực sự hoạt động đến năm 9999.

DFSORT là sản phẩm sắp xếp Mainframe của IBM. Dữ liệu có thể bị thao túng, nhưng vì việc sắp xếp là chính và các loại thường lớn và lâu dài, thẻ điều khiển DFSORT không có cấu trúc lặp, vì vậy chúng ta không thể đặt SORT vào một vòng lặp. Làm cho mọi thứ hơi dài dòng cho các nhiệm vụ như Golf.

Tại sao để đăng câu trả lời, là vì DFSORT có PREVDdaychức năng. Vì vậy, chủ nhật tuần trước trong một tháng thật dễ dàng. Hôm nay là Chủ nhật (PREVDSUN) đến ngày đầu tiên của tháng tiếp theo.

Thật thú vị khi thực hiện nó trong một "toán hạng" (TỔNG QUAN), giống như thực hiện tất cả trong sprintfhoặc tương tự.

Đây là vô căn cứ:

 OPTION COPY 

 INREC OVERLAY=(1,4,C'0201',1,8,1,8,1,8,1,8,1,8,1,8, 
         1,8,1,8,1,8,1,8, 
         1,8,94:C'1',89:1,4,ZD,ADD,+1,ZD,LENGTH=4, 
         14:C'3',22:C'4',30:C'5',38:C'6',46:C'7',54:C'8',
         62:C'9',69:C'10',77:C'11',85:C'12', 
        127:X,89,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
        116:X,81,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
        105:X,73,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         94:X,65,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         83:X,57,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         72:X,49,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         61:X,41,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         50:X,33,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         39:X,25,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         28:X,17,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         17:X,09,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
          1:1,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         11:X,18,120,6X) 

Mặc dù không hoàn toàn lạm dụng, nhưng thông thường sẽ cố gắng nhồi nhét tất cả những thứ này vào một LƯỢT, và có một số thứ dường như không cần thiết để cho phép tất cả đi vào một LƯỢT. Có một số chỗ để chơi gôn, nhưng vì nó sẽ chỉ loại bỏ tối đa một dòng, tôi không bị cám dỗ.

INREC được xử lý cho mỗi hồ sơ.

TỔNG QUAN cho phép thay đổi nội dung của một bản ghi hiện có. Nếu bản ghi được mở rộng vượt quá độ dài của nó trong quá trình, đó không phải là vấn đề.

1,4 là năm sắp tới. Nó có một chữ là 0201 được thêm vào, và sau đó 1,8 giây liên tiếp lặp lại 11 lần để tạo ra một mâm cặp dài 96 byte,

Năm thứ 12 trong hồ sơ hiện tại mở rộng được thêm 1 vào đó và tháng được thực hiện thành 1 (tháng 1).

10 tháng còn lại được đổi thành 3 đến 11.

Sau đó, có 12, theo thứ tự ngược lại (do QUÁ TRÌNH) của loại điều này:

127:X,89,8,Y4T,PREVDSUN,TOGREG=Y4T(-),

Số n: là số cột trong hồ sơ. X chèn một khoảng trống. 89,8 lấy dữ liệu từ cột / độ dài đó, Y4T coi đó là ngày CCYYMMDD, PREVDSUM hoạt động vào Chủ nhật trước đó, TOGREG = Y4T (-) xuất ra dưới dạng ngày CCYY-MM-DD của Gregorian.

Bởi vì bạn nhận được rác nếu nguồn và mục tiêu của một phần cụ thể của TỔNG QUAN chồng chéo lên nhau một cách triệt để, cuối cùng 11:X,18,120,6X)sắp xếp lại và che dấu một chút lộn xộn.

Hướng dẫn và giấy tờ có thể được tìm thấy tại: http://www-01.ibm.com/support/docview.wss?uid=isg3T7000080 , và bao gồm Hướng dẫn lập trình ứng dụng DFSORT hơn 900 trang.

Như với tất cả các sản phẩm của IBM, tất cả các hướng dẫn đều có sẵn miễn phí (ngoại trừ một lượng rất nhỏ những thứ rất đắt tiền mà chỉ một số rất ít người trên thế giới thậm chí còn giả vờ hiểu).

Tất cả các thẻ kiểm soát DFSORT phải bắt đầu bằng một khoảng trống. Cột 72 chỉ được sử dụng để tiếp tục (mọi trường hợp không trống sẽ làm, nhưng * là thông thường). Cột 72 được theo sau bởi một khu vực số thứ tự bị bỏ qua, làm cho mỗi bản ghi 80 byte.

Một vài giải pháp sắp tới, có thể.


5

Bash, 63 byte

for i in {01..12};{  date -v30d -v${i}m  -v2014y  -vsun +%Y-%m-%d;}

Đầu ra:

2014-01-26
2014-02-23
2014-03-30
2014-04-27
2014-05-25
2014-06-29
2014-07-27
2014-08-24
2014-09-28
2014-10-26 
2014-11-30
2014-12-28

for i in {1..12};{ date -v30d -v${i}m -v$1y -v0w +%Y-%m-%d;}- 60 byte
Chấn thương kỹ thuật số

-vparam datelà cụ thể cho ngày BSD. Vì vậy, điều này hoạt động trên OSX, nhưng không phải trên hầu hết Linux - có lẽ điều đó nên được nêu trong câu trả lời.
Chấn thương kỹ thuật số

@DigitalTrauma, hoạt động trên mac và Linux của tôi.
michael501

4

Python 2 - 189 byte

y=input()
for m in range(12):
 d=[31-(1322>>m&1),28+(y%400<1or 1>y%4<y%100)][m==1];Y=y-(m<2);Z=Y%100;C=Y/100
 while(d+13*((m-2)%12+4)/5+Z+Z/4+C/4-2*C)%7-1:d-=1
 print"%d-%02d-%d"%(y,m+1,d),

Nhập ngày qua STDIN.

Vẫn còn rất nhiều chơi golf có thể được thực hiện. Chương trình hơi quá nhiệt tình, chỉ để giải trí:

  • Không nhập, đặc biệt là không sử dụng bất kỳ chức năng ngày tích hợp nào
  • Sử dụng sự phù hợp của Zeller để tính các ngày trong tuần

Ghi chú

  • 1322 là bảng tra cứu ma thuật để xác định xem một tháng không có tháng hai có 30 hay 31 ngày
  • Không zfillcần thiết trong nhiều năm do phạm vi đầu vào, cũng không phải ngày vì chúng sẽ luôn trên 20

Python 2 - 106 byte

Giải pháp không thú vị:

from calendar import*
y=input();m=1
while m<13:w,n=monthrange(y,m);print"%d-%02d-%d"%(y,m,n-(n+w)%7),;m+=1

calendar.monthrangetrả về hai số: ngày trong tuần tháng bắt đầu ( w) và số ngày trong tháng ( n). Giải pháp hơi phản trực giác do bị bắt - ngày trong tuần được trả về bắt đầu từ 0 cho thứ Hai , không phải Chủ nhật! Tuy nhiên, điều này được bù đắp bởi thực tế nlà dựa trên 1.


1
Một câu trả lời Pyth rất ngớ ngẩn:$from calendar import monthrange as gt$V12AGH>QhN%"%d-%02d-%d"(QhN-H%+GH7
FryAmTheEggman

3

JavaScript (ES6) 155 145

Chỉnh sửa Các sự cố múi giờ cố định Có thể ngắn hơn nếu được thực hiện đệ quy. Có lẽ.

F=y=>{
  for(n=i=o=[];!o[11];)
    d=new Date(Date.UTC(y,0,++i)),m=d.getMonth(),
    d.getDay()||(m!=n&&o.push(p.toISOString().slice(0,10)),p=d,n=m);
  return o.join(' ')
}

Bạn có thể sử dụng new Date(y,0,++i,9). Ngoài ra, điều này không thành công trong 2100 năm trở lên vì JS không có thông tin về những năm nhuận đó và do đó, hoàn toàn không có Feb 29trong những năm nhuận từ 2100 trở lên.
Tối ưu hóa

@Optimizer không phải là JS: 2100,2200,2300 không phải là năm nhuận. 2014 là một năm nhuận và JS biết. Đối với việc sử dụng giờ 9, tôi không thể xác minh nhưng tôi nghĩ rằng nó không hoạt động nếu bạn ở Melbourne chẳng hạn ...
edc65

Ah .. Không bao giờ biết chúng tôi giảm 3 ngày trên 400 năm. Khoảng 9 - Tôi đã thay đổi múi giờ của mình từ -1000 (Hawaii) thành +1100 (Melbourne) và new Date(2014,0,26,9)là một ngày Chủ nhật đưa ra ISOchuỗi chính xác cũng getDay()như 0.
Tối ưu hóa

3

JavaScript, ES6, 222 219 199 byte

Tôi không thấy bất kỳ câu trả lời JavaScript nào trong wiki Rosetta.

Ở đây chúng tôi đi:

S=Y=>{for(l=[],p=new Date(Y,i=0);i<365+!(Y%4);)if(!(d=new Date(Y,0,++i,9)).getDay()){p.getMonth()-d.getMonth()&&l.push(p);p=new Date(d)}return[...l,p].map(x=>x.toISOString().split("T")[0]).join(" ")}

Điều này tạo ra một chức năng S trả về một chuỗi với đầu ra mong muốn. chức năng cũng chăm sóc năm nhuận.

Do ES6, điều này chỉ hoạt động trong một Firefox mới nhất.

Cảm ơn apsillers cho mẹo đã giảm xuống còn 200 byte

Tìm phiên bản chưa được chỉnh sửa dưới đây dưới dạng một đoạn trích mà bạn có thể chạy ở đây:

S=Y=>{
  for(l=[],p=new Date(Y,i=0);i<365+!(Y%4);)
    if(!(d=new Date(Y,0,++i,9)).getDay()){
      p.getMonth()-d.getMonth()&&l.push(p);
      p=new Date(d)
    }
  return[...l,p].map(x=>x.toISOString().split("T")[0]).join(" ")
}

alert(S(parseInt(prompt())))


Bạn có thể sử dụng + prompt () thay vì parseInt và tắt một số byte
Jacob

@Jacob Dấu nhắc đó không được thêm vào số byte.
Trình tối ưu hóa

OIC. Tôi nên đọc câu hỏi ...
Jacob

@apsillers Cảm ơn rất nhiều! Đã khắc phục sự cố và giảm nó rất nhiều dựa trên mẹo của bạn.
Trình tối ưu hóa

Đầu vào 2100đầu ra 2100-01-31 2100-02-28 2100-03-28 2100-04-25 2100-05-30 2100-06-27 2100-07-25 2100-08-29 2100-09-26 2100-10-31 2100-11-28 2100-12-26 2101-01-02là sai.
Qwertiy

3

Rebol - 120 116 80 79 76

d: do join"1-1-"input print collect[for m 2 13 1[d/2: m keep d - d/weekday]]


Ungolfed + một số chú thích:

d: do join "1-1-" input         ;; golfy way to create Rebol date! datatype 1-Jan-(year)

print collect [
    for m 2 13 1 [              ;; loop thru months 2 to 13!
        d/2: m                  ;; move to (1st of) next month
        keep d - d/weekday      ;; collect/keep last sunday of month
    ]
]

Ví dụ về tính toán chủ nhật trong bảng điều khiển Rebol:

>> ; get last sunday of Jan 2014

>> d: 1-1-2014
== 1-Jan-2014

>> d/month: d/month + 1
== 2

>> d
== 1-Feb-2014

>> d/weekday
== 6

>> d - d/weekday
== 26-Jan-2014

>> ; above is last sunday of Jan 2014
>> ; and when pass end of year (ie. month 13!)

>> d/month: 13
== 13

>> d
== 1-Jan-2015

Tiềm năng 87: d: 1-1-1 d / năm: thu thập dữ liệu in [lặp lại m 12 [d / tháng: m + 1 giữ d - d / ngày trong tuần]]
rgchris

@rgchris Cảm ơn Chris. Đã có thể cạo thêm 7 ký tự của nó.
Drainegtun

Tốt đẹp!! Thật tệ, nhưng không bao giờ thực sự nghĩ rằng FOR là một lối tắt.
rgchris

2

CJam, 122 102 byte

30li:X400%){[1387Yb30f+~28I!I4%!I100%e&|g+\]W%{\_2$>7*-\7%7\m1$+}/}fI;]12/W=12,{101+s1>}%]z{X+W%'-*S}/

Điều này không sử dụng bất kỳ hình thức thư viện ngày. Nó có thể vẫn còn được chơi golf rất nhiều, tôi nghĩ vậy.

Kiểm tra nó ở đây.


3
Tôi đã rất phấn khích khi một câu trả lời của CJam không phải là câu trả lời hàng đầu trong một thử thách chơi gôn mã một lần. Tôi có thể chết hạnh phúc .. Hôm nay là một ngày tốt lành (rõ ràng cho đến khi nó giảm xuống còn 6 byte)
Brandon

@Brandon: Đó là loại lý do tôi nghĩ nó sẽ thú vị. Thực sự hy vọng để xem một số thư viện tuyệt vời làm cho điều này dễ dàng, nhưng thất vọng cho đến nay.
Phil H

1

R, 128 ký tự

P=paste;f=format;a=strptime(P(1:366,scan()),"%j %Y");cat(sort(sapply(split(a,f(a,"%B")),function(x)P(tail(x[f(x,"%u")==7],1)))))

Với ngắt dòng:

P=paste
f=format
a=strptime(P(1:366,scan()),"%j %Y")
cat(sort(sapply(split(a,f(a,"%B")),function(x)P(tail(x[f(x,"%u")==7],1)))))

1

C # 255

Ung dung

static void Main(string[] a)
    {
        int y = Int32.Parse(Console.ReadLine());
        DateTime d = new DateTime(y, 1, 1);
        while (d.Year == y)
        {
            if (d.DayOfWeek == DayOfWeek.Sunday && d.Day>(DateTime.DaysInMonth(y,d.Month)-7))
                Console.WriteLine(d.ToShortDateString());
            d = d.AddDays(1);
        }
        Console.ReadKey();
    }

Chỉnh sửa: sửa đổi để chỉ in cuối cùng chủ nhật :)


Không phải là định dạng đầu ra cần thiết. + Đây là mã golf
edc65

1

q, 67

{({{1<>x mod 7}-[;1]/x}')14h$1_til[13]+13h$"D"$(($)x),".01.01"}

Không có thư viện ngày có thể sử dụng cho điều này trong q?
Phil H

1

"Ồ, không, anh ta nữa!"

Java - 259 246 byte

void g(int y){for(int i=;i<12;i++){GregorianCalendar c=new GregorianCalendar(y,i,0);c.set(c.DAY_OF_WEEK,c.SUNDAY);c.set(c.DAY_OF_WEEK_IN_MONTH,-1);System.out.print(y+"-"+String.format("%02d",(c.get(c.MONTH)+1))+"-"+(c.get(c.DAY_OF_MONTH))+" ");}}

Phiên bản bị đánh cắp:

void g(int y){
    for (int i = 0; i < 12;i++) {
        GregorianCalendar c = new GregorianCalendar(y, i, 0);
        c.set(c.DAY_OF_WEEK, c.SUNDAY);
        c.set(c.DAY_OF_WEEK_IN_MONTH, -1);
        System.out.print(y+"-"+String.format("%02d",(c.get(c.MONTH)+1))+"-"+(c.get(c.DAY_OF_MONTH))+" ");
    }
}

Sử dụng:

import java.util.GregorianCalendar;
import java.util.Scanner;

public class LastSundayInYear {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("Year?");
        int year = scanner.nextInt();
        LastSundayInYear sunday = new LastSundayInYear();
        sunday.g(year); 
    }

    void g(int y){
        for (int i = -1; ++i < 12;) {
            GregorianCalendar c = new GregorianCalendar(y, i, 0);
            c.set(c.DAY_OF_WEEK, c.SUNDAY);
            c.set(c.DAY_OF_WEEK_IN_MONTH, -1);
            System.out.print(y+"-"+String.format("%02d",(c.get(c.MONTH)+1))+"-"+(c.get(c.DAY_OF_MONTH))+" ");
        }
    }
}

Đầu ra:

2014-01-26 2014-02-23 2014-03-30 2014-04-27 2014-05-25 2014-06-29 2014-07-27 2014-08-31 2014-09-28 2014-10-26 2014-11-30 2014-12-28

Một câu trả lời "hãy đặt câu trả lời Java chỉ cho cú đá". Ồ tốt Nhưng, ít nhất, vì bạn đã bận tâm đến điểm này trong câu trả lời của tôi, tôi sẽ cố gắng làm bạn chán thêm và giải thích lý do của tôi.

Phương thức gnhận được năm mong muốn và, mỗi tháng, tạo ra một GregorianCalendarđối tượng (tháng đi từ 0 đến 11). Sau đó, lần đầu tiên c.setđặt ngày trong tuần là Chủ nhật và lần thứ hai tuyên bố rằng chúng tôi muốn tuần cuối cùng của tháng - như được thấy trong tài liệu chính thức . Các System.out.printlnbản in ra vào ngày Chủ nhật đó (nếu chúng ta làm đúng, năm sẽ được in thành c.get(c.YEAR), nhưng sử dụng ylại để xóa 13 ký tự), tháng phải được định dạng để thêm số 0 đứng đầu từ tháng 1 đến tháng 9 (và giá trị được tăng lên bởi vì, tốt, tháng ở đây được biểu thị 0-11) và ngày Chủ nhật tuần trước được in. Và thủ tục này được lặp lại trong mười một tháng khác.


0

C #, 212 , 237

string x(int y){var s="";var t="";var d=new DateTime(y,1,1);for(;;){if(d.Year!=y){return s;}t=(d.DayOfWeek==DayOfWeek.Sunday)?t=string.Format("{0}-{1}-{2} ",d.Year,d.Month,d.Day):t;s=(d.AddDays(1).Month!=d.Month)?s+=t:s;d=d.AddDays(1);}}

Với ngắt dòng

string x(int y)
    {
        var s = "";
        var t = "";
        var d = new DateTime(y,1,1);
        for (;;)
        {
            if (d.Year != y) {
                return s;
            }
            t = (d.DayOfWeek == DayOfWeek.Sunday) ? t = string.Format("{0}-{1}-{2} ", d.Year, d.Month, d.Day) : t;
            s=(d.AddDays(1).Month!=d.Month)?s+=t:s;
            d=d.AddDays(1);
        }
    }

Đầu ra cho năm 2014

"2015-1-25 2015-2-22 2015-3-29 2015-4-26 2015-5-31 2015-6-28 2015-7-26 2015-8-30 2015-9-27 2015-10-25 2015-11-29 2015-12-27"

Không phải định dạng đầu ra bắt buộc
edc65

Ở đó, cố định. Tốt hơn?
Darren Breen

0

C # 171

Hàm trả về một chuỗi.

string S(int y){var r="";for(int m=1;m<13;++m){var d=new System.DateTime(y,1,1).AddMonths(m).AddDays(-1);r+=y+string.Format("-{0:00}-{1} ",m,d.Day-d.DayOfWeek);}return r;}

Ung dung

string S(int y)
{
    var r="";
    for (int m=1;m<13;++m)
    {
        var d = new System.DateTime(y, 1, 1).AddMonths(m).AddDays(-1);
        r += y + string.Format("-{0:00}-{1} ", m, d.Day - d.DayOfWeek);
    }
    return r;
}

0

C # 194

sử dụng Linq:

string d(int y){return string.Join(" ",Enumerable.Range(1,12).Select(m=>new DateTime(y,m,DateTime.DaysInMonth(y,m))).Select(d=>d.AddDays(-(int)d.DayOfWeek)).Select(d=>d.ToString("yyy-MM-dd")));}

Ung dung

string d(int y)
{
    return string.Join(" ",Enumerable.Range(1,12)
        .Select(m => new DateTime(y, m, DateTime.DaysInMonth(y, m)))
        .Select(d => d.AddDays(-(int)d.DayOfWeek))
        .Select(d => d.ToString("yyy-MM-dd")));
}

Đầu ra

2013-01-27 2013-02-24 2013-03-31 2013-04-28 2013-05-26 2013-06-30 2013-07-28 2013-08-25 2013-09-29 2013-10-27 2013-11-24 2013-12-29

0

Toán học - 171

Được bọc trong một hàm ẩn danh, trả về chuỗi

StringJoin[Last@#~DateString~{"Year","-","Month","-","Day"," "}&/@GatherBy[Select[DateRange[DateObject[{#}],DateObject[{#+1}]],DayName@#==Sunday&],DateValue[#,"Month"]&]]&

Golf toán học đầu tiên. Tôi cảm thấy như nó có thể được giảm đáng kể.


0

VB-192

Function z(y)
For i = 1 To 11
a = 0
s = IIf(i <> 11, DateSerial(y, i + 1, 1), DateSerial(y + 1, 1, 1))
While Weekday(s - a) <> 1
a = a + 1
Wend
r = r + Str(s - a) + " "
Next
z = r
End Function

Có thể tệ hơn ^^

Mục nhập thứ hai và cuối cùng của tôi (đừng nghĩ rằng tôi có thể làm cho nó nhỏ hơn)

142

Function z(y)
Dim m(12)
For i = 1 To 366
s = DateSerial(y, 1, 1) + i
If Weekday(s) = 1 Then m(Month(s)) = s
Next
z = Join(m, " ")
End Function

0

Ruby 76

Sử dụng một tham số dòng lệnh ruby sundays.rb 1900. Sử dụng thư viện Date.

require'date';puts (1..12).map{|m|d=Date.new($*[0].to_i,m,-1);d-d.wday}*" "
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.