¿Podrían ser el mismo día de la semana?

14

Desafío

Dado un número entero no negativo, indique si es posible que dos fechas (del calendario gregoriano) difieran exactamente en esa cantidad de años para compartir un día de la semana. Se supone que un año es bisiesto si es divisible por 4 pero no por 100, o si es divisible por 400.

La salida puede ser:

  • Falsey / Verdad (en cualquier orientación)
  • cualesquiera dos valores distintos
  • un valor distinto y otro siendo cualquier otra cosa
  • por código de retorno del programa
  • por éxito / error
  • por cualquier otro medio razonable: solo pregunte si sospecha que puede ser controvertido

Pero no por dos conjuntos de valores no distintos, a excepción de falsey / truthy (¡ya que esto permitiría un no-op!)

Detalle

Esto es si la entrada es un miembro de la secuencia OEIS A230995 .

Miembros:

0, 5, 6, 7, 11, 12, 17, 18, 22, 23, 28, 29, 33, 34, 35, 39, 40, 45, 46, 50, 51, 56, 57, 61, 62, 63, 67, 68, 73, 74, 78, 79, 84, 85, 89, 90, 91, 95, 96, 101, 102, 106, 107, 108, 112, 113, 114, 117, 118, 119, 123, 124, 125, 129, 130, 131, 134, 135, 136, 140, 141, 142, 145, 146, 147, 151, 152, 153, 157, 158, 159, 162, 163, 164, 168, 169, 170, 173, 174, 175, 179, 180, 181, 185, 186, 187, 190, 191, 192, 196, 197, 198, 202, 203, 204, 208, 209, 210, 213, 214, 215, 219, 220, 221, 225, 226, 227, 230, 231, 232, 236, 237, 238, 241, 242, 243, 247, 248, 249, 253, 254, 255, 258, 259, 260, 264, 265, 266, 269, 270, 271, 275, 276, 277, 281, 282, 283, 286, 287, 288, 292, 293, 294, 298, 299, 304, 305, 309, 310, 311, 315, 316, 321, 322, 326, 327, 332, 333, 337, 338, 339, 343, 344, 349, 350, 354, 355, 360, 361, 365, 366, 367, 371, 372, 377, 378, 382, 383, 388, 389, 393, 394, 395
plus
400, 405, 406, 407, 411, ...

No miembros:

1, 2, 3, 4, 8, 9, 10, 13, 14, 15, 16, 19, 20, 21, 24, 25, 26, 27, 30, 31, 32, 36, 37, 38, 41, 42, 43, 44, 47, 48, 49, 52, 53, 54, 55, 58, 59, 60, 64, 65, 66, 69, 70, 71, 72, 75, 76, 77, 80, 81, 82, 83, 86, 87, 88, 92, 93, 94, 97, 98, 99, 100, 103, 104, 105, 109, 110, 111, 115, 116, 120, 121, 122, 126, 127, 128, 132, 133, 137, 138, 139, 143, 144, 148, 149, 150, 154, 155, 156, 160, 161, 165, 166, 167, 171, 172, 176, 177, 178, 182, 183, 184, 188, 189, 193, 194, 195, 199, 200, 201, 205, 206, 207, 211, 212, 216, 217, 218, 222, 223, 224, 228, 229, 233, 234, 235, 239, 240, 244, 245, 246, 250, 251, 252, 256, 257, 261, 262, 263, 267, 268, 272, 273, 274, 278, 279, 280, 284, 285, 289, 290, 291, 295, 296, 297, 300, 301, 302, 303, 306, 307, 308, 312, 313, 314, 317, 318, 319, 320, 323, 324, 325, 328, 329, 330, 331, 334, 335, 336, 340, 341, 342, 345, 346, 347, 348, 351, 352, 353, 356, 357, 358, 359, 362, 363, 364, 368, 369, 370, 373, 374, 375, 376, 379, 380, 381, 384, 385, 386, 387, 390, 391, 392, 396, 397, 398, 399
plus
401, 402, 403, 404, 408, ...

Este es el por lo que gana la respuesta más corta en cada idioma.

Jonathan Allan
fuente
¿La salida puede ser: el programa finaliza (en menos de 30 segundos) si la entrada pertenece a la secuencia, o de lo contrario se ejecuta indefinidamente (bucle infinito)?
Luis Mendo
@LuisMendo Permitiré un programa que lo haga siempre y cuando esté acompañado de un programa que proporcione el límite de tiempo (para que uno pueda adquirirlo antes para el hardware). Sin embargo, es controvertido :)
Jonathan Allan
¿En qué situación es un número divisible por 400 pero no divisible por 100?
ATaco
@ATaco En ninguno. La excepción a la regla de cada cuarto año son años que son divisibles por 4 y 100, pero no por 400.
Dennis
@ATaco quizás la redacción sea más clara ahora
Jonathan Allan

Respuestas:

4

MATL , 17 bytes

`0Gv@+5:YcYO8XOda

El programa se detiene si la entrada pertenece a la secuencia o, de lo contrario, se ejecuta indefinidamente (bucle infinito).

Deje nser la entrada. El código ejecuta un ciclo que prueba años 1y 1+n; entonces 2y 2+n; ... hasta que se encuentre un día coincidente de la semana. Si no existe una coincidencia, el ciclo se ejecuta indefinidamente.

La función de membresía nes periódica con período 400. Por lo tanto, en la mayoría de las 400iteraciones son necesarias si npertenece a la secuencia. Esto requiere menos de 20 segundos en Pruébelo en línea. Como prueba de este límite superior, aquí hay un programa modificado que limita el número de iteraciones a 400 (agregando @401<*al final). Tenga en cuenta también que este límite está suelto y, por lo general, unos segundos son suficientes.

Pruébalo en línea!

Explicación

`           % Do...while
  0Gv       %   Push column vector [0; n], where n is the input number
  @+        %   Add k, element-wise. Gives [k; k+n]
  5:        %   Push row vector [1, 2, 3, 4, 5]
  Yc        %   Horizontal "string" concatenation: gives the 2×6 matrix
            %   [k, 1, 2, 3, 4, 5; k+n, 1, 2, 3, 4, 5]. The 6 columns
            %   represent year, month, day, hour, minute, second
  YO        %   Convert each row to serial date number. Gives a column
            %   vector of length 2
  8XO       %   Convert each date number to date string with format 8,
            %   which is weekday in three letters ('Mon', 'Tue', etc).
            %   This gives a 2×3 char matrix such as ['Wed';'Fri']
  d         %   Difference (of codepoints) along each column. Gives a
            %   row vector of length 3
  a         %   True if some element is nonzero, or false otherwise
            % End (implicit). The loop proceeds with the next iteration
            % if the top of the stack is true

Versión anterior, 24 bytes

400:"0G&v@+5:YcYO8XOdavA

La salida es 0si la entrada pertenece a la secuencia, o de 1otra manera.

Pruébalo en línea!

Explicación

400         % Push row vector [1, 2, ..., 400]
"           % For each k in that array
  0G&v      %   Push column vector [0; n], where n is the input number
  @+        %   Add k, element-wise. Gives [k; k+n]
  5:        %   Push row vector [1, 2, 3, 4, 5]
  Yc        %   Horizontal "string" concatenation: gives the 2×6 matrix
            %   [k, 1, 2, 3, 4, 5; k+n, 1, 2, 3, 4, 5]. The 6 columns
            %   represent year, month, day, hour, minute, second
  YO        %   Convert each row to serial date number. Gives a column
            %   vector of length 2
  8XO       %   Convert each date number to date string with format 8,
            %   which is weekday in three letters ('Mon', 'Tue', etc).
            %   This gives a 2×3 char matrix such as ['Wed';'Fri']
  d         %   Difference (of codepoints) along each column. Gives a
            %   row vector of length 3
  a         %   True if some element is nonzero, or false otherwise
  v         %   Concatenate vertically with previous results
  A         %   True if all results so far are true
            % End (implicit). Display (implicit)
Luis Mendo
fuente
Parece bueno, mi solicitud fue realmente que me gustaría saber la entrada del peor de los casos, o tener un programa que fuerce las 400 iteraciones, de esa manera uno podría obtener un límite superior donde sea que elija ejecutarlo. (Por cierto, creo que el bucle infinito, en la práctica, termina con un error fuera de límites.)
Jonathan Allan
1
@ JonathanAllan Gracias. Veo. He agregado un programa modificado que limita el número de iteraciones a 400. Tarda unos 14 segundos, por lo que estoy usando 20 segundos como límite superior
Luis Mendo
5

Python 2 , 58 bytes

u=-abs(200-input()%400)-4
print u/100+5>(u-8)*5/4%7>u%4/-3

Pruébalo en línea!

Una fórmula directa.

xnor
fuente
Esto es bonito. Creo que puede guardar 2 bytes con en 5*u/4%7-3lugar de (u-8)*5/4%7.
Jonathan Allan
Ahorre 2 más utilizando la opción de éxito / error con en 1/(...)lugar de print ....
Jonathan Allan
5

Jalea , 20 18 bytes

99R4ḍj`‘ṡ%4ȷ$S€P7ḍ

Salidas 1 para miembros, 0 para no miembros.

Pruébalo en línea!

Cómo funciona

99R4ḍj`‘ṡ%4ȷ$S€P7ḍ  Main link. Argument: n

99                  Set the return value to 99.
  R                 Range; yield [01, .., 99].
   4ḍ               Test each element in the range for divisibility by 4.
     j`             Join the resulting array, using itself as separator.
                    The result is an array of 9801 Booleans indicating whether the
                    years they represent have leap days.
       ‘            Increment the results, yielding 1 = 365 (mod 7) for non-leap
                    years, 2 = 366 (mod 7) for leap years.
         %4ȷ$       Compute n % 4000.
        ṡ           Take all slices of length n % 4000 of the result to the left.
             S€     Take the sum of each slice.
               P    Take the product of the sums.
                7ḍ  Test for divisibility by 7.
Dennis
fuente
1

Haskell , 76 bytes

-35 bytes gracias a Jonathan Allan. -2 bytes gracias a Lynn.

f i=or[c y==c$y+i|y<-[0..400]]
c n=(5*n#4+n%4-n#100+n#400)%7
(%)=mod
(#)=div

Pruébalo en línea!

Usando el algoritmo del programa OEIS PARI.

totalmente humano
fuente
1
5*(n#4)puede ser 5*n#4también!
Lynn
1

Pyth , 32 bytes

iI7*FsM.:hMs.iKiIL4S99*98]K%Q400

Pruébalo aquí! (Haga clic en "Cambiar a Test Suite" para verificar más casos de prueba a la vez)

¿Cómo?

Utiliza un truco genial que acabo de agregar al hilo "Consejos para jugar golf en Pyth".

iI7 * FsM.: hMs.iKiIL4S99 * 98] K% Q400 | Programa completo Lecturas de STDIN, salidas a STDOUT.

                   S99 | Genere los enteros en 1 ... 99.
                 L | Para cada entero N en esa lista ...
               iI 4 | Compruebe si 4 es invariante sobre la aplicación de GCD con N.
                                 El | Esto es equivalente a verificar si 4 | NORTE.
              K | Almacene el resultado en una variable K.
            .i * 98] K | E intercala K con los elementos de K envueltos
                                 El | en una lista y repite 98 veces.
           s | Aplanar.
         hM | Incremento.
       .: | Y generar todas las subcadenas ...
                           % Q400 | De longitud% 400.
     sM | Suma cada uno.
   * F | Y aplique el producto doblado.
iI7 | Compruebe si 7 es invariante cuando se aplica GCD con el
                                 El | producto (básicamente verifique si 7 | producto).
                                 El | Salida implícita del valor booleano apropiado.
Sr. Xcoder
fuente
0

Python 3 , 110 107 bytes

from datetime import*
lambda n,d=date:0in[d(i,1,1).weekday()-d(i+n%400,1,1).weekday()for i in range(1,999)]

Pruébalo en línea!

-3 bytes gracias al Sr. Xcoder.

Кирилл Малышев
fuente