Planeje seus domingos!


16

Quem não gosta de relaxar em uma manhã de domingo no verão com uma cerveja gelada e TV ou no inverno jogando badminton ou jogando com amigos?

Eu sempre acho que saber quantos dias você precisa relaxar por mês mantém você bem informado e ajuda a planejar o que você quer fazer. Seja na frente do seu PC e resolvendo um problema de código-golfe ou saindo para jogar futebol.

Então, me ajudar a escrever um programa ou função que toma como entrada 2 inteiros positivos, Ye Me emite o número de domingos, nesse ano ( Y) e mês (M ) (de acordo com o calendário gregoriano), seguido da data de cada domingo.

Além disso, lembre-se de que o código mais curto vence.

Restrições de entrada

1000 <= Y <= 9999

1 <= M <= 12

Resultado

Esses casos de teste terão saída e terão as datas de cada domingo daquele mês naquele ano no formato DD-MM-YYYY .

Casos de teste de amostra

Caso de teste 1

Entrada de amostra

2017 1

Saída de amostra

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

Caso de teste 2

Entrada de amostra

2018 2

Saída de amostra

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

Caso de teste 3

Entrada de amostra

2016 11

Saída de amostra

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

2
Eu recomendo permitir qualquer formato de data, incluindo um Date()objeto, e qualquer formato de saída, incluindo [4, [<dateobj>, <dateobj>, <dateobj>, <dateobj>]](onde <dateobj>é um objeto de data real e []é uma matriz real).
precisa saber é o seguinte

2
Quando o formato de saída é a parte definidora de um desafio, o consenso da comunidade é que é chato. No futuro, eu recomendo usar o Sandbox, mas como ninguém respondeu ainda, você pode se safar de alterá-lo.
wizzwizz4

1
Eu vou fazer uma edição. Você pode reverter se achar que isso prejudica o desafio.
Wizzwizz4

1
Então, quão flexível é o formato de saída? Por exemplo, ele pode ter em /vez de -? Ou pode ser mês, depois dia e ano?
Luis Mendo

1
Alguma localidade em particular? Observe que, antes de 1582, o calendário juliano era de uso comum, com países em transição para gregoriano até 1952 para a Grécia. Na Inglaterra, eles avançaram 11 dias no mês de setembro de 1752, levando a tumultos em massa. A recomendação é usar algo chamado "Calendário Gregoriano Proléptico", que finge que o calendário atual estava em uso o mais tardar possível.

Respostas:


0

MATL , 46 45 42 35 bytes

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

Entrada é uma matriz do formulário [2017 1]. O formato de saída é 29/01/2017.

Experimente online! Ou verifique todos os casos de teste .

Explicação

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

Isso funciona com datas mais antigas (como o ano 1217)?
Titus


Woops não viu o TiO.
Titus

4

Python 2 , 150.148, 145 bytes

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)

Experimente online!

-3 bytes, tornando as coisas mais pitônicas (usando zip e filtro!)


Vai ser 150 se você levar a declaração de impressão até a linha anterior e se você adicionar '02' no primeiro% d na linha 3.
Koishore Roy

'02' no primeiro% d! Hã. perdeu isso. Obrigado! enfim. salvou dois bytes embora em vez de aumentar em dois!
Keerthana Prabhakaran

4

JavaScript (ES6), 107 bytes

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>

Editar: a adição de uma contagem explícita custa 15 bytes. A formatação da saída custaria pelo menos outros 33 bytes, dependendo da rigidez do formato de saída.


> outputs the number of Sundays in that particular year and month; parece que atualmente não gera o número de domingos.
numbermaniac

Você poderia usar <input type='date'>.
Matthew Roh

@SIGSEGV Ainda não há suporte no Firefox, que é o que eu uso.
Neil

2
@Neil Use Chrome m8
Matthew Roh

3
@SIGSEGV Gosto menos do Chrome que do Internet Explorer.
Neil

2

PowerShell , 91 bytes

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

Experimente online!

(Nota especial - isso depende das configurações de local e cultura. Como o TIO está sendo executado comoen-us , funciona corretamente como está. Este código pode precisar ser alterado para diferentes locais.)

Leva a entrada como dois inteiros $ye $m. Faz um loop de 1para 31, obtendo um novo datetimeobjeto para cada data possível (por meio do Get-Datecmdlet). Lança erros no STDERR (ignorado por padrão nos desafios de código-golfe) por meses com menos de 31 dias, mas isso não afeta a saída. Pegamos cada um desses datetimeobjetos e usamos um Where-Object( |?{...}) neles, com a cláusula de !$_.dayofweek. A propriedade .dayofweeké um número de 0a 6, com 0convenientemente correspondente a Sunday, portanto, isso !é verdade, o que economiza alguns bytes em comparação com uma verificação de igualdade como -eq0.

Os domingos são então reunidos em parênteses e armazenados em $a. Em seguida, pegamos o .countmesmo e ele é colocado no pipeline. Em seguida, percorremos $ae usamos o -foperador ormat para construir o formato de saída correto. Observe que isso não gera zeros à esquerda por dias ou meses. Essas seqüências de datas também são deixadas no pipeline e um implícito Write-Outputna conclusão do programa as imprime com separadores de nova linha.


NB - se o formato de saída fosse mais flexível, poderíamos simplesmente sair $ado pipeline e não precisarmos fazer um loop. Isso definirá os datetimeobjetos como o formato de data longa, incluindo informações de hora, mas nos reduzirá a 69 bytes , que (atualmente) seriam vencidos apenas pelo Mathematica e MATL.


1

Oitava, 72 bytes

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

nweekdateretorna o número da data correspondente à N-ésima ocorrência de um determinado dia da semana no mês / ano especificado. Usamos a matriz 1:6no lugar de Npara obter todas as ocorrências em um mês. Se houver menos que Nocorrências desse dia da semana em um mês, o número da data resultante será 0. Por esse motivo, selecionamos apenas as datas válidas (x>1)e as convertemos em strings usando datestr.

Para contar o número de domingos, contamos o número de números diferentes de zero ( nnz) no resultado.

Em seguida, agrupamos a coisa inteira cellfunpara exibir cada valor.


0

Ruby, 140 132 129 118 bytes

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 caracteres

Coloque o ano na célula A1e o mês na célulaA2 .

A contagem está na célula D1e os domingos nas célulasD2:D6 .

Supõe que D2:D6estão formatados DD-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 bytes

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

Função anônima. Produz uma lista do número de dias, seguida por uma lista dos domingos como DateObjects. Acontece que no Mathematica, o 0º dia de um mês é interpretado como o último dia do mês anterior.


0

C #, 183 bytes

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

Método anônimo que retorna uma matriz de cadeias de caracteres, contendo primeiro o número de domingos e depois todos os domingos no formato especificado. Se houver apenas 4 domingos em um mês, a última sequência será nula.

Programa completo com método não destruído e casos de teste:

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 bytes

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

Eu acho que isso não funciona com anos menores. Você já tentou 1217?
Titus

0

Bash + bsdmainutils, 94 bytes

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

Usa o comando cal que imprime um calendário e é instalado por padrão em vários UNIX / LINUX / BSD (infelizmente não no TIO).

Para tentar salvar para file, chmod +x filee prazo./file 2017 9

Salva na matriz os dois primeiros bytes de saída de calibração anexados à string "MM-AAAA", passados ​​como segundo e primeiro parâmetros (as alterações serão alteradas se o código do idioma não iniciar semanas aos domingos).

O próximo eco da matriz é subtraído por um (primeiro elemento é a palavra que representa domingo) e a matriz sem o primeiro elemet, um por linha fmt -1


Ele lida caso especial 1,752 9
marcosm

0

SAS, 182 bytes

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

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

Não sei se é uma resposta válida, pois gera o número de domingos após as datas

Experimente aqui

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 bytes

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

recebe entrada de argumentos de linha de comando; executar -rou testá-lo online .

demolir

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 bytes

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

Saída de amostra para p (2000, 1) (não tenho certeza se isso se qualifica)

02-01-2000 
09-01-2000 
16-01-2000 
23-01-2000 
30-01-2000 
 5 
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.