Zaplanuj swoje niedziele!

16

Kto nie lubi relaksować się w niedzielny poranek latem przy schłodzonym piwie i telewizorze lub zimą grając w badmintona lub z przyjaciółmi?

Zawsze myślę, że wiedza o tym, ile dni musisz odpocząć w ciągu miesiąca, zapewnia ci dobre informacje i pomaga zaplanować, co chcesz zrobić. Czy to siedzenie przed komputerem i rozwiązywanie problemów z golfem lub wychodzenie na mecz.

Więc mi pomóc napisać program lub funkcję, która przyjmuje jako wejście 2 liczb całkowitych dodatnich, Ya Mi wysyła liczbę niedziele w danym roku ( Y) i miesiąca ( M) (wg kalendarza gregoriańskiego), a następnie do dnia każdej niedzieli.

Pamiętaj też, że wygrywa najkrótszy kod.

Ograniczenia wejściowe

1000 <= Y <= 9999

1 <= M <= 12

Wynik

Te przypadki testowe będą miały dane wyjściowe będą miały daty każdej niedzieli tego miesiąca w tym roku w formacie DD-MM-YYYY.

Przykładowe przypadki testowe

Przypadek testowy 1

Przykładowe dane wejściowe

2017 1

Przykładowe dane wyjściowe

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

Przypadek testowy 2

Przykładowe dane wejściowe

2018 2

Przykładowe dane wyjściowe

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

Przypadek testowy 3

Przykładowe dane wejściowe

2016 11

Przykładowe dane wyjściowe

4
06-11-2016
13-11-2016
20-11-2016
27-11-2016
Koishore Roy
źródło
2
Zalecam zezwalanie na dowolny format daty, w tym Date()obiekt, i dowolny format wyjściowy, w tym [4, [<dateobj>, <dateobj>, <dateobj>, <dateobj>]](gdzie <dateobj>jest rzeczywisty obiekt daty i []rzeczywista tablica).
wizzwizz4,
2
Kiedy format wyjściowy jest decydującą częścią wyzwania, społeczna zgoda jest taka, że ​​jest nudny. W przyszłości polecam korzystanie z piaskownicy, ale ponieważ nikt jeszcze nie odpowiedział, możesz go zmienić.
wizzwizz4
1
Dokonam edycji. Możesz go wycofać, jeśli uważasz, że niszczy wyzwanie.
wizzwizz4
1
Jak więc elastyczny jest format wyjściowy? Na przykład, czy może mieć /zamiast -? Czy może to być miesiąc, dzień, rok?
Luis Mendo,
1
Jakieś konkretne ustawienia regionalne? Należy pamiętać, że przed 1582 r. Kalendarz juliański był w powszechnym użyciu, a kraje przeniosły się do gregoriańskiego dopiero w 1952 r. Dla Grecji. W Anglii przeskoczyli kalendarz o 11 dni we wrześniu 1752 r., Co doprowadziło do masowych zamieszek. Zaleca się stosowanie czegoś zwanego „Proleptycznym kalendarzem gregoriańskim”, który udaje, że bieżący kalendarz był używany tak długo, jak potrzebujesz.

Odpowiedzi:

0

MATL , 46 45 42 35 bajtów

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

Dane wejściowe to tablica formularza [2017 1]. Format wyjściowy to 29/01/2017.

Wypróbuj online! Lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie

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
Luis Mendo
źródło
Czy to działa ze starszymi datami (jak rok 1217)?
Tytus
Woops nie widział TiO.
Tytus
4

Python 2 , 150,148, 145 bajtów

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)

Wypróbuj online!

-3 bajty, dzięki czemu rzeczy są bardziej pytoniczne (użycie zip i filtru!)

Keerthana Prabhakaran
źródło
Wyniesie 150, jeśli przeniesiesz instrukcję print do poprzedniej linii i dodasz „02” w pierwszym% d w linii 3.
Koishore Roy
„02” w pierwszych% d! hę przegapiłem to. Dzięki! tak czy inaczej. zapisane dwa bajty zamiast zwiększania o dwa!
Keerthana Prabhakaran
4

JavaScript (ES6), 107 bajtów

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>

Edycja: dodanie jawnej liczby kosztuje 15 bajtów. Formatowanie danych wyjściowych kosztowałoby co najmniej kolejne 33 bajty w zależności od tego, jak ścisły jest format wyjściowy.

Neil
źródło
> outputs the number of Sundays in that particular year and month; wygląda na to, że obecnie nie wyświetla liczby niedziel.
numbermaniac
Możesz użyć <input type='date'>.
Matthew Roh
@SIGSEGV Nie jest jeszcze obsługiwany w Firefoksie, którego używam.
Neil,
2
@Neil Użyj Chrome m8
Matthew Roh
3
@SIGSEGV Lubię Chrome nawet mniej niż Internet Explorer.
Neil
2

PowerShell , 91 bajtów

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

Wypróbuj online!

(Uwaga specjalna - jest to zależne od ustawień regionalnych i kulturowych. Ponieważ TIO działa jakoen-us , działa poprawnie tam, gdzie jest). Kod ten może wymagać zmiany w różnych lokalizacjach.)

Pobiera dane wejściowe jako dwie liczby całkowite $yi $m. Pętle od 1do 31, otrzymując nowy datetimeobiekt dla każdej możliwej daty (poprzez Get-Datecmdlet). Przerzuca błędy do STDERR (domyślnie ignorowane w wyzwaniach związanych z golfem) przez miesiące z mniej niż 31 dni, ale to nie wpływa na wynik. Bierzemy każdy z tych datetimeobiektów i używamy na nich znaku Where-Object( |?{...}) z klauzulą !$_.dayofweek. Właściwość .dayofweekjest liczbą od 0do 6, z 0dogodnie odpowiadającą Sunday, więc !ta jest prawdziwa, co pozwala zaoszczędzić kilka bajtów w porównaniu do kontroli równości, takiej jak -eq0.

Niedziele są następnie gromadzone w parenach i przechowywane w $a. Następnie bierzemy to .count, a to jest umieszczane na rurociągu. Następnie wykonujemy pętlę $ai używamy -foperatora ormat do skonstruowania poprawnego formatu wyjściowego. Pamiętaj, że to nie generuje zer wiodących przez dni lub miesiące. Te ciągi dat są również pozostawione w potoku, a domniemane Write-Outputpo zakończeniu programu drukuje je z separatorami nowej linii.


Uwaga - jeśli format wyjściowy byłby bardziej elastyczny, moglibyśmy po prostu wyjść $az potoku i nie musieć go zapętlać. Spowoduje to usztywnienie datetimeobiektów jako format długiej daty, w tym informacje o czasie, ale doprowadzi nas do 69 bajtów , które (obecnie) zostałyby pobite tylko przez Mathematica i MATL.

AdmBorkBork
źródło
1

Oktawa, 72 bajty

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

nweekdatezwraca numer daty odpowiadający N-temu wystąpieniu określonego dnia tygodnia w określonym miesiącu / roku. Używamy tablicy 1:6zamiast, Naby uzyskać wszystkie wystąpienia w ciągu miesiąca. Jeśli Nw ciągu miesiąca jest mniej niż wystąpień tego dnia tygodnia, wynikowy numer daty to 0. Z tego powodu wybieramy tylko prawidłowe daty za pomocą, (x>1)a następnie przekształcamy je w ciągi za pomocą datestr.

Następnie, aby policzyć liczbę niedziel, zliczamy liczbę niezerowych ( nnz) liczb daty w wyniku.

Następnie zawijamy całość, cellfunaby wyświetlić każdą wartość.

Suever
źródło
0

Rubinowy, 140 132 129 129 118 bajtów

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'}
emlai
źródło
0

Excel - 103 znaki

Umieść rok w komórce A1, a miesiąc w komórce A2.

Liczba jest w komórce D1, a niedziele w komórkach D2:D6.

Zakłada D2:D6się, że są sformatowane DD-MM-RRRR.

   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,"")

źródło
0

Mathematica, 82 68 bajtów

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

Funkcja anonimowa. Wyświetla listę dni, a następnie listę niedziel jako DateObjects. Okazuje się, że w Mathematica 0 dzień miesiąca jest interpretowany jako ostatni dzień poprzedniego miesiąca.

NumberManiac
źródło
0

C #, 183 bajtów

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

Anonimowa metoda, która zwraca tablicę ciągów znaków, zawierającą najpierw liczbę niedziel, a następnie każdą niedzielę w określonym formacie. Jeśli w miesiącu są tylko 4 niedziele, ostatni ciąg jest pusty.

Pełny program z nieprzylepioną metodą i przypadkami testowymi:

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);
    }
}
adrianmp
źródło
0

REXX, 168 bajtów

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
idrougge
źródło
Myślę, że to nie działa z mniejszymi latami. Próbowałeś 1217?
Tytus
0

Bash + bsdmainutils, 94 bajty

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

Używa polecenia, calktóre drukuje kalendarz, jest domyślnie instalowane w kilku systemach UNIX / LINUX / BSD (niestety nie w TIO).

Aby spróbować go zapisać do file, chmod +x filei run./file 2017 9

Zapisuje w szyku pierwsze dwa bajty wyjścia calowego wraz z łańcuchem „MM-RRRR” przekazanym jako drugi i pierwszy parametr (wymaga zmiany, jeśli ustawienia regionalne nie rozpoczynają się w niedziele przez kilka tygodni).

Następnie echo długości tablicy odejmowanej przez jeden (pierwszy element to słowo reprezentujące niedzielę) i tablica bez pierwszego elementu, po jednym w wierszu fmt -1

marcosm
źródło
Obsługuje specjalny przypadek 1752 9
marcosm 11.04.17
0

SAS, 182 bajty

%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;
J_Lard
źródło
0

T-SQL, 316 311 bajtów

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

Nie wiem jednak, czy jest to poprawna odpowiedź, ponieważ podaje liczbę niedziel po datach

Wypróbuj tutaj

bez golfa:

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
złapać rybę
źródło
0

PHP, 127 118 112 107 bajtów

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

pobiera dane wejściowe z argumentów wiersza poleceń; uruchom go -rlub przetestuj online .

awaria

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
Tytus
źródło
0

Excel VBA, 190 bajtów

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

Przykładowe dane wyjściowe dla p (2000, 1) (nie jestem pewien, czy to się kwalifikuje)

02-01-2000 
09-01-2000 
16-01-2000 
23-01-2000 
30-01-2000 
 5 
Stupid_Intern
źródło