Desafío multiplicador de fechas

19

(Inspirado por Riddler de la semana pasada en FiveThirtyEight.com. Publicación de Sandbox ).

Dado un año entre 2001 y 2099, calcule y devuelva el número de días durante ese año calendario donde mm * dd = yy(donde yyes el año de 2 dígitos ).

2018, por ejemplo, tiene 5:

  • 18 de enero (1 * 18 = 18)
  • 9 de febrero (2 * 9 = 18)
  • 6 de marzo (3 * 6 = 18)
  • 3 de junio (6 * 3 = 18)
  • 2 de septiembre (9 * 2 = 18)

La entrada puede ser un año numérico de 2 o 4 dígitos.

La salida debe ser un número entero. El espacio final opcional o el retorno están bien.

Lista completa de entrada / salida:

Input = Output
 2001 = 1     2021 = 3     2041 = 0     2061 = 0     2081 = 2
 2002 = 2     2022 = 3     2042 = 4     2062 = 0     2082 = 0
 2003 = 2     2023 = 1     2043 = 0     2063 = 3     2083 = 0
 2004 = 3     2024 = 7     2044 = 3     2064 = 2     2084 = 5
 2005 = 2     2025 = 2     2045 = 3     2065 = 1     2085 = 1
 2006 = 4     2026 = 2     2046 = 1     2066 = 3     2086 = 0
 2007 = 2     2027 = 3     2047 = 0     2067 = 0     2087 = 1
 2008 = 4     2028 = 4     2048 = 6     2068 = 1     2088 = 3
 2009 = 3     2029 = 1     2049 = 1     2069 = 1     2089 = 0
 2010 = 4     2030 = 6     2050 = 3     2070 = 3     2090 = 5
 2011 = 2     2031 = 1     2051 = 1     2071 = 0     2091 = 1
 2012 = 6     2032 = 3     2052 = 2     2072 = 6     2092 = 1
 2013 = 1     2033 = 2     2053 = 0     2073 = 0     2093 = 1
 2014 = 3     2034 = 1     2054 = 4     2074 = 0     2094 = 0
 2015 = 3     2035 = 2     2055 = 2     2075 = 2     2095 = 1
 2016 = 4     2036 = 6     2056 = 4     2076 = 1     2096 = 4
 2017 = 1     2037 = 0     2057 = 1     2077 = 2     2097 = 0
 2018 = 5     2038 = 1     2058 = 0     2078 = 2     2098 = 1
 2019 = 1     2039 = 1     2059 = 0     2079 = 0     2099 = 2
 2020 = 5     2040 = 5     2060 = 6     2080 = 4

Este es un desafío de , gana el conteo de bytes más bajo en cada idioma.

El cálculo previo y la simple búsqueda de las respuestas normalmente se excluyen de acuerdo con nuestras reglas de escapatoria , pero lo estoy permitiendo explícitamente para este desafío. Permite algunas estrategias alternativas interesantes, aunque no es probable que una lista de búsqueda de 98 99 ítems sea más corta.

BradC
fuente
Si lo hace más fácil en su idioma, la respuesta será la misma independientemente del siglo; 1924 y 2124 tienen el mismo número de días que 2024.
BradC
Si el resultado de mm * dd es mayor que 100, ¿se filtra automáticamente?
DanielIndie
@DanielIndie Correcto, no se deben contar las fechas "envolventes". En otras palabras, el 12 de diciembre de 2044 no cuenta, aunque 12 * 12 = 144.
BradC
Como solo necesitamos manejar un número limitado de entradas, las he editado todas. Siéntase libre de revertir o reformatear.
Shaggy
1
@gwaugh Solo que puede decidir cuál aceptar como entrada válida (para que no tenga que gastar caracteres adicionales convirtiendo entre los dos).
BradC

Respuestas:

14

Excel, 48 bytes

¡Hurra! Finalmente algo en Excel es realmente bueno.

=COUNT(VALUE(ROW(1:12)&"/"&A1/ROW(1:12)&"/"&A1))

Toma información de A1 en forma de un número entero 1-99 que representa el año, y sale a donde ingrese esta fórmula. Es una fórmula de matriz, así que use Ctrl-Shift-Enter en lugar de Enter para ingresarla.

Esto aprovecha el hecho de que COUNTignora los errores, por lo que cualquier error causado por el mes que no divide el año (lo que hace que Excel analice algo así como 2/12.5/25por la fecha que no es válida, 2/29/58simplemente se ignora en silencio).

Sophia Lechner
fuente
1
Muy agradable. Probablemente valga la pena mencionar que requiere un año de 2 dígitos A1. Ingresar un año de 4 dígitos simplemente regresa 0.
BradC
¡Cierto! Lo editaré en la descripción.
Sophia Lechner
También debo mencionar que es específico de la localidad; depende de tener un entorno local que utilice un pedido mm / dd / aa. En un entorno local con orden dd / mm / aa, la respuesta sería la misma cantidad de bytes, por supuesto.
Sophia Lechner
1
Súper inteligente; Me gusta que solo evalúes a 12 candidatos de fecha (uno por mes), en lugar de presentarte todos los días del año.
BradC
¿Arreglar el año a un byte de salvar sin salto?
l4m2
6

Python 2 , 44 bytes

[k/32%13*(k%32)for k in range(96,509)].count

Pruébalo en línea!

Una función anónima dada como un objeto de método. Produce todos los productos de (month, day)pares (m, d)como codificada por k=32*m+dcon 0≤m≤12, 0≤d≤31, envolviendo alrededor. Elimina del 29 al 31 de febrero al excluirlos del rango.

xnor
fuente
5

Java (JDK 10) , 65 bytes

y->{int m=13,c=0;for(;m-->1;)if(y%m<1&y/m<29+m%2*3)c++;return c;}

Pruébalo en línea!

Créditos

Olivier Grégoire
fuente
No cabe el año bisiesto 29*n, así que no es necesario el cheque
l4m2
Gracias por tu contribución. Podría eliminar 27 bytes en total con muchos otros cambios.
Olivier Grégoire
1
Cambiar (m==2?29:32)a 29+m%2*3todavía parece dar todos los OKresultados. Crédito para @AsoneTuhid Rubí respuesta 's .
Kevin Cruijssen
4

PowerShell , 94 bytes

param($a)for($x=Date 1/1/$a;$x-le(Date 12/9/$a);$x=$x.AddDays(1)){$z+=$x.Month*$x.Day-eq$a};$z

Pruébalo en línea!

Toma la entrada como un año de dos dígitos, luego construye un forciclo de 1/1/yeara 12/9/year(porque 12/10 y más allá nunca contarán y esto ahorra un byte). Cada iteración, incrementamos $zsi las .Monthveces el .Dayes igual a nuestro año de entrada. Fuera del bucle, $zse deja en la tubería y la salida es implícita.

Editar: esto depende de la cultura. El código anterior funciona para en-us. El formato de fecha puede necesitar cambiar para otras culturas.

AdmBorkBork
fuente
2
"cultura"? ¿Quiso decir "locale"? ...
user202729
1
@ user202729 Coloquialmente, sí, pero la documentación de PowerShell se refiere a ella como "cultura".
AdmBorkBork
"Cultura" es la palabra que la EM generalmente usa para hablar sobre la configuración regional, por ejemplo. System.Globalization.CultureInfo en .NET.
sundar - Restablece a Monica el
3

JavaScript (ES6), 91 bytes

Tenía curiosidad por saber cómo se compararía el hardcoding con un cálculo iterativo. Es definitivamente más larga (ver @ respuesta de Shaggy ), pero no muy largo.

Editar : Sin embargo, es mucho más largo que una fórmula más directa (ver respuesta @ l4m2 ).

Toma la entrada como un entero en [1..99] .

n=>(k=parseInt('8ijkskercdtbnqcejh6954r1eb2kc06oa3936gh2k0d83d984h'[n>>1],36),n&1?k>>3:k&7)

Pruébalo en línea!

¿Cómo?

Los años impares tienen significativamente menos posibilidades de tener mm * dd = aa que los años pares. Más concretamente, los años impares tienen 0 a 3 partidos, mientras que los años pares tienen 0 a 7 partidos. Esto nos permite codificar cada par de años con solo 5 bits, que se pueden representar convenientemente como un solo carácter en la base 36.

Arnauld
fuente
3

Bash + utilidades GNU , 57

  • 1 byte guardado gracias a @SophiaLechner
seq -f1/1/$1+%gday 0 365|date -f- +%m*%d-%y|bc|grep -c ^0

Tenga en cuenta que el seqcomando siempre produce una lista de 366 fechas; para los años no bisiestos, se incluirá el 1 de enero del próximo año. Sin embargo, en el rango de fechas 2001..2099, MM * DD nunca será AA durante el 1 de enero del próximo año durante ninguno de estos años, por lo que este día adicional no afectará el resultado.

Pruébalo en línea!

Trauma digital
fuente
Muy agradable, ni siquiera sabía dateque harían citas de matemáticas así mientras analizaba. seqno necesita un espacio después del -f, por lo que puede guardar un byte allí.
Sophia Lechner
3

T-SQL, 123 121 bytes

Según nuestras reglas de IO , la entrada se toma a través de la tabla t preexistente con un campo entero y , que contiene un año de 2 dígitos.

WITH c AS(SELECT 1m UNION ALL SELECT m+1FROM c WHERE m<12)
SELECT SUM(ISDATE(CONCAT(m,'/',y/m,'/',y)))FROM c,t WHERE y%m=0

El salto de línea es solo para legibilidad. Inspirado en gran medida por la solución Excel de Sophia .

  • La línea superior genera una tabla de números de 12 elementos c que se une a la tabla de entrada t .
  • Si eso pasa, mezclo un candidato de fecha usando CONCAT(), lo que hace varcharconversiones de tipo de datos implícitas . De lo contrario, tendría que hacer un montón de CASTo CONVERTdeclaraciones.
  • Encontró la función de evaluación perfecta ISDATE(), que devuelve 1 para fechas válidas y 0 para fechas no válidas.
  • Envuélvelo en una SUMA y listo.
  • EDITAR : Movió la verificación de división de enteros ( y%m=0) en la WHEREcláusula para guardar 2 bytes, gracias @RazvanSocol.

Desafortunadamente, no es mucho más corto que la versión de la tabla de búsqueda (usando la cadena de la versión de osdavison ):

Búsqueda de T-SQL, 129 bytes

SELECT SUBSTRING('122324243426133415153317223416132126011504033106131204241006003213011306002122042005101305111014012',y,1)FROM t

EDITAR : Dejando mi original arriba, pero podemos guardar algunos bytes usando un par de nuevas funciones:

  • STRING_SPLIT está disponible en MS SQL 2016 y superior.
  • CONCAT_WS está disponible en MS SQL 2017 y versiones posteriores.
  • Como arriba, reemplazado IIFconWHERE

MS-SQL 2017, 121 118 bytes

SELECT SUM(ISDATE(CONCAT_WS('/',value,y/value,y)))
FROM t,STRING_SPLIT('1-2-3-4-5-6-7-8-9-10-11-12','-')
WHERE y%value=0

MS-SQL 2017, edición extra cheaty: 109 bytes

SELECT SUM(ISDATE(CONCAT_WS('/',number,y/number,y)))
FROM t,spt_values WHERE number>0AND y%number=0AND'P'=TYPE

Requiere que esté en la masterbase de datos, que contiene una tabla del sistema spt_valuesque (cuando se filtra por TYPE='P'), le proporciona números de conteo del 0 al 2048.

BradC
fuente
Similar a otras respuestas, el orden en que ensamblo la fecha ( m/d/y) depende de la configuración de localidad de la instancia de SQL. Otras localidades pueden requerir un orden diferente o un separador diferente, pero no creo que afecte la longitud del código.
BradC
Supongo que te diste cuenta de que convertir '2/29/64' a una fecha da 1964-02-29 (no 2064-02-29), pero teniendo en cuenta que los años 2000 y 2100 están excluidos, es una buena manera de acortar código.
Razvan Socol
Usar en SPLIT_STRINGlugar de un CTE lo reduce a 120 bytes. Usar en CONCAT_WSlugar de CONCATguardar otro carácter, llevándolo a 119 bytes.
Razvan Socol
@RazvanSocol Sí, no estoy seguro de dónde está el intervalo entre las fechas de 2 dígitos que se asignan a 19xx vs 20xx, pero ambas dan la misma respuesta. Voy a probar las otras dos sugerencias, ¡gracias!
BradC
1
Reemplazar IIFcon WHERE.
Razvan Socol
3

Julia 0.6 , 49 44 42 bytes

y->sum(y/i1:28+3(i%2i÷8)for i=1:12)

Pruébalo en línea!

-5 bytes inspirados en la respuesta Ruby de Asone Tuhid.
-2 bytes reemplazando cuenta con suma

Explicación:

Para cada mes idel 1 al 12, calcule y/iy verifique si es uno de los días de ese mes. Los meses con 31 días son 1, 3, 5, 7, 8, 10, 12, por lo que son impares por debajo de 8 e incluso por encima de 8. Entonces, i%2o i÷8(que es 0 para i <8 y 1 para i> = 8 aquí) debería ser 1, pero no ambos, así que los XOR. Si el resultado xor es verdadero, verificamos las fechas , 1:28+3es decir 1:31, de lo contrario verificamos solo las fechas 1:28.

1:28es suficiente para el resto de los meses (esta mejora inspirada en la respuesta de Ruby de Asone Tuhid ) porque:

  • para febrero, la única posibilidad hubiera sido 2*29 = 58, pero 2058no es un año bisiesto, por lo que podemos suponer que febrero siempre tiene 28 días.

  • los otros meses con 30 días son el mes 4 y superiores, para los cuales i*29(y i*30) serían superiores a 100, lo que puede ignorarse.

Finalmente, contamos el número de veces que y/ipertenece a esta lista de días (usando boolean sumaquí), y devolvemos eso.

sundar - Restablece a Monica
fuente
3

JavaScript, 91 85 82 81 77 bytes

Toma la entrada como una cadena de 2 dígitos (o un entero de 1 o 2 dígitos).

Aprovecha el hecho de que new Datepasará al próximo mes y continuará haciéndolo, si le pasa un valor de día que excede el número de días en el mes en que lo pasa, entonces, en la primera iteración, intenta construir el fecha yyyy-01-345que se convierte yyyy-12-11, o yyyy-12-10en años bisiestos. No necesitamos verificar las fechas después de eso, ya que 12*11+da como resultado un número de 3 dígitos.

y=>(g=d=>d&&([,M,D]=new Date(y,0,d).toJSON().split(/\D/),D*M==y)+g(--d))(345)

3 bytes guardados gracias a Arnauld .


Pruébalo

f=
y=>(g=d=>d&&([,M,D]=new Date(y,0,d).toJSON().split(/\D/),D*M==y)+g(--d))(345)
o.innerText=[...Array(99)].map((_,x)=>(2001+x++)+` = `+f(x)).join`\n`
pre{column-count:5;width:480px;}
<pre id=o></pre>

Lanudo
fuente
2

Excel, 83 bytes

{=SUM(IF(MONTH(DATE(A1,1,0)+ROW(1:366))*DAY(DATE(A1,1,0)+ROW(1:366))=A1-2000,1,0))}

La entrada está en la celda A1en el formato yyyy. Esta es una fórmula de matriz y se ingresa con Ctrl+ Shift+ Enterpara obtener las llaves {}. Es bastante sencillo y sin ninguna inteligencia.

Cuando está en una fórmula de matriz, DATE(A1,1,0)+ROW(1:366)nos da una matriz de 366 valores de fecha. En los años no bisiestos, esto incluirá el 1 de enero del próximo año, pero eso no es un problema porque 1*1=1solo contaría como falso positivo si el próximo año es 2001, pero, dado que el rango de año requerido es 2001 - 2099, nunca surgirá como un problema.

Si acortó esa parte simplemente ~, la fórmula es mucho más fácil de seguir:

{=SUM(IF(MONTH(~)*DAY(~)=A1-2000,1,0))}

Intenté usarlo en COUNTIF()lugar de hacerlo, SUM(IF())pero Excel ni siquiera me permitió ingresarlo como una fórmula de matriz, y mucho menos me dio un resultado. Me hice encontrar un Hojas de Google solución usando CountIf()pero el mismo método de otro modo que resultó ser de 91 bytes, en su mayoría, ya que utiliza ArrayFormula()en lugar de simplemente { }.

=CountIf(ArrayFormula(Month(Date(A1,1,0)+Row(1:366))*Day(Date(A1,1,0)+Row(1:366))),A1-2000)
Tostadas de ingeniero
fuente
No he visto un consenso, pero generalmente no he incluido los corchetes externos en mis conteos de bytes para Excel. Se sienten más como una forma en que Excel está formateando su pantalla que como parte de la fórmula. Opiniones?
Sophia Lechner el
@SophiaLechner Los he incluido en lugar de decidir cómo incluir las pulsaciones de teclas adicionales necesarias para ingresarlo como una fórmula de matriz. Hay una meta pregunta sobre eso y la única respuesta dice que el comando CTRL + ALT + ENTRAR contaría como 1 pulsación de tecla. Si usa lo mismo que vim ( por meta ), esa pulsación de tecla contaría como 1 byte. Sin embargo, generalmente no cuento el ENTER al final de ingresar una fórmula como 1 byte en otras respuestas.
Ingeniero Brindis
2

Retina 0.8.2 , 55 bytes

..
$*
(?<=^(1{1,12}))(?=(?(?<=^11$)\1{0,27}|\1{0,30})$)

Pruébalo en línea! Toma un año de dos dígitos; agregue 1 byte para admitir años de 4 dígitos. Explicación: La primera etapa simplemente se convierte en unaria. La segunda etapa comienza haciendo coincidir de 1 a 12 caracteres antes de la posición de la coincidencia, representando el mes, y luego intenta mirar hacia adelante para una cantidad completa de repeticiones de ese mes. Sin embargo, la búsqueda anticipada contiene un condicional, que elige entre 27 o 30 repeticiones adicionales según el mes. El recuento de las posiciones del partido es el resultado deseado.

Neil
fuente
2

R , 22 122 bytes

x=scan();substr("122324243426133415153317223416132126011504033106131204241006003213011306002122042005101305111014012",x,x)

Pruébalo en línea!

Decidí ir con un enfoque de tabla de búsqueda. El año de entrada debe ser de 2 dígitos.

Robert S.
fuente
1
También en TIO puede presionar el botón "enlace" y formateará automáticamente la respuesta por usted. ¡Gracias a Dennis por configurarlo!
Giuseppe
Se puede quitar el inicial if, ya que de entrada puede ser ya sea de 2 dígitos o 4 dígitos, su elección (por lo que puede optar por aceptar solamente la entrada de 2 dígitos). Pero parece que el código considera que cada mes contiene 31 días, por lo que, por ejemplo, 62 (para 2062) devuelve 1 donde debería devolver 0.
sundar - Restablecer Monica
2
Entendí mal. Dicho esto, estoy bastante seguro de que la tabla de búsqueda debería incluirse en el recuento de bytes.
ngm
@ngm Tampoco estaba seguro de si era necesario incluir la tabla de búsqueda, pero la agregaré al conteo de bytes solo para estar seguro.
Robert S.
¡Todavía no estoy seguro de cuáles son todas las reglas!
ngm
2

C (gcc), 65 60 59 bytes

d(a,t,e){for(t=0,e=13;e-->1;)t+=a%e<1&a/e<(e-2?32:29);a=t;}

Puerto de la respuesta Java de user202729 . Pruébelo en línea aquí . Gracias a Jonathan Frech por jugar al golf 1 byte.

OOBalance
fuente
a=0,m=13;for(;~> for(a=0,m=13;.
Jonathan Frech
@ JonathanFrech Gracias por señalar eso, he editado.
OOBalance
2

J , 29 bytes

1#.(,x*i."+29+3*2~:x=.i.13)=]

Pruébalo en línea!

Cómo funciona

1#.(,x*i."+29+3*2~:x=.i.13)=]    Input: year (2-digit, 1..99)
                   x=.i.13       array of 0..12; assign to x
                2~:              1 1 0 1 .. 1
              3*                 3 3 0 3 .. 3
           29+                   32 32 29 32 .. 32
       i."+                      for each item of above, generate a row 0 .. n
    ,x*                          each row times 0 .. 12 and flatten
                           =]    1 for each item == input, 0 otherwise
1#.                              sum

Intenté obtener menos de 2 veces la solución de gelatina :)

Nota al margen

Si alguien realmente quiere codificar los datos de 99 dígitos, aquí hay un poco de información:

Divide los 99 dígitos en trozos de 2 dígitos. Entonces el primer dígito es <4y el segundo <8, lo que significa que cinco bits pueden codificar dos números. Luego, todos los datos se pueden codificar en 250 bits o 32 bytes.

Bubbler
fuente
2

Pitón 3 , 158 162 215 241 bytes

Eliminado 4 Gracias a Stephen por jugar golf a los condicionales.

Eliminado 53 gracias Stephen por señalar el espacio en blanco

Eliminado 26 gracias al enlace proporcionado por caird

Soy bastante nuevo en esto. No se me ocurre cómo hacerlo sin que se describan los días de un mes.

r=range
def n(Y):
 a,b,c=31,30,0
 for x in r(12):
  for y in r([a,(28if Y%4else 29),a,b,a,b,a,a,b,a,b,a][x]):
   if(x+1)*(y+1)==int(str(Y)[2:]):c+=1
 return c

Pruébalo en línea!

akozi
fuente
55
Bienvenido al sitio, y buen primer post! Hay muchas maneras de jugar golf, como eliminar algunos espacios en blanco, así que asegúrese de consultar estos consejos para jugar golf en Python
caird coinheringaahing
@cairdcoinheringaahing Gracias por el consejo, el enlace fue muy útil.
akozi
1
158 bytes : jugué un poco, pero en su mayoría tenía una gran línea de espacios en su tercera línea, no sé cómo llegaron allí
Stephen
@Stephen Gracias :) Agregué el tuyo como dos ediciones. Uno para el espacio en blanco y el otro como el golf.
akozi
(28if Y%4else 29)se puede acortar a [29,28][Y%4>0]. Además, la larga lista se puede acortar a [a,...]+2*[a,b,a,b,a]. a,b,cse puede agregar en la lista de parámetros para guardar una línea. int(str(Y)[2:])se puede acortar a Y%100. Finalmente, las variables de contador se pueden acortar en su mayoría a lens de comprensión de listas, esto también permite nhacer a lambda. Esto hace 118 .
Black Owl Kai
2

Adelante (gforth) , 60 59 bytes

: f 0 13 1 do over i /mod swap 32 i 2 = 3 * + 0 d< - loop ;

Pruébalo en línea!

Esta versión aprovecha el hecho de que no puede haber más de 1 día coincidente por mes, y que el año debe ser divisible por el mes para que coincida.

Explicación

Se repite a lo largo de los meses, verifica si el año es divisible por mes, y si el cociente es <31 (28 para febrero) Los meses posteriores a marzo no pueden coincidir con días superiores a 25, por lo que podemos suponer todos los meses (excepto febrero) Tiene 31 días para el propósito del rompecabezas.

Explicación del código

: f                   \ start new word definition
  0                   \ set up counter
  13 1 do             \ start a counted loop from 1 to 12
    over i /mod       \ get the quotient and remainder of dividing year by month
    swap              \ default order is remainder-quotient, but we want to swap them
    32 i 2= 3 * +     \ we want to compare to 32 days unless month is Feb
    0 d<=             \ treat the 4 numbers on the stack as 2 double-length numbers
                      \ and compare [1]
    -                 \ subtract result from counter (-1 is true in Forth)
  loop                \ end loop
;                     \ end word definition    

[1] - Forth tiene el concepto de números de doble longitud, que se almacenan en la pila como dos números de longitud única (de la forma xy, donde el valor del doble = y * 2^(l) + x donde l es el tamaño en bits de un solo en el cuarta implementación con la que estás trabajando).

En este caso, comparé el cociente y el resto con 32 (o 29) 0. Si el resto fuera mayor que 0 (año no divisible por mes), el primer doble sería automáticamente mayor que 32 (o 29) 0 y el resultado Sería falso. Si el resto es 0, entonces se resuelve de manera efectiva una verificación regular del cociente <= 32 (o 29)

Adelante (gforth) , 61 bytes

: f 0 13 1 do i 2 = 3 * 32 + 1 do over i j * = - loop loop ; 

Pruébalo en línea!

Ahorré algunos bytes al darme cuenta de que solo febrero importa en términos de tener la cantidad correcta de días en el mes

Explicación

Las comparaciones de Forth (al menos gforth) devuelven -1 para verdadero y 0 para falso

0                     \ place 0 on top of the stack to use as a counter
13 1 do               \ begin the outer loop from 1 to 12
  i 2 = 3 *           \ if i is 2 place -3 on top of the stack, otherwise 0
  32 + 1 do           \ begin the inner loop from 1 to 31 (or 28)
    over              \ copy the year from stack position 2 and place it on top of the stack
    i j * = -         \ multiply month and day compare to year, subtract result from counter 
  loop                \ end the inner loop
loop                  \ end the outer loop
reffu
fuente
1

Java (JDK 10) , 79 72 70 bytes

y->{int a=0,m=13;for(;m-->1;)a+=y%m<1&&y/m<(m==2?29:32)?1:0;return a;}

Pruébalo en línea!

usuario202729
fuente
@ Shaggy Gracias! (restos de la versión anterior en la que d
recorro
Si cambia &&a &, es la misma respuesta que la respuesta Java de OlivierGrégoire, aunque ha respondido 19 minutos antes.
Kevin Cruijssen
@KevinCruijssen Coincidencia aleatoria. Aunque mi versión es un poco peor (uso innecesario de ternary).
usuario202729
1

JavaScript (Node.js) , 108 bytes

a=>'0122324243426133415153317223416132126011504033106131204241006003213011306002122042005101305111014012'[a]

f=a=>'0122324243426133415153317223416132126011504033106131204241006003213011306002122042005101305111014012'[a]
o.innerText=[...Array(99)].map((_,x)=>(2001+x++)+` = `+f(x)).join`\n`
pre{column-count:5;width:480px;}
<pre id=o></pre>


fuente
Búsqueda de fuerza bruta, ¡bien!
BradC
Bienvenido a PPCG!
Shaggy
1

Python 3, 132 bytes

Este es realmente un programa bastante largo, pero pensé que podría ser de interés.

Todos los valores están entre 0-7, por lo que codifico cada número con 3 bits en una cadena binaria larga. Intenté pegar una cadena binaria sin procesar en mi programa de Python, pero no pude hacer que funcionara, así que me decidí por base64 en el archivo.

Usé la siguiente cadena como una tabla de búsqueda (terminando el 7 utilizado para el relleno): 01223242434261334151533172234161321260115040331061312042410060032130113060021220420051013051110140127

El programa toma esta cadena y la decodifica como un número, luego usa el desplazamiento de bits para extraer el resultado.

import base64
lambda n:int.from_bytes(base64.b64decode(b'pNRRxYtw01s9Jw4tFYE0QNkYsoRQgYBosEsYBFIRAUgsUkgwFQM='),'big')>>(6306-3*n)&7

66 bytes + archivo de 37 bytes = 103 bytes

Esto lee un archivo binario llamado ey evita usar base64.

lambda n:int.from_bytes(open('e','rb').read(),'big')>>(6306-3*n)&7

Aquí hay un hexdump del archivo de lectura (sin relleno):

00000000  a4 d4 51 c5 8b 70 d3 5b  3d 27 0e 2d 15 81 34 40  |..Q..p.[='.-..4@|
00000010  d9 18 b2 84 50 81 80 68  b0 4b 18 04 52 11 01 48  |....P..h.K..R..H|
00000020  2c 52 48 30 0a                                    |,RH0.|
qwr
fuente
1

Oracle SQL, 115 bytes

select count(decode(sign(decode(l,2,29,32)-y/l),1,1))from t,
xmltable('1to 12'columns l int path'.')where mod(y,l)=0

Podemos notar que realmente no importa cuántos días en abril (y meses posteriores), desde 100/4 <28. Además, no es necesario verificar si el año es bisiesto o no. Solo tenemos que especificar que hay 28 días en febrero (no 29 porque esa validación se ejecutará solo para 2058, lo que no es un salto), de lo contrario, puede ser solo 31 para cualquier mes.

Otros enfoques

Oracle SQL (12c versión 2 y posterior), 151 bytes

select count(to_date(y/l||'-'||l||'-1' default '' on conversion error,'dd-mm-y'))from t,
(select level l from dual connect by level<=12)where mod(y,l)=0

Oracle SQL (12c Release 2 y posterior), 137 bytes

select sum(validate_conversion(y/l||'-'||l||'-1'as date,'dd-mm-y'))from t,
(select level l from dual connect by level<=12)where mod(y,l)=0

Tanto solución podría haber sido 8 bytes más corto si reemplazamos (select level l from dual connect by level<=12)con xmltable('1to 12'columns l int path'.')pero Oracle lanza una excepción debido al error (probado con las versiones 12.2.0.1.0, 18.3.0.0.0).

SQL> select count(to_date(y/l||'-'||l||'-1' default '' on conversion error,'dd-mm-y'))from t,
  2  xmltable('1to 12'columns l int path'.')where mod(y,l)=0
  3  /
select count(to_date(y/l||'-'||l||'-1' default '' on conversion error,'dd-mm-y'))from t,
*
ERROR at line 1:
ORA-00932: inconsistent datatypes: expected DATE got DATE


SQL> select sum(validate_conversion(y/l||'-'||l||'-1'as date,'dd-mm-y'))from t,
  2  xmltable('1to 12'columns l int path'.')where mod(y,l)=0
  3  /
select sum(validate_conversion(y/l||'-'||l||'-1'as date,'dd-mm-y'))from t,
*
ERROR at line 1:
ORA-43909: invalid input data type

El único caso en ambas soluciones cuando el año importa es 2058, que no es bisiesto, por lo que se usó literal '-1' para especificar el año no bisiesto.

Oracle SQL, 128 bytes

select count(d)from t,(select date'1-1-1'+level-1 d from dual connect by level<365)
where to_char(d(+),'mm')*to_char(d(+),'dd')=y

Oracle SQL, 126 bytes

select substr('122324243426133415153317223416132126011504033106131204241006003213011306002122042005101305111014012',y,1)from t

Actualizar

Oracle SQL, 110 bytes

select-sum(least(sign(y/l-decode(l,2,29,32)),0))from t,
xmltable('1to 12'columns l int path'.')where mod(y,l)=0

Oracle SQL, 108 bytes

select sum(decode(sign(decode(l,2,29,32)-y/l)*mod(y+1,l),1,1))from t,
xmltable('1to 12'columns l int path'.')

Spark SQL, 137 bytes

select count(cast(regexp_replace(concat_ws('-','2001',l,y/l),'.0$','')as date))
from(select explode(array(1,2,3,4,5,6,7,8,9,10,11,12))l),t

Spark 2.3+ SQL, 126 bytes

(la replacefunción está disponible)

select count(cast(replace(concat_ws('-','2001',l,y/l),'.0')as date))
from(select explode(array(1,2,3,4,5,6,7,8,9,10,11,12))l),t
Dr. Y Wit
fuente
1

PHP , 73 bytes

Usando entrada de tubería y php -nR:

for(;++$m<13;$d=1)while($d<25+($m-2?$m>4?:7:4))$c+=$argn==$m*$d++;echo$c;

Pruébalo en línea!

PHP , 76 bytes

Usando la entrada de línea de comando arg php dm.php 18:

for(;++$m<13;$d=1)while($d<25+($m-2?$m>4?:7:4))$c+=$argv[1]==$m*$d++;echo$c;

Pruébalo en línea!

Enfoque iterativo. Dado que el único año bisiesto a considerar es 2 * 29 = 58, y 2058 no es un año bisiesto, no es necesario considerar el año bisiesto en los días de febrero. Y dado que envolver no es una preocupación, desde abril en adelante, cualquier día mayor de 25 excederá de 100, solo decimos que el resto de los meses solo tienen 25 días.

La entrada es de 2 dígitos al año a través de la línea de comando (-10 bytes como programa, gracias a la sugerencia de @Titus).

O:

PHP , 101 bytes

$y=$argv[1];for($d=strtotime("$y-1");date(Y,$d)==$y;$d+=86400)eval(date("$\x+=j*n=='y';",$d));echo$x;

Pruébalo en línea!

Todavía iterativo pero usando las funciones de marca de tiempo de PHP. Acepta el año como un número de cuatro dígitos. Gracias a @Titus por sugerencia de uso en strtotime()lugar de mktime().

640 KB
fuente
La primera versión falla por años de 4 dígitos, la segunda falla por dos dígitos. Pero bien pensado. Prueba $m<5?$m-2?31:28:25por el primero y $d=strtotime("$y-1")por el segundo
Titus
Uhm ... ¿Por qué pusiste el yen la evaluación entre comillas?
Tito
@Titus porque PHP7 ahora trata los dígitos precedidos por 0 como octales, por lo que 08 y 09 en realidad no son válidos. tio.run/##K8go@G9jXwAkU5Mz8hUMFWxtFQwsrP//BwA Usando la función date () solo puede obtener un año de cero dígitos de 2 dígitos.
640 KB
¡Gorrón! por supuesto.
Tito
1
@Titus, segunda versión actualizada usando en strtotime()lugar de mktime()y re-implementado como programa, -7 bytes. Además, analicé la mayoría de los envíos, incluidos los más votados, solo aceptarán el año como 2 o 4 dígitos, así que voy a tomar eso como que corresponde al remitente. Gracias de nuevo por las sugerencias!
640 KB
0

PHP, 74 70 bytes

while(++$m<13)for($d=$m<5?$m-2?31:28:25;$d;)$n+=$d--*$m==$argn;echo$n;

acepta años de dos dígitos solamente.

Adopté consideraciones gwaugh's y les Jugamos al golf; mi primer enfoque fue más largo que el suyo (92 bytes):

for($y=$argn%100;++$m<13;)for($d=$m-2?30+($m+$m/8)%2:29-($y%4>0);$d;)$n+=$d--*$m==$y;echo$n;

%100 permite usar años de 4 dígitos.


Ejecutar como tubería -nRo probarlos en línea .

Titus
fuente
Puede guardar 4 bytes eliminando el% 100 y solo tomando la entrada de 2 dígitos, lo cual está bien: codegolf.stackexchange.com/questions/162137/…
640KB