Плануйте свої неділі!


16

Хто не любить влітку в неділю влітку охолоджувати пиво та телевізор, а взимку грати в бадмінтон чи інтим з друзями?

Я завжди думаю, що знаючи, скільки днів вам потрібно застудити за місяць, ви добре обізнані і допомагаєте планувати, що ви хочете робити. Будь то сидіти перед ПК та вирішувати проблему з кодом-гольф або збиратися грати у футбол.

Отже, допоможіть мені написати програму або функцію, яка приймає за вхід 2 натуральних числа, Yі Mвиводить кількість неділь у тому конкретному році ( Y) та місяці ( M) (згідно з Григоріанським календарем) з наступною датою кожної неділі.

Також пам’ятайте, що виграє найкоротший код.

Обмеження введення

1000 <= Y <= 9999

1 <= М <= 12

Вихідні дані

Ці тестові випадки матимуть вихідні дані у форматі кожної неділі цього місяця цього року DD-MM-YYYY.

Зразки тестових випадків

Тестовий випадок 1

Зразок введення

2017 1

Вибірка зразка

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

Тестовий випадок 2

Зразок введення

2018 2

Вибірка зразка

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

Тестовий випадок 3

Зразок введення

2016 11

Вибірка зразка

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

2
Я рекомендую дозволяючи будь-який формат дати, включаючи Date()об'єкт, і будь-який вихідний формат, в тому числі [4, [<dateobj>, <dateobj>, <dateobj>, <dateobj>]](де <dateobj>є актуальним завданням дата і []є фактичним масив).
wizzwizz4

2
Коли вихідний формат є визначальною частиною виклику, консенсус громади полягає в тому, що це нудно. Надалі я рекомендую використовувати «Пісочницю», але так як ніхто ще не відповів, ви можете уникнути її зміни.
wizzwizz4

1
Я зроблю редагування. Ви можете повернути його назад, якщо вважаєте, що це завдає шкоди проблемі.
wizzwizz4

1
То наскільки гнучким є вихідний формат? Наприклад, чи може це мати /замість -? Або це може бути місяць, то день, то рік?
Луїс Мендо

1
Якийсь конкретний локал? Зауважимо, що до 1582 року Юліанський календар використовувався загальним користуванням, а країни перейшли до Грегоріанського аж до 1952 року для Греції. В Англії вони стрибали календар попереду на 11 днів у вересні місяця 1752 року, що призвело до масових заворушень. Рекомендація полягає в тому, щоб використовувати щось, що називається "Пролептичний григоріанський календар", який робить вигляд, що поточний календар використовувався стільки, скільки вам потрібно.

Відповіді:


0

MATL , 46 45 42 35 байт

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

Введення - це масив форми [2017 1]. Формат виводу є 29/01/2017.

Спробуйте в Інтернеті! Або перевірити всі тестові випадки .

Пояснення

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

Чи працює це з більш старими датами (наприклад, рік 1217)?
Тит


Woops не бачили TiO.
Тит

4

Python 2 , 150,148, 145 байт

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)

Спробуйте в Інтернеті!

-3 байти, що робить речі більш пітонічними (використовуючи блискавку та фільтр!)


Це буде 150, якщо ви приведете заявку до друку до попереднього рядка, і якщо ви додасте "02" у першому% d у рядку 3.
Koishore Roy

'02' у першому% d! так. пропустив це. Спасибі! все одно. збережено два байти, хоча замість збільшення на два!
Keerthana Prabhakaran

4

JavaScript (ES6), 107 байт

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>

Редагування: додавання явного рахунку коштує 15 байт. Форматування результату коштуватиме щонайменше ще 33 байти залежно від того, наскільки жорсткий вихідний формат.


> outputs the number of Sundays in that particular year and month; Схоже, це наразі не видає кількість неділь.
numbermaniac

Ви можете використовувати <input type='date'>.
Меттью Рох

@SIGSEGV Ще не підтримується у Firefox, що я використовую.
Ніл

2
@Neil Використовуйте Chrome m8
Matthew Roh

3
@SIGSEGV Мені подобається Chrome ще менше, ніж Internet Explorer.
Ніл

2

PowerShell , 91 байт

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

Спробуйте в Інтернеті!

(Спеціальна примітка - це залежать від параметрів місцевості та культури. Оскільки TIO працює як такийen-us , він працює правильно так, як є. Цей код може знадобитися змінити для різних локалів.)

Приймає вхід у вигляді двох цілих чисел $yі $m. Цикли від 1до 31, отримуючи новий datetimeоб'єкт для кожної можливої ​​дати (через Get-Dateкомандлет). Буде викинуто помилки на STDERR (ігнорується за замовчуванням у кодово-гольф-викликах) протягом місяців з меншим числом, ніж 31 день, але це не впливає на вихід. Ми беремо кожен із цих datetimeоб'єктів і використовуємо Where-Object( |?{...}) на них, із пунктом!$_.dayofweek . Властивість .dayofweekє число від 0до 6, з 0зручно , відповідними Sunday, так що !з цього є truthy, що економить пару байт по порівнянні з перевіркою рівності як -eq0.

Потім неділі збираються в паренах і зберігаються в $a . Потім ми беремо .countїх, і це розміщується на трубопроводі. Далі ми перебираємо $aта використовуємо -fоператор ormat, щоб побудувати правильний вихідний формат. Зауважте, що це не видає провідні нулі днями і місяцями. Ці рядки дат також залишаються на конвеєрі, і неявна Write-Outputпри завершенні програми друкує їх роздільниками нових рядків.


Зверніть увагу: якщо формат виводу був більш гнучким, ми могли б просто піти $a на конвеєрі і не потрібно перебирати його. Це об'єктивує datetimeоб'єкти як формат давніх дат, включаючи інформацію про час, але зводить нас до 69 байт , які (на даний момент) били лише Mathematica та MATL.


1

Октава, 72 байти

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

nweekdateповертає номер дати, що відповідає N-му виникненню певного будня в зазначеному місяці / році. Ми використовуємо масив 1:6замість, Nщоб отримати всі події за місяць. Якщо Nцього тижня в місяць буває менше випадків, то одержуваний номер дати є 0. З цієї причини ми вибираємо лише дійсні дати за допомогою (x>1)та перетворюємо їх у рядки за допомогою datestr.

Тоді для підрахунку кількості неділь ми підраховуємо кількість ненульових ( nnz) номерів дат у результаті.

Потім ми загортаємо всю річ, cellfunщоб відобразити кожне значення.


0

Рубі, 140 132 129 118 байт

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 символи

Помістіть рік у комірці A1та місяць у комірціA2 .

Кількість - у комірці D1, а неділя - у клітинкахD2:D6 .

Припускаємо, що D2:D6вони відформатовані 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

Математика, 82 68 байт

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

Анонімна функція. Виводить список кількості днів, а потім список неділей як DateObjects. Виявляється, в Mathematica 0-й день місяця трактується як останній день попереднього місяця.


0

C #, 183 байт

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

Анонімний метод, який повертає масив рядків, що містить спочатку число неділей, а потім кожну неділю у вказаному форматі. Якщо в місяць є лише 4 неділі, останній рядок є нульовим.

Повна програма з методом unolfolf та тестовими кейсами:

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 байт

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

Я думаю, що це не працює з меншими роками. Ви пробували 1217?
Тит

0

Bash + bsdmainutils, 94 байти

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

Використовує команду cal яка друкує календар, за замовчуванням встановлюється в декількох UNIX / LINUX / BSD (на жаль, не в TIO).

Для того, щоб спробувати зберегти на file, chmod +x fileі запустити./file 2017 9

Зберігає для масиву перші два байти виведення кал, додані до рядка "MM-YYYY", передані як другий і перший параметри (потребує змін, якщо ваш локальний не починається тижнями по неділях).

Далі лунає довжина масиву, підкреслена одним (перший елемент - слово, що представляє неділю) та масив без першого елементу, по одному на рядок fmt -1


Він обробляє спеціальний корпус 1752 9
маркосм

0

SAS, 182 байти

%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 байт

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

Я не знаю, чи це правдива відповідь, оскільки вона видає кількість неділей після дат

Спробуйте тут

неозорений:

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 байт

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

приймає дані з аргументів командного рядка; запустити -rабо випробувати його в Інтернеті .

зламатися

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 байт

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) (не впевнений, чи відповідає це)

02-01-2000 
09-01-2000 
16-01-2000 
23-01-2000 
30-01-2000 
 5 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.