Hoy es el centro

36

Dada una fecha como entrada en cualquier formato conveniente, imprima un calendario con esa fecha como el centro exacto de una ventana de cinco semanas. El encabezado del calendario debe incluir las abreviaturas de dos letras para los días de la semana (es decir, Su Mo Tu We Th Fr Sa). No se permiten abreviaturas de tres letras u otras de los días.

Por ejemplo, dado April 2 2019como entrada, la salida debe ser

Sa Su Mo Tu We Th Fr
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31  1  2  3  4  5
 6  7  8  9 10 11 12
13 14 15 16 17 18 19

para que la fecha dada sea la mitad exacta del calendario.

Dado February 19 2020, salida

Su Mo Tu We Th Fr Sa
 2  3  4  5  6  7  8
 9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
 1  2  3  4  5  6  7

Para September 14 1752, muestre lo siguiente:

Mo Tu We Th Fr Sa Su
28 29 30 31  1  2  3
 4  5  6  7  8  9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30  1

  • La entrada y salida se pueden dar por cualquier método conveniente .
  • La entrada está garantizado que no esté vacía y válido (es decir, nunca se recibirá ""o Feb 31etc.).
  • Asumir calendario gregoriano para todas las fechas.
  • Los años bisiestos deben tenerse en cuenta.
  • Las fechas de entrada variarán de Jan 1 1600a Dec 31 2500.
  • Puede imprimirlo en STDOUT o devolverlo como resultado de una función.
  • Un programa completo o una función son aceptables.
  • Cualquier cantidad de espacios en blanco extraños es aceptable, siempre y cuando los caracteres se alineen apropiadamente.
  • Se permiten ceros a la izquierda en los días de un solo dígito, al igual que la alineación de los días de un solo dígito para alinearse a la izquierda.
  • Las lagunas estándar están prohibidas.
  • Este es el por lo que se aplican todas las reglas habituales de golf, y gana el código más corto (en bytes).
AdmBorkBork
fuente

Respuestas:

12

R , 77 72 bytes

function(d,`~`=format)write(c(strtrim(d+-3:3~"%a",2),d+-17:17~"%e"),1,7)

Pruébalo en línea!

Salida fija para usar abreviaturas de 2 letras por día.

-1 byte usando strtrimgracias a Aaron Hayman .

Los números de fecha de las almohadillas con ceros a la izquierda; toma la entrada como a Date, que se puede crear usando as.Date("YYYY/MM/DD").

Extrañamente corto para una respuesta de R ...

Giuseppe
fuente
8

05AB1E , 175 174 172 171 160 bytes

¦WΘ1š-1šVтFY`2ô0Kθ4ÖUD2Qi\28X+ë<7%É31α}‹iY¬>0ëY1¾ǝDÅsD12‹i>1ë\1Dǝ¤>2}}ǝVY})DJIJk18+£35.£¬.•4ιõ÷‡o‹ƶ¸•2ôs`UÐ3‹12*+>13*5÷s3‹Xα©т%D4÷®т÷©4÷®·()DćsćsO7%._s€нT‰J«7ô»

Entrada en el formato [day, month, year]. Salida con 0s iniciales para días de un solo dígito y minúsculas mohasta su(se puede agregar +1 byte si titlecase es obligatorio).

Pruébelo en línea o verifique todos los casos de prueba .

Santa mierda ... Este podría ser mi nuevo récord para la respuesta más larga 05AB1E, y luego incluyo algunos desafíos de asiatico muy complejos que hice ...>.> EDITAR: Hmm ok, casi ...; p

Nota importante: 05AB1E no tiene ninguna función integrada para los objetos o cálculos de fecha. Lo único que incluye las fechas que tiene es el año / mes / día / horas / minutos / segundos / microsegundos de hoy.

Por eso, casi todo el código que ve son cálculos manuales para calcular los días anteriores y siguientes (incluida la transición a lo largo de los años y teniendo en cuenta los años bisiestos), y calcular el día de la semana utilizando la congruencia de Zeller .

Enormes partes del código se copian de esta respuesta anterior de 05AB1E mía , que también será relevante para la explicación a continuación.

Explicación:

Comenzamos yendo al primer día del mes anterior:

¦          # Remove the first item (the days) from the (implicit) input
 W         # Get the minimum (without popping the list itself)
           # (since the year is guaranteed to be above 1599, this is the month)
  Θ        # Check if its exactly 1 (1 if 1, 0 if in the range [2,31])
   1š      # Prepend a 1 as list (so we now have either [1,1] or [1,0]
     -     # Subtract this from the month and year
      1š   # And prepend a 1 for the day
        V  # Pop and store this first day of the previous month in variable `Y`

Luego uso esa fecha como fecha de inicio y calculo los próximos 100 días:

тF    # Loop 100 times:
  Y`2ô0Kθ4ÖUD2Qi\28X+ë<731α}‹iY¬>0ëY1¾ǝDÅsD12i>1ë\1Dǝ¤>2}}ǝV
      #  Calculate the next day in line
      #  (see the linked challenge above for a detailed explanation of this)
   Y  #  And leave it on the stack
 })   # After the loop: wrap the entire stack into a list, which contains our 100 days

Luego, con la fecha de entrada como el medio, solo dejo de la lista el 17 antes y el 17 después de esa fecha de entrada:

DJ          # Duplicate the 100 dates, and join the day/month/year together to strings
  IJ        # Push the input, also joined together
    k       # Get the 0-based index of the input in this list
            # (the joins are necessary, because indexing doesn't work for 2D lists)
     18+    # Add 18 to this index (18 instead of 17, because the index is 0-based)
        £   # Only leave the first index+18 items from the 100 dates
     35.£   # Then only leave the last 35 items

Ahora tenemos nuestros 35 días. El siguiente paso es calcular el día de la semana y crear el encabezado de la tabla de salida:

¬                # Get the first date of the list (without popping the list itself)
 .•4ιõ÷‡o‹ƶ¸•    # Push compressed string "sasumotuwethfr"
             2ô  # Split it into chunks of size 2
s                # Swap to get the first date again
 `UÐ312*+>13*5÷s3Xα©т%D4÷®т÷©4÷®·()DćsćsO7%
                 # Calculate the day of the week (sa=0; su=1; ...; fr=6)
                 # (see the linked challenge above for a detailed explanation of this)
  ._             # Rotate the list of strings that many times

Ver este consejo 05AB1E mío (sección Cómo comprimir cadenas que no forman parte del diccionario? ) Para entender por qué .•4ιõ÷‡o‹ƶ¸•es "sasumotuwethfr".

Luego creamos los días para llenar la tabla misma en función de nuestra lista de fechas creada anteriormente. Que fusionaremos junto con el encabezado. Después de lo cual podemos imprimir el resultado final:

s           # Swap to get the list of dates again
 €н         # Only leave the first item of each date (the days)
   T       # Take the divmod 10 of each
     J      # Join those divmod results together
            # (we now have leading 0s for single-digit days)
      «     # Merge this list together with the header list
       7ô   # Split it into chunks of size 7
         »  # Join each inner list by spaces, and then each string by newlines
            # (and output the result implicitly)
Kevin Cruijssen
fuente
2
¡Eso es una gran cantidad de trabajo!
Luis Mendo
2
¡Sí, Java supera a 05AB1E! : D Primera vez, supongo ;-)
Olivier Grégoire
@LuisMendo Most se hizo la última vez con el desafío vinculado, pero sí, fue mucho trabajo ...;) Por cierto, se agregó la explicación.
Kevin Cruijssen
@ OlivierGrégoire Ahora somos el mismo conteo de despedidas. ;)
Kevin Cruijssen
@ OlivierGrégoire Y ahora vuelve a bajar, lo siento. ; p
Kevin Cruijssen
6

JavaScript (ES6),  141126  bytes

Ahorró 15 bytes tomando prestado .toUTCString().slice(0,2)de la respuesta de Neil

Toma la entrada como un objeto de fecha.

f=(d,n=0)=>n<42?(D=new Date(d-864e5*(24-n)),n<7?D.toUTCString().slice(0,2):(i=D.getDate())>9?i:' '+i)+`
 `[++n%7&&1]+f(d,n):''

Pruébalo en línea!

Arnauld
fuente
Huh, podría haber jurado que mi código falló para el tercer caso de prueba cuando lo escribí originalmente ... bueno, eso me ahorra 52 bytes ...
Neil
4

JavaScript (Node.js) , 205 152 145 bytes

f=
d=>`012345`.replace(g=/./g,r=>`0123456
`.replace(g,c=>`${new Date(d-864e5*(24-c-r*7))[+r?`getUTCDate`:`toUTCString`]()}`.slice(0,2).padStart(3)))
<input type=date oninput=o.textContent=f(this.valueAsDate)><pre id=o>

Pruébalo en línea! Toma la entrada como objeto de fecha de JavaScript o marca de tiempo. Editar: guardado 1 byte gracias a @EmbodimentofIgnorance, que luego me permitió guardar otros 7 bytes agregando una nueva línea final a la salida. Ahorré 52 bytes cuando descubrí que estaba trabajando en un comportamiento que en realidad no tenía errores en primer lugar ...

Neil
fuente
padStart(2)-> padStart(3), elimina el espacio en la cadena de unión para -1 byte
Realización de la ignorancia
3

Perl 6 , 87 bytes

{~rotate(<Th Fr Sa Su Mo Tu We>,.day-of-week),|comb 21,($_-17..$_+17)>>.day.fmt('%2d')}

Pruébalo en línea!

Toma un Dateobjeto, devuelve una lista de líneas.

nwellnhof
fuente
2

Wolfram Language (Mathematica) , 123 bytes

(s=#;Grid@Join[{StringTake[ToString@DayName[s~d~#]&/@Range[-3,3],2]},Partition[Last@d[s,#]&/@Range[-17,17],7]])&
d=DatePlus

Pruébalo en línea!

No sé por qué Gridno funciona en TIO, pero este código genera esto

ingrese la descripción de la imagen aquí

@DavidC guardó 1 byte

J42161217
fuente
¿Tal vez Gridno funciona porque TIO no puede centrar los elementos como en su imagen?
AdmBorkBork
@AdmBorkBork Hay una manera de cargar gráficos como este en TIO. Alguien me había mostrado el año pasado, creo. Pero no recuerdo cómo hacerlo ... Entonces, si alguien lo sabe, ¡háganoslo saber!
J42161217
2

MATL , 34 33 31 bytes

YO-17:17+t7:)8XOO3Z(!1ew7XOU7e!

Pruébalo en línea!

Explicación

YO       % Implicit input. Convert to date number. This is a single number
         % that specifies the date
-17:17   % Push [-17 -16 ... 16 17]
+        % Add to date number, element-wise. This gives a row vector of 35
         % date numbers centered around the input date
t        % Duplicate
7:       % Push [1 2 ... 7]
)        % Index into the 35-element vector. This keeps the first 7 entries
8XO      % Convert to day-of-week in 3 letters. Gives a 3-col char matrix
O3Z(     % Write char 0 (equivalent to space for display purposes) into the
         % 3rd column
!1e      % Tranpose and linearize into a row. This produces a string such as
         % 'Tu We Th Fr Sa Su Mo ', to be used as column headings
w        % Swap. This brings to top the row vector of 35 date numbers
         % computed from the input
7XO      % Convert to day-of-month. Gives a 2-col char matrix
U        % Convert each row to number
7e!      % Reshape into 7-row matrix and transpose
         % Implicit display. This prints the string with the headings and
         % the matrix. The latter has a minimum-one-space separation between
         % columns, so it is aligned with the headings
Luis Mendo
fuente
2

Java (JDK) , 149 bytes

d->{d.add(5,-24);for(int i=0,w;i<42;d.add(5,1))System.out.printf("%c%2s",i%7<1?10:32,i++<7?"SaSuMoTuWeThFr".substring(w=d.get(7)%7*2,w+2):d.get(5));}

Pruébalo en línea!

Créditos

Olivier Grégoire
fuente
1
159 bytes
Kevin Cruijssen
1
@KevinCruijssen Espera ... ¿qué? ¡Te felicito! Traté de hacer esto, pero no pude encontrar una manera de hacerlo, ¡y aún así lo hiciste! Muy agradable :-)
Olivier Grégoire
1
¿Quizás ves algo más para combinar iy de jalguna manera? ¿O algo más corto j++%7<1?10:32con algo de magia bit a bit? Pero te lo dejo a ti. Voy a volver al trabajo, jajaja. ;)
Kevin Cruijssen
1
Ah, por supuesto ... ¡Buen trabajo en equipo! ;) PD: ¿Dónde está el wsoporte? ¿Por qué no hpara encabezado?
Kevin Cruijssen
1
@KevinCruijssen wpara "día de W eek". Además, el giro de bits solo puede conducir a (i%7+6)/7*22+10que sea mucho más largo.
Olivier Grégoire
2

PHP ,197 189 187 bytes

for($d=date_create($argn)->sub($i=new DateInterval(P17D)),$i->d=1;$x++<35;$h.=$x<8?substr($d->format(D),0,2).' ':'',$d->add($i))$o.=str_pad($d->format(j),3,' ',2);echo wordwrap($h.$o,20);

Pruébalo en línea!

La entrada es STDINcomo una cadena de fecha. Corre con php -nF.

$ echo April 2 2019|php -nF cal.php

Sa Su Mo Tu We Th Fr 
16 17 18 19 20 21 22 
23 24 25 26 27 28 29 
30 31  1  2  3  4  5 
 6  7  8  9 10 11 12 
13 14 15 16 17 18 19 

Verificar todos los casos de prueba

O 174 bytes con dígitos individuales rellenos con ceros.

640 KB
fuente
1

Excel VBA, 190 159 bytes

Gracias @TaylorScott

Function z(i)
Dim d(5,6)
v=DateValue(i)-17
For x=1To 5
For y=0To 6
d(0,y)=Left(WeekdayName(Weekday(v+y)),2)
d(x,y)=day(v+y+(x-1)*7)
Next y,x
z=d()
End Function

Toma la entrada en forma de una cadena de fecha válida para Excel VBA (por ejemplo, 19 de febrero de 2020; 19/02/2020; 19-febrero-2019), y devuelve una matriz con el calendario dado centrado en él.

william porter
fuente
Puede reducir esta solución a 159 eliminando el espacio en blanco de esta solución,Function z(i) Dim d(5,6) v=DateValue(i)-17 For x=1To 5 For y=0To 6 d(0,y)=Left(WeekdayName(Weekday(v+y)),2) d(x,y)=Day(v+y+(x-1)*7) Next y,x z=d() End Function
Taylor Scott,
@TaylorScott Gracias, solo estaba usando el editor incorporado que autopobla esos espacios.
William Porter
0

Rojo , 153 131 bytes

func[d][s: d - 24 loop 7[prin[""copy/part system/locale/days/(s/10) 2]s:
s + 1]loop 5[print""loop 7[prin pad/left s/4 3 s: s + 1]]]

Pruébalo en línea!

Galen Ivanov
fuente
0

T-SQL, 203 bytes

DECLARE @f date='2020-02-19'

,@ char(20)=0,@d char(105)=0SELECT
@=left(format(d,'D'),2)+' '+@,@d=right(d,2)+char(32-n%7/6*19)+@d
FROM(SELECT dateadd(d,number-17,@f)d,number n
FROM spt_values WHERE'P'=type)x ORDER BY-n
PRINT @+'
'+@d

La versión en línea es ligeramente diferente, esta versión publicada funciona en MS-SQL Studio Management. Ahorra 1 bytes en comparación con la versión en línea, pero no da el resultado correcto en línea

Pruébalo en línea

t-clausen.dk
fuente
0

Python 2 , 115 bytes

from datetime import*
d=input()
for i in range(42):print(d+timedelta(i-24)).strftime('%'+'da'[i<7])[:2]+i%7/6*'\n',

Pruébalo en línea!

No estoy seguro si esto está permitido ... toma la entrada de STDIN en el formulario date(year, month, day). Esto también se puede representar como __import__('datetime').date(year, month, day). Estos son realmente __import__('datetime').dateobjetos.

Erik el Outgolfer
fuente