Pazar günlerinizi planlayın!


16

Kim bir Pazar sabahı yaz aylarında soğuk bir bira ve TV ile ya da kışın badminton ya da arkadaşlarla oynayarak serinlemeyi sevmez?

Her zaman ayda kaç gün soğutmanız gerektiğini bilmek sizi iyi bilgilendirir ve ne yapmak istediğinizi planlamanıza yardımcı olur. Bu pc önünde oturan ve bir kod-golf sorunu çözme ya da futbol oynamak için dışarı olsun.

Bu nedenle, girdi 2 pozitif tamsayıları alan Yve her Myıl ( Y) ve ay ( M) (Gregoryen Takvimi'ne göre) Pazar günlerini ve ardından her Pazar gününü çıkaran bir program veya işlev yazmama yardımcı olun .

Ayrıca, en kısa kodun kazandığını unutmayın.

Giriş Kısıtlamaları

1000 <= Y <= 9999

1 <= M <= 12

Çıktı

Bu test senaryoları, o ayın her Pazar gününün biçiminde çıktısına sahip olacaktır DD-MM-YYYY.

Örnek Test Durumları

Test Durumu 1

Örnek Giriş

2017 1

Örnek Çıktı

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

Test Durumu 2

Örnek Giriş

2018 2

Örnek Çıktı

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

Test Durumu 3

Örnek Giriş

2016 11

Örnek Çıktı

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

2
Bir Date()nesne dahil herhangi bir tarih biçimine ve dahil olmak üzere herhangi bir tarih biçimine izin vermenizi öneririm [4, [<dateobj>, <dateobj>, <dateobj>, <dateobj>]](burada <dateobj>gerçek bir tarih nesnesidir ve []gerçek bir dizidir).
wizzwizz4

2
Çıktı formatı bir zorluğun tanımlayıcı kısmı olduğunda, topluluk konsensüsü sıkıcı olmasıdır. Gelecekte Sandbox'ı kullanmanızı tavsiye ederim, ancak henüz kimse cevap vermediğinden, değiştirmekten kurtulabilirsiniz.
wizzwizz4

1
Bir düzenleme yapacağım. Zorluğa zarar verdiğini düşünüyorsanız geri alabilirsiniz.
wizzwizz4

1
Peki çıktı biçimi ne kadar esnektir? Örneğin, /bunun yerine sahip olabilir -mi? Yoksa ay, sonra gün, sonra yıl olabilir mi?
Luis Mendo

1
Herhangi bir yerel ayar? 1582'den önce, Julian takviminin yaygın olarak kullanıldığını, ülkelerin Yunanistan için 1952'nin sonlarında Gregoryen'e geçtiklerini unutmayın. İngiltere'de takvimi 1752 Eylül ayının 11 günü ileri atlayarak kitlesel ayaklanmalara yol açtılar. Öneri, mevcut takvimin ihtiyacınız olduğu kadar kullanıldığını iddia eden "Proleptik Gregoryen Takvimi" olarak adlandırılan bir şey kullanmanızdır.

Yanıtlar:


0

MATL , 46 45 42 35 bayt

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

Girdi, formun bir dizisidir [2017 1]. Çıktı biçimi 29/01/2017.

Çevrimiçi deneyin! Veya tüm test senaryolarını doğrulayın .

açıklama

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

Bu eski tarihlerle mi çalışıyor (1217 yılı gibi)?
Titus


Woops TiO'yu görmedi.
Titus

4

Python 2 , 150.148, 145 bayt

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)

Çevrimiçi deneyin!

-3 bayt daha pythonic (zip ve filtre kullanarak!)


Yazdırma ifadesini önceki satıra getirirseniz ve satır 3'teki ilk% d'ye '02' eklerseniz 150 olur.
Koishore Roy

İlk% d'de '02'! ha. kaçırdı. Teşekkürler! neyse. iki bayt artırmak yerine iki bayt tasarruf!
Keerthana Prabhakaran

4

JavaScript (ES6), 107 bayt

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>

Düzenleme: Açık bir sayım eklemek 15 bayt tutar. Çıktıyı biçimlendirmek, çıktı biçiminin ne kadar katı olduğuna bağlı olarak en az 33 bayta mal olur.


> outputs the number of Sundays in that particular year and month; şu anda Pazar günlerinin sayısını vermiyor gibi görünüyor.
numbermaniac

Kullanabilirsin <input type='date'>.
Matthew Roh

@SIGSEGV Henüz kullandığım Firefox'ta desteklenmiyor.
Neil

2
@Neil Chrome m8 kullanın
Matthew Roh

3
@SIGSEGV Chrome'u Internet Explorer'dan bile daha az seviyorum.
Neil

2

PowerShell , 91 bayt

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

Çevrimiçi deneyin!

(Özel not - bu yerel ayara ve kültür ayarlarına bağlıdır. TIO olduğu gibien-us çalıştığı için orada olduğu gibi doğru çalışır. Bu kodun farklı yerel ayarlar için değiştirilmesi gerekebilir.)

Girdiyi iki tamsayı olarak alır $yve $m. (Cmdlet aracılığıyla ) olası her tarih için yeni bir nesne elde ederek arasında 1geçiş yapar . Hataları 31 günden az aylar boyunca STDERR'a (kod-golf zorluklarında varsayılan olarak yok sayılır) atar, ancak bu çıktıyı etkilemez. Bu nesnelerin her birini alıp üzerlerinde fıkra ile bir ( ) kullanırız . Özelliği arasında bir sayı için olan uygun bir tekabül eden , böylece bunun gibi bir eşitlik kontrole göre bayt bir çift kaydeder truthy, olduğu .31datetimeGet-DatedatetimeWhere-Object|?{...}!$_.dayofweek.dayofweek060Sunday!-eq0

Pazar günleri daha sonra parenslerde toplanır ve saklanır $a. Daha sonra bunları alırız .countve bu boru hattına yerleştirilir. Ardından, doğru çıktı biçimini oluşturmak için ormat operatörünü dolaşır $ave kullanırız -f. Bunun günler veya aylar boyunca önde gelen sıfırlar vermediğini unutmayın. Bu tarih dizeleri de boru hattında bırakılır ve Write-Outputprogram tamamlandığında örtük olarak yeni satır ayırıcılarla yazdırılır.


NB - çıktı biçimi daha esnek olsaydı, sadece $aboru hattında bırakabiliriz ve içinden geçmemiz gerekmez. Bu, datetimenesneleri zaman bilgileri de dahil olmak üzere uzun tarih formatı olarak dizginleyecektir , ancak bizi 69 bayta indirir, bu da (şu anda) sadece Mathematica ve MATL tarafından dövülecektir.


1

Oktav, 72 bayt

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

nweekdateNbelirtilen ay / yılda belirli bir hafta içi günün gerçekleşmesine karşılık gelen tarih numarasını döndürür . Diziyi bir ay 1:6içinde gerçekleşen tüm olayları Nalmak için kullanıyoruz . Bir ay içinde hafta içi gün sayısından daha az olay varsa, sonuç tarih numarası olur . Bu nedenle, yalnızca geçerli tarihleri ​​kullanarak seçer ve ardından bunları kullanarak dizelere dönüştürürüz .N0(x>1)datestr

Ardından Pazar günlerini saymak için nnz, sonuçta sıfır olmayan ( ) tarih sayılarını sayıyoruz .

Daha sonra cellfunher bir değeri görüntülemek için her şeyi içine sarıyoruz.


0

Yakut, 140 132 129 118 bayt

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

Yılı hücreye A1, ayı hücreye koyun A2.

Sayım hücrede D1ve Pazar günleri hücrelerde D2:D6.

Varsayımlar D2:D6DD-AA-YYYY olarak biçimlendirilir.

   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 bayt

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

Anonim işlev. Gün sayısı ve ardından Pazar günleri listesi verilir DateObject. Görünüşe göre, Mathematica'da bir ayın 0 günü bir önceki ayın son günü olarak yorumlanıyor.


0

C #, 183 bayt

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

Önce Pazar sayısını ve ardından her Pazar günü belirtilen biçimde içeren bir dize dizisi döndüren anonim yöntem. Bir ayda sadece 4 Pazar varsa, son dize null olur.

Golfsiz yöntem ve test senaryoları ile tam program:

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 bayt

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

Sanırım bu daha küçük yıllarla çalışmıyor. Denedin 1217mi
Titus

0

Bash + bsdmainutils, 94 bayt

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

calTakvim yazdıran, varsayılan olarak birkaç UNIX / LINUX / BSD'ye yüklendi (maalesef TIO'da değil) komutunu kullanır .

Kaydet denemek için file, chmod +x fileve çalıştırma./file 2017 9

İkinci ve ilk parametreler olarak "MM-YYYY" dizesiyle eklenen ilk iki baytlık cal çıkışının dizisini a kaydeder (yerel ayarınız pazar günleri haftalarca başlamazsa değiştirilmesi gerekir).

Sonraki dizi uzunluğu bir tarafından çıkarılır (ilk öğe pazar temsil eden kelime) ve ilk elemet olmayan dizi, her satırda bir tane fmt -1


Özel durum 1752 9
marcosm

0

SAS, 182 bayt

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

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

Tarihlerden sonra pazar sayısını çıkardığı için bunun geçerli bir cevap olup olmadığını bilmiyorum

Burada deneyin

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, 12711812110 bayt

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

komut satırı bağımsız değişkenlerinden girdi alır; ile çalıştırın -rveya çevrimiçi test edin .

Yıkmak

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 bayt

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

P (2000, 1) için Örnek Çıktı (bunun uygun olup olmadığından emin değilim)

02-01-2000 
09-01-2000 
16-01-2000 
23-01-2000 
30-01-2000 
 5 
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.