Inspirado em um cenário da vida real, ao qual solicitei uma resposta aqui: /superuser/1312212/writing-a-formula-to-count-how-many-times-each-date- aparece em um conjunto de datas
Dada uma matriz de intervalos de tempo (ou pares de datas de início e término), produza uma contagem de quantos intervalos de tempo abrangem todos os dias, para todos os dias no intervalo total.
Por exemplo:
# 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 os dados acima, os resultados devem ser os seguintes:
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)
Você só precisa exibir as contagens para cada dia (em ordem, classificadas da mais antiga para a mais nova); não em quais registros eles aparecem.
Você pode assumir que cada período de tempo contém apenas datas, não horários; e assim dias inteiros são sempre representados.
I / O
A entrada pode ser qualquer formato que represente um conjunto de intervalos de tempo - portanto, um conjunto de pares de horários ou uma coleção de objetos (integrados) que contêm datas de início e término. A data e hora são limitadas entre 1901 e 2099, como é normal para os desafios do PPCG.
Você pode assumir que a entrada é pré-classificada da maneira que desejar (especifique na sua resposta). As datas de entrada são inclusivas (portanto, o intervalo inclui todas as datas de início e término).
Você também pode assumir que, das duas datas em um determinado intervalo, a primeira será mais antiga ou igual à segunda (ou seja, você não terá um período negativo).
A saída é uma matriz que contém a contagem para cada dia, da mais antiga à mais recente na entrada quando classificada por Data de Início.
Portanto, a saída para o exemplo acima seria {3,2,2,0,1}
É possível que alguns dias não sejam incluídos em nenhum intervalo de tempo; nesse caso, a 0
saída será para essa data.
Critérios Vencedores
Isso é código-golfe, então os bytes mais baixos vencem. Aplicam-se exclusões usuais
Exemplo 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
Outros algoritmos para obter o mesmo resultado são bons.
0
deveria estar em um dicionário? Parece apenas forçar o usuário a iterar demin(input)
paramax(input)
, o que não parece acrescentar nada ao cerne do desafio (intervalos de tempo de computação).Respostas:
APL (Dyalog Unicode) , SBCS de 32 bytes
Programa completo. Solicita ao stdin uma lista de pares de números de datas internacionais (como o Excel e o MATLAB usam). A lista e os pares podem ser fornecidos em qualquer ordem, por exemplo (Fim, Início). Imprime a lista de contagens para stdout.
¯1+⊢∘≢⌸(R,⊢)∊(R←⌊/,⌊/+∘⍳⌈/-⌊/)¨⎕
Experimente online!Se isso for inválido, uma lista de pares (YMD) poderá ser convertida para 21 bytes adicionais, totalizando 53:
¯1+⊢∘≢⌸(R,⊢)∊(R⌊/,⌊/+∘⍳⌈/-⌊/)¨{2⎕NQ#'DateToIDN'⍵}¨¨⎕
Experimente online!⎕
console de prompt para entrada avaliada(
…)¨
Aplique a seguinte função tácita a cada par⌊/
o mínimo (lit. min-redução), ou seja, a data de início⌈/-
a data máxima (isto é, data final) menos⌊/+∘⍳
a data de início mais o intervalo de 1 a⌊/,
a data de início anexada a essaR←
atribuir esta função aR
(para R ange)∊
ε nlist (achatar) a lista de intervalos em uma única lista(
…)
Aplique a seguinte função tácita a isso:R,⊢
o resultado da aplicaçãoR
(ou seja, o período) seguido do argumento(isso garante que cada data no intervalo seja representada pelo menos uma vez e que as datas apareçam na ordem classificada)
…
⌸
Para cada par de dados únicos (data, seus índices de ocorrência na entrada), faça:⊢∘≢
ignore a data real em favor da contagem de índices¯1+
adicione -1 a essas notas (porque adicionamos um de cada data no intervalo)fonte
JavaScript (ES6), 85 bytes
Recebe entrada como uma lista de
Date
pares. Espera que a lista seja classificada por data de início. Retorna uma matriz de números inteiros.Experimente online!
ou 84 bytes, se pudermos usar timestamps JS como entrada (como sugerido por @Shaggy)
fonte
JavaScript,
7573 bytesRecebe a entrada como uma matriz classificada de matrizes de pares primitivos de datas, gera um objeto em que as chaves são as primitivas de cada data e os valores que são contadas nessas datas nos intervalos.
Tente
Eu estava trabalhando nessa versão de 60 bytes, até que foi confirmado que as datas que não aparecem em nenhum dos intervalos devem ser incluídas, então atualizei-a rapidamente para a solução acima.
Experimente on-line (ou com datas legíveis por humanos na saída )
fonte
Oitava , 63 bytes
Experimente online!
Agora isso foi feio!
Explicação:
Aceita a entrada como uma matriz de
datenum
elementos da célula (ou seja, uma string"2001-01-01"
convertida em um valor numérico, com a seguinte aparência:onde
d()
representa a funçãodatenum
. Em seguida, usamoscellfun
para criar células com os intervalos da primeira coluna à segunda para cada uma dessas linhas. Concatenamos esses intervalos horizontalmente, para termos um vetor horizontal longo com todas as datas.Em seguida, criamos um histograma usando
histc
esses valores, com compartimentos fornecidos pelo intervalo entre a data mais baixa e a mais alta.fonte
R , 75 bytes
Experimente online!
Input é uma matriz cuja primeira coluna é Start e a segunda coluna é End. Assume Início <= Final, mas não exige que as datas de início sejam classificadas.
fonte
hist
; você poderia fazerc(-25668,min(x):max(x))
desde-25568
antes,1900
mas isso acaba sendo mais longo do que a resposta sugerida. Dito isto, há uma maneira melhor de gerar as datas do queapply
; Eu tenho um que tem 68 bytes e não encontrei tempo para publicá-lo.(min(x)-1):max(x)
e deve funcionar como esperado; se você encontrar oapply
caminho para gerar as datas, poderá obtê-lo em 63 bytes e amarrar a resposta da oitava.table
efactor
antes do que era meu uso originalMap
por 68 bytes, mashist
é uma abordagem interessante que eu sempre esqueço, provavelmente porque é irritante fazer as caixas da maneira certa (como vimos )Vermelho , 174 bytes
Implementação bastante longa e literal.
Experimente online!
Legível:
fonte
Groovy, 142 bytes
O que outras pessoas estão dizendo
Formatado para fora:
fonte
Python 2 ,
1148793 bytes-27 bytes graças a Jonathan Allan
+6 bytes graças a sundar
Recebe entrada como lista de pares de objetos de data e hora.
Supõe que o primeiro par começa com a data mais baixa.
Experimente online!
fonte
days
é o argumento padrão paratimedelta
.from datetime import*
e substituird+=timedelta(days=1)
por,d+=type(d-d)(1)
já que as entradas já sãodate
s. 87 bytes[(2001-01-01, 2001-01-05), (2001-01-02, 2001-01-03)]
. A menos que o OP nos permita dividir e reorganizar esses intervalos durante o pré-processamento (o que parece improvável), essa entrada não pode ser processada por esse código corretamente.Wolfram Language (Mathematica) , 62 bytes
Experimente online!
+35 bytes porque OP especificado que
0
deve ser incluído na saída.Se a omissão de uma entrada em um dicionário fosse permitida, 27 bytes
Experimente online!
O built-in
DayRange
aceita doisDateObject
s (ou um equivalente de sequência) e gera uma listaDates
entre essas datas (inclusive).fonte
R ,
65bytes 63Experimente online!
Esta é uma colaboração entre JayCe e eu, portando a resposta de Stewie Griffin para R.
Para citar JayCe:
Possivelmente,
$c
é desnecessário, mas não está no espírito do desafio, então eu o incluí.fonte
Powershell,
122121118113 bytessalve-o como
count-timespan.ps1
. Script de teste:Explicação
fonte
$cnt.Keys.Date
claro.function
substituído porscriptblock
. códigos de golfe e não de golfe são testados.scriptblock
substituído emfilter
. A chamada de afilter
é mais compacta.J, 43 bytes
a entrada é uma lista de pares de números inteiros, em que cada número inteiro é o deslocamento de qualquer dia 0 arbitrário comum.
destroçado
explicação
estrutura é:
A&:B
a entrada à esquerda e a entrada achatada à direita((>./ (] + i.@>:@-) <./)"1)
pega o mínimo e o máximo de uma lista e retorna o intervalo resultante e atua com a classificação 1. portanto, fornece o intervalo total à direita e os intervalos individuais à esquerda.=
with rank"0 _
(ou seja, rank of{
) para contar quantas vezes cada entrada aparece em qualquer um dos intervalos. finalmente fecha todos os anos com essas contagens.Experimente online!
fonte
JavaScript (Node.js) , 80 bytes
Experimente online!
undefined
significa zero; O primeiro elemento deve começar o mais cedo(a,u=[])=>a.map(g=([p,q])=>p>q||g([p,q-1],u[z=(q-a[0][0])/864e5]=-~u[z]))&&u
é mais curto se você vir apenas elementos e usar mais pilhafonte
0
é aceitável.Ruby , 70 bytes
Experimente online!
Entrada:
Matriz de pares de datas, classificadas por data final decrescente.
fonte
R (70)
Pressupõe um quadro de dados
x
com duas colunas (Start
eEnd
ou possivelmenteS
eE
) com datas (classeDate
).Experimente online
fonte
library(magrittr)
precisa ser incluído nas contagens de bytes.x
sua resposta, começa comfunction(x)
o corpo da função.Julia 0,6 , 77 bytes
Experimente online!
Inspirado na solução Python da @ DeadPossum .
Recebe entrada como uma matriz, onde cada linha tem duas datas: as datas inicial e final de um intervalo de entrada. Supõe que a entrada tenha a data mais antiga primeiro e que cada linha tenha a data inicial primeiro, mas não assume nenhuma classificação além daquela entre linhas diferentes.
Solução mais antiga:
Julia 0.6 , 124 bytes
Experimente online!
Aceita entrada como uma matriz de períodos. Não assume nenhuma classificação entre os diferentes intervalos na matriz.
fonte