Inspirado en un escenario de la vida real, al que he pedido una respuesta aquí: /superuser/1312212/writing-a-formula-to-count-how-many-times-each-date- aparece en un conjunto de fechas
Dada una serie de intervalos de tiempo (o pares de fecha de inicio-fin), genera un recuento de cuántos intervalos de tiempo cubren cada día, para todos los días en el rango total.
Por ejemplo:
# Start End
1 2001-01-01 2001-01-01
2 2001-01-01 2001-01-03
3 2001-01-01 2001-01-02
4 2001-01-03 2001-01-03
5 2001-01-05 2001-01-05
Dados los datos anteriores, los resultados deberían ser los siguientes:
2001-01-01: 3 (Records 1,2,3)
2001-01-02: 2 (Records 2,3)
2001-01-03: 2 (Records 2,4)
2001-01-04: 0
2001-01-05: 1 (Record 5)
Solo necesita generar los recuentos de cada día (en orden, ordenados más antiguo-más nuevo); no en qué registros aparecen.
Puede suponer que cada intervalo de tiempo solo contiene fechas, no horarios; y así días completos siempre están representados.
I / O
La entrada puede ser cualquier formato que represente un conjunto de intervalos de tiempo, por lo que puede ser un conjunto de pares de tiempos o una colección de objetos (incorporados) que contienen fechas de inicio y finalización. Las fechas y horas están limitadas entre 1901 y 2099, como es normal para los desafíos de PPCG.
Puede suponer que la entrada está ordenada previamente como desee (especifique en su respuesta). Las fechas de entrada son inclusivas (por lo que el rango incluye la totalidad de las fechas de inicio y finalización).
También puede suponer que, de las dos fechas en cualquier rango dado, la primera será más antigua o igual a la segunda (es decir, no tendrá un rango de fechas negativo).
La salida es una matriz que contiene el recuento de cada día, desde el más antiguo hasta el más nuevo en la entrada cuando se ordena por Fecha de inicio.
Entonces, la salida para el ejemplo anterior sería {3,2,2,0,1}
Es posible que algunos días no se incluyan en ningún intervalo de tiempo, en cuyo caso 0
se emite para esa fecha.
Criterios ganadores
Este es el código de golf, por lo que gana los bytes más bajos. Se aplican exclusiones habituales.
Ejemplo de pseudo algoritmo
For each time range in input
If start is older than current oldest, update current oldest
If end is newer than current newest, update current newest
End For
For each day in range oldest..newest
For each time range
If timerange contains day
add 1 to count for day
End For
Output count array
Otros algoritmos para llegar al mismo resultado están bien.
0
debería estar en un diccionario? Solo parece forzar al usuario a iterar demin(input)
amax(input)
, lo que no parece agregar nada al núcleo del desafío (tiempos de cálculo).Respuestas:
APL (Dyalog Unicode) , SBCS de 32 bytes
Programa completo Solicita stdin para obtener una lista de pares de números de fecha internacional (como lo que usan Excel y MATLAB). Tanto la lista como los pares se pueden dar en cualquier orden, por ejemplo (Fin, Inicio). Imprime la lista de recuentos en stdout.
¯1+⊢∘≢⌸(R,⊢)∊(R←⌊/,⌊/+∘⍳⌈/-⌊/)¨⎕
Pruébalo en línea!Si esto no es válido, se puede convertir una lista de pares (YMD) para 21 bytes adicionales, con un total de 53:
¯1+⊢∘≢⌸(R,⊢)∊(R⌊/,⌊/+∘⍳⌈/-⌊/)¨{2⎕NQ#'DateToIDN'⍵}¨¨⎕
Pruébalo en línea!⎕
consola de solicitud de entrada evaluada(
...)¨
aplique la siguiente función tácita a cada par⌊/
el mínimo (lit. min-reducción), es decir, la fecha de inicio⌈/-
el máximo (es decir, la fecha de finalización) menos eso⌊/+∘⍳
la fecha de inicio más el rango de 1 a ese⌊/,
la fecha de inicio antepuesta a esoR←
asignar esta función aR
(para R ange)∊
ε nlist (aplanar) la lista de rangos en una sola lista(
…)
Aplica la siguiente función tácita a eso:R,⊢
el resultado de la aplicaciónR
(es decir, el intervalo de fechas) seguido del argumento(esto asegura que cada fecha en el intervalo se represente al menos una vez y que las fechas aparezcan en orden)
...
⌸
para cada par de únicos (fecha, sus índices de ocurrencia en la entrada), haga:⊢∘≢
ignorar la fecha real a favor de la cuenta de índices¯1+
agregue -1 a esas cuentas (porque anteponemos una de cada fecha en el rango)fuente
JavaScript (ES6), 85 bytes
Toma la entrada como una lista de
Date
pares. Espera que la lista se ordene por fecha de inicio. Devuelve una matriz de enteros.Pruébalo en línea!
o 84 bytes si podemos tomar las marcas de tiempo JS como entrada (como lo sugiere @Shaggy)
fuente
JavaScript,
7573 bytesToma la entrada como un conjunto ordenado de conjuntos de pares de primitivas de fecha, genera un objeto donde las claves son las primitivas de cada fecha y los valores los recuentos de esas fechas en los rangos.
Intentalo
Estaba trabajando en esta versión de 60 bytes hasta que se confirmó que las fechas que no aparecen en ninguno de los rangos deben incluirse, por lo que la actualicé rápidamente a la solución anterior.
Pruébelo en línea (o con fechas legibles por humanos en la salida )
fuente
Octava , 63 bytes
Pruébalo en línea!
¡Eso sí que fue feo!
Explicación:
Toma la entrada como una matriz de
datenum
elementos de celdas (es decir, una cadena"2001-01-01"
convertida a un valor numérico, que se ve así:donde
d()
es la funcióndatenum
. Luego usamoscellfun
para crear celdas con los rangos de la primera columna a la segunda para cada una de esas filas. Concatenamos estos rangos horizontalmente, de modo que tenemos un vector horizontal largo con todas las fechas.Luego creamos un histograma utilizando
histc
estos valores, con bins dados por el rango entre la fecha más baja y la más alta.fuente
R , 75 bytes
Pruébalo en línea!
La entrada es una matriz cuya primera columna es Inicio y la segunda columna es Fin. Asume que Start <= End pero no requiere que se ordenen las fechas de Inicio.
fuente
hist
; podría hacerloc(-25668,min(x):max(x))
desde-25568
antes,1900
pero esto termina siendo más largo que la respuesta sugerida. Dicho esto, hay una mejor manera de generar las fechas queapply
; Tengo uno que tiene 68 bytes y simplemente no he encontrado el tiempo para publicarlo yo mismo.(min(x)-1):max(x)
y debería funcionar como se esperaba; entonces, si puede encontrar la noapply
manera de generar las fechas, puede obtener esto en 63 bytes y vincular la respuesta de octava.table
yfactor
antes de lo cual era mi uso original deMap
68 bytes, perohist
es un enfoque ordenado que siempre olvido, probablemente porque es molesto tener los contenedores correctamente (como hemos visto )Rojo , 174 bytes
Implementación bastante larga y literal.
Pruébalo en línea!
Legible:
fuente
Groovy, 142 bytes
Formateado:
fuente
Pitón 2 ,
1148793 bytes-27 bytes gracias a Jonathan Allan
+6 bytes gracias a sundar
Toma datos como una lista de pares de objetos de fecha y hora.
Asume que el primer par comienza con la fecha más baja.
Pruébalo en línea!
fuente
days
es el argumento predeterminado paratimedelta
.from datetime import*
y reemplazard+=timedelta(days=1)
cond+=type(d-d)(1)
puesto que las entradas están yadate
lo es. 87 bytes[(2001-01-01, 2001-01-05), (2001-01-02, 2001-01-03)]
. A menos que OP nos permita dividir y reorganizar estos rangos durante el preprocesamiento (lo que parece poco probable), este código no puede procesar esta entrada correctamente.Wolfram Language (Mathematica) , 62 bytes
Pruébalo en línea!
+35 bytes porque OP especificó que
0
debe incluirse en la salida.Si se permitiera omitir una entrada en un diccionario, 27 bytes
Pruébalo en línea!
El incorporado
DayRange
acepta dosDateObject
s (o un equivalente de cadena) y genera una lista deDates
entre esas fechas (inclusive).fuente
R ,
6563 bytesPruébalo en línea!
Esta es una colaboración entre JayCe y yo, portando la respuesta de Stewie Griffin a R.
Para citar a JayCe:
Posiblemente,
$c
es innecesario, pero no está del todo en el espíritu del desafío, así que lo he incluido.fuente
PowerShell,
122121118113 bytesguárdelo como
count-timespan.ps1
. Script de prueba:Explicación
fuente
$cnt.Keys.Date
por supuesto.function
reemplazado conscriptblock
. Se prueban los códigos de golf y de golf.scriptblock
reemplazado enfilter
. La llamada de afilter
es más compacta.J, 43 bytes
la entrada es una lista de pares de enteros, donde cada entero es el desplazamiento de cualquier día 0 arbitrario común.
sin golf
explicación
estructura es:
A&:B
la entrada a la izquierda y la entrada aplanada a la derecha((>./ (] + i.@>:@-) <./)"1)
toma el mínimo y el máximo de una lista y devuelve el rango resultante, y actúa con el rango 1. por lo tanto, da el rango total a la derecha y los rangos individuales a la izquierda.=
con rango"0 _
(es decir, rango de{
) para contar cuántas veces aparece cada entrada en cualquiera de los rangos. finalmente se cierra todos los años con esos recuentos.Pruébalo en línea!
fuente
JavaScript (Node.js) , 80 bytes
Pruébalo en línea!
undefined
significa cero; El primer elemento debe comenzar más temprano(a,u=[])=>a.map(g=([p,q])=>p>q||g([p,q-1],u[z=(q-a[0][0])/864e5]=-~u[z]))&&u
es más corto si solo ve elementos y usa más pilafuente
0
es aceptable sustituirlo por otro valor .Ruby , 70 bytes
Pruébalo en línea!
Entrada:
Matriz de pares de fechas, ordenadas por fecha de finalización descendente.
fuente
R (70)
Presume un marco de datos
x
con dos columnas (Start
y /End
o posiblementeS
yE
) con fechas (claseDate
).Pruébalo en línea
fuente
library(magrittr)
debe incluirse en el recuento de bytes.x
su respuesta comienza confunction(x)
y luego el cuerpo de la función.Julia 0.6 , 77 bytes
Pruébalo en línea!
Inspirado en la solución Python de @ DeadPossum .
Toma la entrada como una matriz, donde cada fila tiene dos fechas: las fechas de inicio y finalización de un rango de entrada. Asume que la entrada tiene la fecha más temprana primero, y que cada fila tiene la fecha de inicio primero, pero no asume ningún orden más allá de eso entre diferentes filas.
Solución anterior:
Julia 0.6 , 124 bytes
Pruébalo en línea!
Acepta entradas como una matriz de rangos de fechas. No asume ninguna clasificación entre los diferentes rangos de la matriz.
fuente