Rencanakan hari Minggu Anda!


16

Siapa yang tidak suka bersantai di hari Minggu pagi di musim panas dengan bir dingin dan TV atau di musim dingin bermain bulu tangkis atau pamungkas bersama teman?

Saya selalu berpikir mengetahui berapa hari Anda harus bersantai dalam sebulan membuat Anda mendapat informasi lengkap dan membantu Anda merencanakan apa yang ingin Anda lakukan. Baik itu duduk di depan komputer Anda dan memecahkan masalah kode-golf atau pergi bermain sepak bola.

Jadi, bantu saya menulis program atau fungsi yang mengambil input 2 bilangan bulat positif, Ydan Mdan menampilkan jumlah hari Minggu di tahun tertentu ( Y) dan bulan ( M) (menurut Kalender Gregorian), diikuti dengan tanggal setiap hari Minggu.

Juga, perlu diingat bahwa kode terpendek menang.

Kendala Input

1000 <= Y <= 9999

1 <= M <= 12

Keluaran

Kasing uji ini akan memiliki keluaran yang memiliki tanggal setiap hari Minggu pada bulan tersebut di tahun itu dalam format DD-MM-YYYY.

Contoh Uji Kasus

Test Case 1

Input Sampel

2017 1

Output Sampel

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

Test Case 2

Input Sampel

2018 2

Output Sampel

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

Test Case 3

Input Sampel

2016 11

Output Sampel

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

2
Saya sarankan mengizinkan format tanggal apa pun, termasuk Date()objek, dan format output apa pun, termasuk [4, [<dateobj>, <dateobj>, <dateobj>, <dateobj>]](di mana <dateobj>objek tanggal aktual, dan []merupakan array aktual).
wizzwizz4

2
Ketika format keluaran adalah bagian yang menentukan dari suatu tantangan, konsensus masyarakat adalah bahwa itu membosankan. Di masa depan saya sarankan menggunakan Sandbox, tetapi karena tidak ada yang menjawab Anda belum bisa mengubahnya.
wizzwizz4

1
Saya akan mengedit. Anda dapat mengembalikannya jika Anda pikir itu merusak tantangan.
wizzwizz4

1
Jadi seberapa fleksibel format outputnya? Sebagai contoh, dapatkah itu /bukan -? Atau mungkinkah bulan, lalu hari, lalu tahun?
Luis Mendo

1
Adakah lokal tertentu? Perhatikan bahwa sebelum tahun 1582, kalender Julian digunakan secara umum, dengan negara-negara yang beralih ke Gregorian pada tahun 1952 untuk Yunani. Di Inggris mereka melompati kalender lebih cepat dari 11 hari di bulan September 1752, yang menyebabkan kerusuhan massal. Rekomendasi adalah untuk menggunakan sesuatu yang disebut "Kalender Gregorian Proleptik" yang berpura-pura kalender saat ini digunakan sejauh yang Anda butuhkan.

Jawaban:


0

MATL , 46 45 42 35 byte

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

Input adalah larik formulir [2017 1]. Format keluaran adalah 29/01/2017.

Cobalah online! Atau verifikasi semua kasus uji .

Penjelasan

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

Apakah ini bekerja dengan tanggal yang lebih lama (seperti tahun 1217)?
Titus


Woops tidak melihat TiO.
Titus

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)

Cobalah online!

-3 byte membuat barang lebih pythonic (menggunakan zip dan filter!)


Ini akan menjadi 150 jika Anda membawa pernyataan cetak ke baris sebelumnya dan jika Anda menambahkan '02' di% d pertama di baris 3.
Koishore Roy

'02' di% d pertama! Hah. merindukan itu. Terima kasih! bagaimanapun. menghemat dua byte meskipun bukannya meningkat dua!
Keerthana Prabhakaran

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>

Sunting: Menambahkan biaya penghitungan eksplisit 15 byte. Memformat output akan menelan biaya setidaknya 33 byte tergantung pada seberapa ketat format outputnya.


> outputs the number of Sundays in that particular year and month; Sepertinya saat ini tidak menampilkan jumlah hari Minggu.
numbermaniac

Anda bisa menggunakannya <input type='date'>.
Matthew Roh

@SIGSEGV Belum didukung di Firefox, itulah yang saya gunakan.
Neil

2
@Neil Gunakan Chrome m8
Matthew Roh

3
@SIGSEGV Saya lebih suka Chrome daripada Internet Explorer.
Neil

2

PowerShell , 91 byte

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

Cobalah online!

(Catatan khusus - ini tergantung pengaturan lokal dan budaya. Karena TIO berjalan sebagaimanaen-us mestinya , ia bekerja dengan benar apa adanya. Kode ini mungkin perlu diubah untuk lokal yang berbeda.)

Mengambil input sebagai dua bilangan bulat $ydan $m. Loops dari 1ke 31, mendapatkan datetimeobjek baru untuk setiap tanggal yang memungkinkan (via Get-Datecmdlet). Akan melemparkan kesalahan ke STDERR (diabaikan secara default pada tantangan kode-golf) selama berbulan-bulan dengan kurang dari 31 hari, tetapi itu tidak mempengaruhi output. Kami mengambil masing-masing datetimeobjek dan menggunakan Where-Object( |?{...}) pada mereka, dengan klausa !$_.dayofweek. Properti .dayofweekadalah nomor dari 0ke 6, dengan 0mudah sesuai dengan Sunday, jadi !itu benar, yang menyimpan beberapa byte dibandingkan dengan cek kesetaraan seperti -eq0.

Hari-hari Minggu dikumpulkan dalam parens dan disimpan $a. Kami kemudian mengambilnya .count, dan itu ditempatkan di saluran pipa. Selanjutnya, kita mengulang $adan menggunakan -foperator ormat untuk membangun format output yang benar. Perhatikan bahwa ini tidak menghasilkan nol terkemuka selama berhari-hari atau berbulan-bulan. String tanggal tersebut juga ditinggalkan di dalam pipa, dan sebuah implisit Write-Outputpada penyelesaian program mencetaknya dengan pemisah baris baru.


NB - jika format output lebih fleksibel, kita bisa membiarkannya $adan tidak perlu mengulanginya. Itu akan mengencangkan datetimeobjek sebagai format tanggal panjang termasuk informasi waktu, tetapi membuat kita turun ke 69 byte , yang (saat ini) hanya akan dikalahkan oleh Mathematica dan MATL.


1

Oktaf, 72 byte

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

nweekdatemengembalikan nomor tanggal yang sesuai dengan Nkejadian -hari tertentu pada hari kerja pada bulan / tahun yang ditentukan. Kami menggunakan array 1:6di tempat Nuntuk mendapatkan semua kemunculan dalam sebulan. Jika ada kurang dari Nkejadian hari kerja dalam sebulan, maka jumlah tanggal yang dihasilkan adalah 0. Karena alasan ini, kami hanya memilih tanggal yang valid menggunakan (x>1)dan kemudian mengonversinya menjadi string menggunakandatestr .

Kemudian untuk menghitung jumlah hari Minggu, kami menghitung jumlah non-nol (nnz angka tanggal yang ) dalam hasilnya.

Kami kemudian membungkus semuanya cellfununtuk menampilkan setiap nilai.


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 karakter

Masukkan tahun dalam sel A1, dan bulan dalam sel A2.

Hitungannya ada di sel D1, dan hari Minggu di sel D2:D6.

Asumsi D2:D6diformat 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

Mathematica, 82 68 byte

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

Fungsi anonim. Menghasilkan daftar jumlah hari, diikuti oleh daftar hari Minggu sebagai DateObjects. Ternyata, di Mathematica, hari ke-0 dalam sebulan ditafsirkan sebagai hari terakhir bulan sebelumnya.


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;};

Metode anonim yang mengembalikan array string, berisi pertama jumlah hari Minggu dan kemudian setiap hari Minggu dalam format yang ditentukan. Jika hanya ada 4 Minggu dalam sebulan, string terakhir adalah nol.

Program lengkap dengan metode ungolfed dan uji kasus:

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

Saya kira ini tidak bekerja dengan tahun yang lebih kecil. Sudahkah Anda mencoba 1217?
Titus

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}

Menggunakan perintah calyang mencetak kalender, diinstal secara default di beberapa UNIX / LINUX / BSD (sayangnya tidak di TIO).

Untuk mencobanya menyimpan ke file, chmod +x file, dan menjalankan./file 2017 9

Menyimpan untuk menyusun dua byte pertama dari output kal ditambahkan dengan string "MM-YYYY" dilewatkan sebagai parameter kedua dan pertama (perlu diubah jika lokal Anda tidak dimulai minggu pada minggu).

Gema panjang array berikutnya dikurangi dengan satu (elemen pertama adalah kata yang mewakili minggu) dan array tanpa elemet pertama, satu per baris fmt -1


Ini menangani kasus khusus 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

Saya tidak tahu apakah itu jawaban yang valid, karena ini menghasilkan jumlah minggu setelah tanggal

Coba di sini

ungolfed:

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;

mengambil input dari argumen baris perintah; jalankan dengan -ratau coba online .

kerusakan

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

Excel VBA, 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

Contoh Output untuk p (2000, 1) (tidak yakin apakah ini memenuhi syarat)

02-01-2000 
09-01-2000 
16-01-2000 
23-01-2000 
30-01-2000 
 5 
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.