Lên kế hoạch chủ nhật của bạn!


16

Ai mà không thích thư giãn vào sáng chủ nhật mùa hè với bia và TV ướp lạnh hoặc vào mùa đông chơi cầu lông hay tối thượng với bạn bè?

Tôi luôn nghĩ rằng việc bạn phải làm lạnh bao nhiêu ngày trong một tháng giúp bạn có đủ thông tin và giúp bạn lên kế hoạch cho những gì bạn muốn làm. Có thể là ngồi trước máy tính của bạn và giải quyết vấn đề golf-code hoặc ra ngoài chơi bóng đá.

Vì vậy, giúp tôi viết một chương trình hoặc chức năng mà mất như đầu vào 2 số nguyên dương, YMvà kết quả đầu ra số lượng ngày chủ nhật trong năm đặc biệt ( Y) và tháng ( M) (theo lịch Gregorian), tiếp theo là ngày của mỗi chủ nhật.

Ngoài ra, hãy nhớ rằng mã ngắn nhất sẽ thắng.

Ràng buộc đầu vào

1000 <= Y <= 9999

1 <= M <= 12

Đầu ra

Các trường hợp thử nghiệm này sẽ có đầu ra sẽ có ngày của mỗi Chủ nhật của tháng đó trong năm đó theo định dạng DD-MM-YYYY.

Các trường hợp thử nghiệm mẫu

Trường hợp kiểm tra 1

Đầu vào mẫu

2017 1

Đầu ra mẫu

5
01-01-2017
08-01-2017
15-01-2017
22-01-2017
29-01-2017

Trường hợp thử nghiệm 2

Đầu vào mẫu

2018 2

Đầu ra mẫu

4
04-02-2018
11-02-2018
18-02-2018
25-02-2018

Trường hợp thử nghiệm 3

Đầu vào mẫu

2016 11

Đầu ra mẫu

4
06-11-2016
13-11-2016
20-11-2016
27-11-2016

2
Tôi khuyên bạn nên cho phép bất kỳ định dạng ngày nào, bao gồm một Date()đối tượng và bất kỳ định dạng đầu ra nào, bao gồm [4, [<dateobj>, <dateobj>, <dateobj>, <dateobj>]](trong đó <dateobj>là một đối tượng ngày thực tế và []là một mảng thực tế).
wizzwizz4

2
Khi định dạng đầu ra là phần xác định của một thách thức, sự đồng thuận của cộng đồng là nó nhàm chán. Trong tương lai tôi khuyên bạn nên sử dụng Sandbox, nhưng vì chưa có ai trả lời nên bạn có thể thoát khỏi việc thay đổi nó.
wizzwizz4

1
Tôi sẽ chỉnh sửa. Bạn có thể cuộn nó lại nếu bạn nghĩ rằng nó làm hỏng thử thách.
wizzwizz4

1
Vậy làm thế nào linh hoạt là định dạng đầu ra? Ví dụ, nó có thể có /thay vì -? Hay có thể là tháng, rồi ngày, năm?
Luis Mendo

1
Bất kỳ địa phương cụ thể? Lưu ý rằng trước năm 1582, lịch Julian được sử dụng phổ biến, với các quốc gia chuyển sang Gregorian vào cuối năm 1952 cho Hy Lạp. Ở Anh, họ đã nhảy lịch trước 11 ngày vào tháng 9 năm 1752, dẫn đến bạo loạn lớn. Khuyến nghị là sử dụng một cái gì đó gọi là "Lịch Gregorian Proleptic" giả vờ lịch hiện tại đã được sử dụng cho đến khi bạn cần.

Câu trả lời:


0

MATL , 46 45 42 35 byte

8BhtYOw47B~+YOq&:t8XO!s310=)tnw24XO

Đầu vào là một mảng của mẫu [2017 1]. Định dạng đầu ra là 29/01/2017.

Hãy thử trực tuyến! Hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình

8B       % Push [1 0 0 0] (8 in binary)
h        % Implicit input. Concatenate. Gives something like [2017 1 1 0 0 0],
         % corresponding to the first day of input year and month
tYO      % Duplicate. Convert to serial date number
w        % Swap
47B~     % Push [0 1 0 0 0 0] (47 in binary, then negated)
+        % Add. Gives something like [2017 2 1 0 0 0]: first day of next month
YO       % Convert to serial number
q        % Subtract 1. This corresponds to last day of input month
&:       % Binary range. Gives an array with 28, 29, 30 or 31 days
t8XO     % Duplicate. Convert each number to three letters telling day of the week
!s       % Transpose, Sum of each column
310=     % True for values that equal 310, which is the sum of 'Sun' in ASCII
)        % Apply as a logical index
tnw      % Duplicate, number of elements, swap. This is the first part of output
24XO     % Convert to date format 'dd/mm/yyyy'. Gives 2D char array. Implicit display

Điều này có hoạt động với ngày cũ hơn (như năm 1217) không?
Tít


Woops đã không thấy TiO.
Tít

4

Python 2 , 150,148, 145 byte

from calendar import*
y,m=map(int,input().split())
z=filter(None,zip(*monthcalendar(y,m))[6])
print len(z)
for i in z:print'%02d-%02d-%s'%(i,m,y)

Hãy thử trực tuyến!

-3 byte làm cho công cụ trở nên pythonic hơn (sử dụng zip và bộ lọc!)


Sẽ là 150 nếu bạn đưa câu lệnh in lên dòng trước và nếu bạn thêm '02' trong% d đầu tiên trong dòng 3.
Koishore Roy

'02' trong% d đầu tiên! Huh. bỏ lỡ điều đó Cảm ơn! Dù sao đi nữa. lưu hai byte mặc dù thay vì tăng hai!
Keerthana Mitchhakaran

4

JavaScript (ES6), 107 byte

f=
(y,m,a=[...Array(32)].map((_,i)=>new Date(y,m-1,i)).filter(d=>d.getMonth()==m-1&!d.getDay()))=>[a.length,a]
<div oninput=o.textContent=[].concat(...f(y.value,m.value)).map((d,i)=&gt;i?d.toDateString():d).join`\n`><input id=y type=number min=1000 max=9999 value=2017><input id=m type=number min=1 max=12><pre id=o>

Chỉnh sửa: Thêm một số lượng rõ ràng chi phí 15 byte. Định dạng đầu ra sẽ tốn ít nhất 33 byte tùy thuộc vào mức độ nghiêm ngặt của định dạng đầu ra.


> outputs the number of Sundays in that particular year and month; có vẻ như điều này hiện không xuất ra số ngày chủ nhật.
numbermaniac

Bạn có thể sử dụng <input type='date'>.
Matthew Roh

@SIGSEGV Chưa được hỗ trợ trong Firefox, đây là những gì tôi sử dụng.
Neil

2
@Neil Sử dụng Chrome m8
Matthew Roh

3
@SIGSEGV Tôi thích Chrome thậm chí ít hơn Internet Explorer.
Neil

2

PowerShell , 91 byte

param($y,$m)($a=(1..31|%{Date "$m/$_/$y"}|?{!$_.dayofweek})).count;$a|%{"{0:d-M-yyyy}"-f$_}

Hãy thử trực tuyến!

(Lưu ý đặc biệt - đây là phụ thuộc vào cài đặt văn hóa và ngôn ngữ. Vì TIO là chạyen-us , nó hoạt động chính xác theo nguyên trạng. Mã này có thể cần được thay đổi cho các địa phương khác nhau.)

Lấy đầu vào là hai số nguyên $y$m. Vòng lặp từ 1đến 31, nhận một datetimeđối tượng mới cho mỗi ngày có thể (thông qua Get-Datelệnh ghép ngắn). Sẽ ném lỗi sang STDERR (mặc định bị bỏ qua trong các thử thách chơi gôn mã) trong nhiều tháng với ít hơn 31 ngày, nhưng điều đó không ảnh hưởng đến đầu ra. Chúng tôi lấy từng datetimeđối tượng đó và sử dụng một Where-Object( |?{...}) trên chúng, với mệnh đề của !$_.dayofweek. Tài sản .dayofweeklà một số từ 0đến 6, với 0thuận tiện tương ứng vớiSunday , do đó, !đó là sự thật, giúp tiết kiệm một vài byte so với kiểm tra đẳng thức như thế nào -eq0.

Chủ nhật sau đó được tập hợp trong parens và lưu trữ vào $a. Sau đó chúng tôi lấy .countnó và đặt trên đường ống. Tiếp theo, chúng tôi lặp qua $avà sử dụng -ftoán tử ormat để xây dựng định dạng đầu ra chính xác. Lưu ý rằng điều này không tạo ra số không hàng đầu trong nhiều ngày hoặc nhiều tháng. Các chuỗi ngày đó cũng được để lại trên đường ống và một ẩn Write-Outputkhi hoàn thành chương trình sẽ in chúng bằng các dấu phân cách dòng mới.


NB - nếu định dạng đầu ra linh hoạt hơn, chúng ta có thể chỉ cần rời khỏi $ađường ống và không cần phải lặp qua nó. Điều đó sẽ xâu chuỗi các datetimeđối tượng thành định dạng dài ngày bao gồm thông tin về thời gian, nhưng sẽ đưa chúng ta xuống còn 69 byte , hiện tại (chỉ) sẽ bị Mathicala và MATL đánh bại.


1

Octave, 72 byte

@(y,m)cellfun(@disp,flip({datestr(x=nweekdate(1:6,1,y,m)(x>1)),nnz(x)}))

nweekdatetrả về số ngày tương ứng với Nlần xuất hiện thứ của một ngày trong tuần cụ thể trong tháng / năm được chỉ định. Chúng tôi sử dụng mảng 1:6thay thế Nđể có được tất cả các lần xuất hiện trong một tháng. Nếu có ít hơn số Nlần xuất hiện của ngày trong tuần đó trong một tháng, thì số ngày kết quả là 0. Vì lý do này, chúng tôi chỉ chọn ngày hợp lệ bằng cách sử dụng (x>1)và sau đó chuyển đổi chúng thành chuỗi bằng cách sử dụng datestr.

Sau đó, để đếm số ngày chủ nhật, chúng tôi đếm số lượng khác không (nnz ) trong kết quả.

Sau đó chúng tôi bọc toàn bộ thứ cellfunđể hiển thị từng giá trị.


0

Ruby, 140 132 129 118 byte

require'date'
d=Date.parse gets.split*?-+'-1'
s=(d...d>>1).select &:sunday?
puts s.size,s.map{|d|d.strftime'%d-%m-%Y'}

0

Excel - 103 ký tự

Đặt năm trong ô A1, và tháng trong ô A2.

Số lượng là trong tế bào D1và Chủ nhật trong các tế bàoD2:D6 .

Giả D2:D6định được định dạng DD-MM-YYYY.

   A      B       C              D
1  [year] [month] =DATE(A1,B1,1) =COUNTIF(D2:D7,">0")
2                                =C1+7-WEEKDAY(C1,2)
3                                =D2+7
4                                =D3+7
5                                =D4+7
6                                =IF(MONTH(D5+7)=MONTH(C1),D5+7,"")

0

Toán học, 82 68 byte

d=DateObject;{Length[x=DayRange[d@{#,#2,1},d@{#,#2+1,0},Sunday]],x}&

Chức năng ẩn danh. Xuất ra một danh sách số ngày, theo sau là danh sách các ngày chủ nhật dưới dạng DateObjects. Hóa ra, trong Mathicala, ngày thứ 0 của tháng được hiểu là ngày cuối cùng của tháng trước.


0

C #, 183 byte

y=>m=>{var s=new string[6];int i=1,n=0;for(DateTime d;i<=DateTime.DaysInMonth(y,m);)if((int)(d=new DateTime(y,m,i++)).DayOfWeek<1)s[++n]=d.ToString("dd-MM-yyyy");s[0]=n+"";return s;};

Phương thức ẩn danh trả về một chuỗi chuỗi, đầu tiên chứa số Chủ nhật và sau đó mỗi Chủ nhật theo định dạng đã chỉ định. Nếu chỉ có 4 Chủ nhật trong một tháng, chuỗi cuối cùng là null.

Chương trình đầy đủ với phương pháp vô căn cứ và các trường hợp thử nghiệm:

using System;

class P
{
    static void Main()
    {
        Func<int, Func<int, string[]>> f =
        y=>m=>
        {
            var s=new string[6];
            int i=1,n=0;
            for(DateTime d;i<=DateTime.DaysInMonth(y,m);)
                if((int)(d=new DateTime(y,m,i++)).DayOfWeek<1)
                    s[++n]=d.ToString("dd-MM-yyyy");

            s[0]=n+"";
            return s;
        };

        // test cases:
        var result = f(2017)(1);
        foreach (var x in result)
            Console.WriteLine(x);

        result = f(2018)(2);
        foreach (var x in result)
            Console.WriteLine(x);

        result = f(2016)(11);
        foreach (var x in result)
            Console.WriteLine(x);
    }
}

0

REXX, 168 byte

arg y m
signal on syntax
do d=1 to 31
  m=right(m,2,0);d=right(d,2,0)
  if date(w,y||m||d,s)='Sunday' then queue d'-'m'-'y
  end
syntax:n=queued()
say n
do n
  pull a
  say a
  end

Tôi đoán điều này không hoạt động với những năm nhỏ hơn. Bạn đã thử 1217chưa
Tít

0

Bash + bsdmainutils, 94 byte

a=(`for i in $(cal $2 $1|cut -b1-2);{ echo $i-$2-$1;}`);echo $[${#a[@]}-1];fmt -1 <<<${a[@]:1}

Sử dụng lệnh cal in lịch, được cài đặt theo mặc định trong một số UNIX / LINUX / BSD (không may là không có trong TIO).

Để thử nó tiết kiệm tới file, chmod +x filevà chạy./file 2017 9

Lưu vào mảng hai byte đầu ra của cal được nối với chuỗi "MM-YYYY" được truyền dưới dạng tham số thứ hai và thứ nhất (cần thay đổi nếu miền địa phương của bạn không bắt đầu tuần vào chủ nhật).

Tiếng vang tiếp theo của chiều dài mảng được trừ đi bởi một (phần tử đầu tiên là từ đại diện cho chủ nhật) và mảng không có từ xa đầu tiên, mỗi dòng trên mỗi dòng fmt -1


Nó xử lý trường hợp đặc biệt 1752 9
marcosm

0

SAS, 182 byte

%macro s(y,m);%let c=%eval(%sysfunc(intck(week,%sysfunc(nwkdom(1,1,&m,&y)),%sysfunc(nwkdom(5,1,&m,&y))))+1);%put&c;%do i=1%to&c;%put%sysfunc(nwkdom(&i,1,&m,&y),ddmmyy10.);%end;%mend;

0

T-SQL, 316 311 byte

DECLARE @ DATE=DATEADD(ww,-52*(2017-@y),'20170101')IF DATEPART(d,@)>7SET @=DATEADD(ww,-1,@);WITH c(d)AS(SELECT d FROM(SELECT DATEADD(ww,ROW_NUMBER()OVER(ORDER BY name)-1,@)d FROM sys.stats)a WHERE @y=DATEPART(yy,d)AND @m=DATEPART(m,d))SELECT CAST(COUNT(*)AS CHAR(1))FROM c UNION SELECT CAST(d AS CHAR(10))FROM c

Tôi không biết đó có phải là một câu trả lời hợp lệ hay không, vì nó đưa ra số lượng chủ nhật sau ngày

Hãy thử nó ở đây

vô dụng:

DECLARE @m INT = 1,@y INT = 2017

DECLARE @ DATE=DATEADD(ww,-52*(2017-@y),'20170101')

IF DATEPART(d,@)>7
    SET @=DATEADD(ww,-1,@)

;WITH c(d)
AS
(SELECT d 
 FROM (SELECT DATEADD(ww,ROW_NUMBER()OVER(ORDER BY name)-1,@)d 
       FROM sys.stats) a 
 WHERE @y = DATEPART(yy,d)
   AND @m = DATEPART(m,d)
)

SELECT CAST(COUNT(*) AS CHAR(1))
FROM c 
UNION 
SELECT CAST(d AS CHAR(10))
FROM c

0

PHP, 127 118 112 107 byte

for([,$y,$m]=$argv;$d++<date(t,($t=strtotime)($y.-$m));)date(w,$t($s="
$d.$m.$y"))?:$r.=$s.!++$c;echo$c,$r;

lấy đầu vào từ các đối số dòng lệnh; chạy với -rhoặc kiểm tra nó trực tuyến .

phá vỡ

for([,$y,$m]=$argv;                     # import arguments to $y and $m
    $d++<date(t,strtotime($y.-$m))      # loop while ($d < number of days in that month)
    ;)
    date(w,strtotime($s="\n$d.$m.$y"))?:    # if date(w) is falsy (0 == sunday)
        $r.=$s.!++$c;                       # then append date to $r and increment $c
echo$c,$r;                              # print result

0

VBA Excel, 190 byte

Function p(y, m)
d = CDate("1/" & m & "/" & y)
e = DateAdd("m", 1, d)
Do While d < e
    If Weekday(d) = 1 Then Debug.Print d: i = i + 1
    d = d + 1
Loop
Debug.Print i
End Function

Kết quả mẫu cho p (2000, 1) (không chắc điều này có đủ điều kiện không)

02-01-2000 
09-01-2000 
16-01-2000 
23-01-2000 
30-01-2000 
 5 
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.