¡Planifica tus domingos!


16

¿A quién no le gusta relajarse un domingo por la mañana en verano con una cerveza fría y la televisión o en invierno jugando al bádminton o al máximo con amigos?

Siempre pienso que saber cuántos días tienes para relajarte en un mes te mantiene bien informado y te ayuda a planificar lo que quieres hacer. Ya sea sentado frente a su PC y resolviendo un problema de código de golf o saliendo a jugar al fútbol.

Así que me ayudan a escribir un programa o función que toma como entrada 2 enteros positivos, Yy My emite el número de domingos en ese año en particular ( Y) y mes ( M) (según el calendario gregoriano), seguido de la fecha de cada domingo.

Además, tenga en cuenta que gana el código más corto.

Restricciones de entrada

1000 <= Y <= 9999

1 <= M <= 12

Salida

Estos casos de prueba tendrán salida tendrán las fechas de cada domingo de ese mes en ese año en el formato DD-MM-YYYY.

Ejemplos de casos de prueba

Caso de prueba 1

Entrada de muestra

2017 1

Salida de muestra

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

Caso de prueba 2

Entrada de muestra

2018 2

Salida de muestra

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

Caso de prueba 3

Entrada de muestra

2016 11

Salida de muestra

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

2
Recomiendo permitir cualquier formato de fecha, incluido un Date()objeto, y cualquier formato de salida, incluido [4, [<dateobj>, <dateobj>, <dateobj>, <dateobj>]](donde <dateobj>es un objeto de fecha real y []es una matriz real).
wizzwizz4

2
Cuando el formato de salida es la parte definitoria de un desafío, el consenso de la comunidad es que es aburrido. En el futuro, recomiendo usar el Sandbox, pero como nadie ha respondido aún, podría salirse con la suya.
wizzwizz4

1
Haré una edición. Puedes revertirlo si crees que daña el desafío.
wizzwizz4

1
Entonces, ¿qué tan flexible es el formato de salida? Por ejemplo, ¿puede tener en /lugar de -? ¿O puede ser mes, luego día, luego año?
Luis Mendo

1
¿Alguna localidad en particular? Tenga en cuenta que antes de 1582, el calendario juliano era de uso común, con países que hicieron la transición al gregoriano en 1952 para Grecia. En Inglaterra saltaron el calendario 11 días antes en el mes de septiembre de 1752, lo que provocó disturbios masivos. La recomendación es usar algo llamado el "Calendario Gregoriano Proleptico" que finge que el calendario actual estuvo en uso durante el tiempo que usted necesita.

Respuestas:


0

MATL , 46 45 42 35 bytes

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

La entrada es una matriz del formulario [2017 1]. El formato de salida es 29/01/2017.

Pruébalo en línea! O verificar todos los casos de prueba .

Explicación

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

¿Funciona esto con fechas anteriores (como el año 1217)?
Titus


Woops no vio el 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)

Pruébalo en línea!

-3 bytes haciendo cosas más pitónicas (¡usando zip y filtro!)


Serán 150 si lleva la declaración de impresión a la línea anterior y si agrega '02' en el primer% d en la línea 3.
Koishore Roy

'02' en el primer% d! eh se lo perdí. ¡Gracias! de todos modos ¡ahorró dos bytes en lugar de aumentar en dos!
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: Agregar un recuento explícito cuesta 15 bytes. Formatear la salida costaría al menos otros 33 bytes dependiendo de cuán estricto sea el formato de salida.


> outputs the number of Sundays in that particular year and month; parece que esto no genera actualmente la cantidad de domingos.
numbermaniac

Podrías usar <input type='date'>.
Matthew Roh el

@SIGSEGV Todavía no es compatible con Firefox, que es lo que uso.
Neil

2
@Neil Use Chrome m8
Matthew Roh

3
@SIGSEGV Me gusta Chrome incluso menos que Internet Explorer.
Neil

2

PowerShell , 91 bytes

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

Pruébalo en línea!

(Nota especial: esto depende de la configuración regional y cultural. Dado que TIO se está ejecutando comoen-us , funciona correctamente allí como está. Es posible que sea necesario cambiar este código para diferentes configuraciones regionales).

Toma la entrada como dos enteros $yy $m. Recorre de 1a 31, obteniendo un nuevo datetimeobjeto para cada fecha posible (a través del Get-Datecmdlet). Lanzará errores a STDERR (ignorado por defecto en los desafíos de código de golf) durante meses con menos de 31 días, pero eso no afecta la salida. Tomamos cada uno de esos datetimeobjetos y usamos un Where-Object(|?{...} ) en ellos, con la cláusula de !$_.dayofweek. La propiedad .dayofweekes un número desde 0hasta 6, con 0convenientemente correspondiente a Sunday, por lo que el !de eso es verdadero, lo que ahorra un par de bytes en comparación con una verificación de igualdad como -eq0.

Los domingos se reúnen en parejas y se almacenan en $a. Luego tomamos el .countmismo, y eso se coloca en la tubería. Luego, recorremos $ay usamos el -foperador ormat para construir el formato de salida correcto. Tenga en cuenta que esto no genera ceros iniciales durante días o meses. Esas cadenas de fecha también se dejan en la tubería, y un implícito Write-Outputal finalizar el programa las imprime con separadores de nueva línea.


Nota: si el formato de salida fuera más flexible, podríamos dejarlo $aen la tubería y no tener que recorrerlo. Eso encadenará los datetimeobjetos como el formato de fecha larga, incluida la información de tiempo, pero nos lleva a 69 bytes , que (actualmente) solo serían superados por Mathematica y MATL.


1

Octava, 72 bytes

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

nweekdatedevuelve el número de fecha correspondiente a la Nenésima aparición de un día de la semana en particular en el mes / año especificado. Usamos la matriz 1:6en lugar de Npara obtener todas las ocurrencias en un mes. Si hay menos de las Nocurrencias de ese día de la semana en un mes, entonces el número de fecha resultante es 0. Por esta razón, seleccionamos solo las fechas válidas usando (x>1)y luego las convertimos en cadenas usando datestr.

Luego, para contar el número de domingos, contamos el número de números de fecha que no son cero ( nnz) en el resultado.

Luego envolvemos todo cellfunpara mostrar cada valor.


0

Rubí, 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

Ponga el año en la celda A1y el mes en la celda A2.

El recuento está en la celda D1y los domingos en las celdas D2:D6.

Los supuestos D2:D6tienen formato 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}&

Función anónima. Emite una lista de la cantidad de días, seguida de una lista de domingos como DateObjects. Resulta que, en Mathematica, el día 0 de un mes se interpreta como el último día del mes 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 devuelve una matriz de cadenas, que contiene primero el número de domingos y luego cada domingo en el formato especificado. Si solo hay 4 domingos en un mes, la última cadena es nula.

Programa completo con método no protegido y casos de prueba:

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

Supongo que esto no funciona con años más pequeños. ¿Lo has intentado 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}

Utiliza el comando cal que imprime un calendario, se instala por defecto en varios UNIX / LINUX / BSD (desafortunadamente no en TIO).

Para probarlo Guardar file, chmod +x filey de ejecución./file 2017 9

Se guarda para agrupar los primeros dos bytes de salida de cal anexados con la cadena "MM-AAAA" que se pasa como segundo y primer parámetro (debe cambiar si su configuración regional no comienza semanas los domingos).

El siguiente eco suscribe la longitud de la matriz sustraída por uno (el primer elemento es la palabra que representa el domingo) y la matriz sin el primer elemento, uno por línea fmt -1


Maneja el caso especial 1752 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

Sin embargo, no sé si es una respuesta válida, ya que genera la cantidad de domingos después de las fechas

Pruébalo aquí

sin golf:

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;

toma datos de los argumentos de la línea de comandos; correr -ro probarlo en línea .

Descompostura

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

Salida de muestra para p (2000, 1) (no estoy seguro si esto califica)

02-01-2000 
09-01-2000 
16-01-2000 
23-01-2000 
30-01-2000 
 5 
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.