(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 yy
es 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 código de golf , 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.
Respuestas:
Excel, 48 bytes
¡Hurra! Finalmente algo en Excel es realmente bueno.
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
COUNT
ignora 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í como2/12.5/25
por la fecha que no es válida,2/29/58
simplemente se ignora en silencio).fuente
A1
. Ingresar un año de 4 dígitos simplemente regresa0
.Python 2 , 44 bytes
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 pork=32*m+d
con0≤m≤12
,0≤d≤31
, envolviendo alrededor. Elimina del 29 al 31 de febrero al excluirlos del rango.fuente
Java (JDK 10) , 65 bytes
Pruébalo en línea!
Créditos
fuente
29*n
, así que no es necesario el cheque(m==2?29:32)
a29+m%2*3
todavía parece dar todos losOK
resultados. Crédito para @AsoneTuhid Rubí respuesta 's .PowerShell , 94 bytes
Pruébalo en línea!
Toma la entrada como un año de dos dígitos, luego construye un
for
ciclo de1/1/year
a12/9/year
(porque 12/10 y más allá nunca contarán y esto ahorra un byte). Cada iteración, incrementamos$z
si las.Month
veces el.Day
es igual a nuestro año de entrada. Fuera del bucle,$z
se 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.fuente
Ruby ,
4642 bytesPruébalo en línea!
fuente
JavaScript (Node.js) ,
484443 bytesPruébalo en línea!
JavaScript (Node.js) ,
5958 bytesPruébalo en línea!
fuente
Jalea , 15 bytes
Pruébalo en línea!
Tome un número dentro del rango
[0,100[
como entrada.fuente
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] .
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.
fuente
Perl 6 , 40 bytes
Pruébalo en línea!
fuente
Python 2 y 3 ,
5552 bytesPruébalo en línea!
fuente
Bash + utilidades GNU , 57
Tenga en cuenta que el
seq
comando 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!
fuente
date
que harían citas de matemáticas así mientras analizaba.seq
no necesita un espacio después del-f
, por lo que puede guardar un byte allí.T-SQL,
123121 bytesSegú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.
El salto de línea es solo para legibilidad. Inspirado en gran medida por la solución Excel de Sophia .
CONCAT()
, lo que hacevarchar
conversiones de tipo de datos implícitas . De lo contrario, tendría que hacer un montón deCAST
oCONVERT
declaraciones.ISDATE()
, que devuelve 1 para fechas válidas y 0 para fechas no válidas.y%m=0
) en laWHERE
clá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
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.IIF
conWHERE
MS-SQL 2017,
121118 bytesMS-SQL 2017, edición extra cheaty: 109 bytes
Requiere que esté en la
master
base de datos, que contiene una tabla del sistemaspt_values
que (cuando se filtra porTYPE='P'
), le proporciona números de conteo del 0 al 2048.fuente
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.SPLIT_STRING
lugar de un CTE lo reduce a 120 bytes. Usar enCONCAT_WS
lugar deCONCAT
guardar otro carácter, llevándolo a 119 bytes.IIF
conWHERE
.Julia 0.6 ,
494442 bytesPrué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
i
del 1 al 12, calculey/i
y 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%2
oi÷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+3
es decir1:31
, de lo contrario verificamos solo las fechas1:28
.1:28
es 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
, pero2058
no 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
(yi*30
) serían superiores a 100, lo que puede ignorarse.Finalmente, contamos el número de veces que
y/i
pertenece a esta lista de días (usando booleansum
aquí), y devolvemos eso.fuente
JavaScript,
9185828177 bytesToma la entrada como una cadena de 2 dígitos (o un entero de 1 o 2 dígitos).
Aprovecha el hecho de que
new Date
pasará 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 fechayyyy-01-345
que se convierteyyyy-12-11
, oyyyy-12-10
en años bisiestos. No necesitamos verificar las fechas después de eso, ya que12*11+
da como resultado un número de 3 dígitos.3 bytes guardados gracias a Arnauld .
Pruébalo
fuente
Python 2 ,
89846858 bytesPruébalo en línea!
fuente
Excel, 83 bytes
La entrada está en la celda
A1
en el formatoyyyy
. 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 porque1*1=1
solo contaría como falso positivo si el próximo año es2001
, pero, dado que el rango de año requerido es2001 - 2099
, nunca surgirá como un problema.Si acortó esa parte simplemente
~
, la fórmula es mucho más fácil de seguir: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 usandoCountIf()
pero el mismo método de otro modo que resultó ser de 91 bytes, en su mayoría, ya que utilizaArrayFormula()
en lugar de simplemente{ }
.fuente
Retina 0.8.2 , 55 bytes
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.
fuente
R ,
22122 bytesPrué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.
fuente
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.C (gcc),
656059 bytesPuerto de la respuesta Java de user202729 . Pruébelo en línea aquí . Gracias a Jonathan Frech por jugar al golf 1 byte.
fuente
a=0,m=13;for(;
~>for(a=0,m=13;
.J , 29 bytes
Pruébalo en línea!
Cómo funciona
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
<4
y 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.fuente
Pitón 3 , 158
162215241bytesEliminado 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.
Pruébalo en línea!
fuente
(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,c
se puede agregar en la lista de parámetros para guardar una línea.int(str(Y)[2:])
se puede acortar aY%100
. Finalmente, las variables de contador se pueden acortar en su mayoría alen
s de comprensión de listas, esto también permiten
hacer alambda
. Esto hace 118 .Adelante (gforth) ,
6059 bytesPrué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
[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
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
fuente
Java (JDK 10) ,
797270 bytesPruébalo en línea!
fuente
d
&&
a&
, es la misma respuesta que la respuesta Java de OlivierGrégoire, aunque ha respondido 19 minutos antes.JavaScript (Node.js) , 108 bytes
fuente
Perl 5 , 68 bytes
Pruébalo en línea!
fuente
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.
66 bytes + archivo de 37 bytes = 103 bytes
Esto lee un archivo binario llamado
e
y evita usar base64.Aquí hay un hexdump del archivo de lectura (sin relleno):
fuente
Haskell ,
6151 bytesPruébalo en línea!
Inspirado en la respuesta Python 2 de xnor y Laikoni.
fuente
f y=sum[1|i<-[1..12],mod y i<1,div y i<29+mod i 2*3]
Pruébelo en línea!Oracle SQL, 115 bytes
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
Oracle SQL (12c Release 2 y posterior), 137 bytes
Tanto solución podría haber sido 8 bytes más corto si reemplazamos
(select level l from dual connect by level<=12)
conxmltable('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).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
Oracle SQL, 126 bytes
Actualizar
Oracle SQL, 110 bytes
Oracle SQL, 108 bytes
Spark SQL, 137 bytes
Spark 2.3+ SQL, 126 bytes
(la
replace
función está disponible)fuente
PHP , 73 bytes
Usando entrada de tubería y
php -nR
:Pruébalo en línea!
PHP , 76 bytes
Usando la entrada de línea de comando arg
php dm.php 18
: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
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 demktime()
.fuente
$m<5?$m-2?31:28:25
por el primero y$d=strtotime("$y-1")
por el segundoy
en la evaluación entre comillas?strtotime()
lugar demktime()
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!PHP,
7470 bytesacepta 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):
%100
permite usar años de 4 dígitos.Ejecutar como tubería
-nR
o probarlos en línea .fuente