Organizza le tue domeniche!


16

A chi non piace rilassarsi una domenica mattina d'estate con una birra e una TV refrigerata o d'inverno giocando a badminton o alla grande con gli amici?

Penso sempre che sapere quanti giorni devi rilassarti in un mese ti mantenga ben informato e ti aiuti a pianificare ciò che vuoi fare. Sia seduto davanti al tuo PC e risolvendo un problema di code-golf o uscendo a giocare a calcio.

Quindi, aiutami a scrivere un programma o una funzione che accetta come input 2 numeri interi positivi Ye Mche genera il numero di domeniche in quel particolare anno ( Y) e mese ( M) (secondo il calendario gregoriano), seguito dalla data di ogni domenica.

Inoltre, tieni presente che vince il codice più corto.

Vincoli di input

1000 <= Y <= 9999

1 <= M <= 12

Produzione

Questi casi di test avranno un output con le date di ogni domenica di quel mese in quell'anno nel formato DD-MM-YYYY.

Esempi di casi di test

Caso di prova 1

Input di esempio

2017 1

Uscita campione

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

Caso di prova 2

Input di esempio

2018 2

Uscita campione

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

Caso di prova 3

Input di esempio

2016 11

Uscita campione

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

2
Consiglio di consentire qualsiasi formato di data, incluso un Date()oggetto, e qualsiasi formato di output, incluso [4, [<dateobj>, <dateobj>, <dateobj>, <dateobj>]](dove si <dateobj>trova un oggetto data effettivo ed []è un array effettivo).
wizzwizz4,

2
Quando il formato di output è la parte che definisce una sfida, il consenso della comunità è che è noioso. In futuro consiglio di usare il Sandbox, ma dato che nessuno ha ancora risposto, potresti farcela cambiando.
wizzwizz4,

1
Farò una modifica. Puoi farlo tornare indietro se pensi che danneggi la sfida.
wizzwizz4,

1
Quindi quanto è flessibile il formato di output? Ad esempio, può avere /invece di -? O può essere il mese, quindi il giorno, quindi l'anno?
Luis Mendo,

1
Qualche locale in particolare? Si noti che prima del 1582, il calendario giuliano era di uso comune, con i paesi che passavano a Gregoriano nel 1952 per la Grecia. In Inghilterra saltarono il calendario in avanti di 11 giorni nel mese di settembre 1752, portando a rivolte di massa. La raccomandazione è di usare qualcosa chiamato "Calendario Gregoriano Prolettico" che finge che il calendario attuale fosse in uso per tutto il necessario.

Risposte:


0

MATL , 46 45 42 35 byte

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

L'input è un array del modulo [2017 1]. Il formato di output è 29/01/2017.

Provalo online! Oppure verifica tutti i casi di test .

Spiegazione

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

Funziona con date precedenti (come l'anno 1217)?
Tito


Woops non ha visto il TiO.
Tito

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)

Provalo online!

-3 byte che rendono le cose più pitoniche (usando zip e filtro!)


Saranno 150 se porti l'istruzione print alla riga precedente e se aggiungi '02' nella prima% d nella riga 3.
Koishore Roy

'02' nel primo% d! eh. perso quello. Grazie! in ogni modo. salvato due byte invece di aumentare di due!
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>

Modifica: l'aggiunta di un conteggio esplicito costa 15 byte. La formattazione dell'output costerebbe almeno altri 33 byte a seconda della rigidità del formato di output.


> outputs the number of Sundays in that particular year and month; sembra che al momento non venga visualizzato il numero di domeniche.
numbermaniac

Puoi usare <input type='date'>.
Matthew Roh,

@SIGSEGV Non ancora supportato in Firefox, che è quello che uso.
Neil,

2
@Neil Usa Chrome m8
Matthew Roh

3
@SIGSEGV Mi piace Chrome anche meno di Internet Explorer.
Neil,

2

PowerShell , 91 byte

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

Provalo online!

(Nota speciale: dipende dalle impostazioni locali e della cultura. Poiché TIO è in esecuzione comeen-us , funziona correttamente lì così com'è. Potrebbe essere necessario modificare questo codice per impostazioni locali diverse.)

Accetta input come due numeri interi $ye $m. Passa da 1a 31, ottenendo un nuovo datetimeoggetto per ogni data possibile (tramite il Get-Datecmdlet). Genererà errori su STDERR (ignorato per impostazione predefinita nelle sfide del code-golf) per mesi con meno di 31 giorni, ma ciò non influisce sull'output. Prendiamo ciascuno di quegli datetimeoggetti e usiamo un Where-Object( |?{...}) su di essi, con la clausola di !$_.dayofweek. La proprietà .dayofweekè un numero da 0a 6, con 0convenientemente corrispondente a Sunday, quindi il !che è vero, che consente di risparmiare un paio di byte rispetto a un controllo di uguaglianza simile -eq0.

Le domeniche vengono quindi raccolte in parentesi e conservate in $a. Quindi prendiamo il .countsuo, e questo è posto sulla pipeline. Successivamente, eseguiamo il loop $ae utilizziamo l' -foperatore ormat per costruire il formato di output corretto. Si noti che ciò non genera zero iniziali per giorni o mesi. Anche quelle stringhe di date vengono lasciate sulla pipeline e un implicito Write-Outputal completamento del programma le stampa con i separatori di nuova riga.


NB: se il formato di output fosse più flessibile, potremmo semplicemente abbandonare $ala pipeline e non è necessario eseguirne il loop. Ciò restringerà gli datetimeoggetti come formato di data estesa , comprese le informazioni sull'ora, ma ci porterà fino a 69 byte , che (attualmente) sarebbero battuti solo da Mathematica e MATL.


1

Ottava, 72 byte

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

nweekdaterestituisce il numero della data corrispondente Nall'occorrenza di un determinato giorno della settimana nel mese / anno specificato. Usiamo l'array 1:6al posto di Nper ottenere tutte le occorrenze in un mese. Se ci sono meno di Noccorrenze di quel giorno della settimana in un mese, allora il numero della data risultante è 0. Per questo motivo, selezioniamo solo le date valide utilizzando (x>1)e quindi le convertiamo in stringhe utilizzando datestr.

Quindi per contare il numero di domeniche, contiamo il numero di numeri di data diversi da zero ( nnz) nel risultato.

Quindi avvolgiamo il tutto cellfunper visualizzare ogni valore.


0

Rubino, 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 caratteri

Metti l'anno in cella A1e il mese in cella A2.

Il conteggio è in cella D1e la domenica in celle D2:D6.

I presupposti D2:D6sono formattati GG-MM-AAAA.

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

Funzione anonima. Emette un elenco del numero di giorni, seguito da un elenco delle domeniche come DateObjects. Risulta, in Mathematica il 0 ° giorno di un mese viene interpretato come l'ultimo giorno del mese precedente.


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

Metodo anonimo che restituisce una matrice di stringhe, contenente prima il numero di domeniche e poi ogni domenica nel formato specificato. Se ci sono solo 4 domeniche in un mese, l'ultima stringa è nulla.

Programma completo con metodo non golfizzato e casi di test:

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

Immagino che questo non funzioni con anni più piccoli. Ci hai provato 1217?
Tito

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}

Utilizza il comando calche stampa un calendario, è installato di default in diversi UNIX / LINUX / BSD (purtroppo non in TIO).

Per provarlo Salva file, chmod +x filee corsa./file 2017 9

Salva per allineare i primi due byte dell'output cal aggiunto con la stringa "MM-AAAA" passata come secondo e primo parametro (deve essere modificata se la propria locale non inizia settimane la domenica).

Gli echi successivi vengono sottratti alla lunghezza dell'array da uno (il primo elemento è la parola che rappresenta la domenica) e l'array senza il primo elemet, uno per riga fmt -1


Gestisce caso speciale 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

Non so se sia una risposta valida, dato che genera il numero di domeniche dopo le date

Provalo qui

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;

accetta input dagli argomenti della riga di comando; eseguirlo -ro testarlo online .

abbattersi

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

Output di esempio per p (2000, 1) (non sono sicuro se questo si qualifica)

02-01-2000 
09-01-2000 
16-01-2000 
23-01-2000 
30-01-2000 
 5 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.