Trovare lacune negli intervalli di date


15

Dato un elenco di intervalli di date rcome input, output o restituire tutti gli intervalli non trovati r.

Per il bene di questo esempio, l'input sarà in YYYY-MM-DDformato.

Supponiamo che tu abbia tre intervalli di date:

[2019-01-01, 2019-02-01]
[2019-02-02, 2019-04-05]
[2019-06-01, 2019-07-01]

Puoi vedere che c'è un divario nel mezzo 2019-04-05 e 2019-06-01.

L'output sarà quello gap: [2019-04-06, 2019-05-31]

Regole

  • L'input e l'output possono essere in qualsiasi data o formato di raccolta ragionevoli, purché siano coerenti.
  • Supponiamo che l'input non sia ordinato.
  • L'intervallo di date non deve essere [latest, earliest] , ma deve seguire la regola 2.
  • Supponiamo che non vi siano date sovrapposte nell'input

Casi test:

Ingresso: [[2019-01-01, 2019-02-01],[2019-02-02, 2019-04-05],[2019-06-01, 2019-07-01]]

Produzione: [[2019-04-06, 2019-05-31]]


Ingresso: [[2019-01-01, 2019-02-01],[2018-02-02, 2018-04-05],[2019-06-01, 2019-07-01]]

Produzione: [[2018-04-06, 2018-12-31], [2019-02-02, 2019-05-31]]


Ingresso: [[2019-01-01, 2019-02-01],[2019-02-02, 2019-03-02],[2019-03-03, 2019-07-01]]

Produzione: []


Ingresso: [[2019-01-01, 2019-02-01], [2019-11-02, 2019-11-20]]

Produzione: [[2019-02-02, 2019-11-01]]


Ingresso: [[2019-01-01, 2019-02-01],[2019-02-03, 2019-04-05]]

Uscita: [[2019-02-02, 2019-02-02]]o[[2019-02-02]]


5
Suggerisco di rielaborare tutte le date di esempio in formato ISO, YYYY-MM-DDpoiché il formato corrente è sia estraneo a molte persone, sia reso ancora più difficile da analizzare a causa dell'utilizzo di piccoli giorni del mese ≤12.
Adám,

@ Adám Buona idea, aggiornata.
Oliver,

Possiamo prendere l'input come date di automazione .NET OLE?
Adám,

@ Adám Sì. È accettabile qualsiasi formato di data ragionevole.
Oliver,

1
Le date saranno ordinate? Inoltre, entro un paio di date, l'ultima sarà l'ultima?
Incarnazione dell'ignoranza il

Risposte:


4

APL (Dyalog Extended) , 28 25 24 byte

Funzione prefisso tacito anonimo. L'argomento e il risultato sono matrici a 2 colonne di numeri di giorno da un'epoca, ogni riga rappresenta un intervallo.

1 ¯1+⍤1∘{⍵⌿⍨1<-⍨/⍵}1⌽⍢,∧

Provalo online! La funzione Inpre-processore converte da un elenco di coppie di elenchi di 3 elementi (date in ordine ISO) in una matrice a 2 colonne di IDN, numeri di giorno internazionali (giorni dal 1899-12-31). La funzione Outpost-processore converte da una matrice di IDN a una matrice di elenchi a 3 elementi.

 ordina le righe in ordine crescente

1⌽ ruota ciclicamente le date di un passo a sinistra
⍢, mentre sei inchiodato (appiattito) - successivamente, rimodella di nuovo alla forma originale

1 ¯1+ aggiungi uno e uno negativo
⍤1 usando quell'elenco per ogni riga
 del risultato di
{... } il seguente lambda:
 l'argomento
-⍨/ sottrae la data di sinistra dalla data di destra, la
1< maschera di riga dove le differenze superano un
⍵⌿⍨ filtro (cioè dove gli intervalli non sono adiacenti) le righe di quella maschera


3

C # (compilatore interattivo Visual C #) , 108 byte

n=>{n.Sort();for(int i=0;;)Write(n[i].b.AddDays(1)==n[++i].a?"":n[i-1].b.AddDays(1)+""+n[i].a.AddDays(-1));}

Stampa stampando nel formato DD/MM/YYYY 12:00:00 AMDD/MM/YYYY 12:00:00 AM. Provocherà un'eccezione IndexOutOfRange, che va bene per meta consenso.

Provalo online!

Se prendiamo input in forma di giorni dall'epoca di unix, possiamo ottenere questo fino a ...

83 byte

n=>{n.Sort();for(int i=0;;)Print(n[i].b+1==n[++i].a?"":n[i-1].b+1+" "+(n[i].a-1));}

Provalo online!

Possiamo giocare ancora più in basso con la /u:System.Arraybandiera, per ...

78 byte

n=>{Sort(n);for(int i=0;;)Print(++n[i].b==n[++i].a--?"":n[i-1].b+" "+n[i].a);}

Provalo online!


2

Perl 5, 130 byte

/-(\d+)-/,$_=strftime"%Y-%m-%d",0,0,0,$'+($|--||-1),$1-1,$`-1900 for@F=sort@F;$,lt$;&&say"$, $;"while($,,$;)=@F[++$i,$i+1],++$i<@F

TIO


2

Bash, 125 byte

set `sort<<<$1`;shift;for a;{ s=$[x++%2?-1:1]day;c=`date -d$a\ $s +%Y-%m-%d`;[ $p ]&&{ [[ $p < $c ]]&&echo $p $c;p=;}||p=$c;}

TIO



2

PHP, 208 197 190 177 byte

grosso grosso era seduto su un muro ... sebbene il nuovo approccio avesse un certo potenziale di golf.

function($a){sort($a);for($m=$x=$a[0][0];$f=$m<=$x;$f^$g&&print($g=$f)?"$m/":"$n
",$m=date("Y-m-d",strtotime($n=$m)+9e4))foreach($a as$d)$x=max($x,$d[1|$f&=$m<$d[0]|$m>$d[1]]);}

La funzione accetta una serie di intervalli [inizio, fine] in formato ISO, stampa intervalli di spazio. Provalo online .


abbattersi

function($a){
    sort($a);                           # sort ranges (for easy access to min date)
    for($m=$x=$a[0][0];$f=$m<=$x;       # loop from min date to max date, 1. set flag
        $f^$g&&print($g=$f)?"$m/":"$n\n",       # 4. flag changed: backup flag, print date
        $m=date("Y-m-d",strtotime($n=$m)+9e4)   # 5. backup and increment date
    )foreach($a as$d)
        $x=max($x,$d[1                          # 2. find max date
            |$f&=$m<$d[0]|$m>$d[1]              # 3. date found in ranges: clear flag
        ]);
}

1

Gelatina , 13 byte

FṢṖḊs2+Ø+>/Ðḟ

Jelly (attualmente) non ha date integrate, quindi utilizza giorni dall'epoca.
L'elenco di input degli intervalli (coppie di numeri interi) può essere in ordine misto e direzioni miste.
Il risultato è un elenco di intervalli crescenti in ordine crescente.

Provalo online! (formati piè di pagina per mostrare un elenco vuoto come[])

Come?

Nota: ciò si basa sull'assicurazione che "non ci sono date sovrapposte nell'input" come indicato nelle regole.

FṢṖḊs2+Ø+>/Ðḟ - Link: list of pairs of integers
F             - flatten
 Ṣ            - sort
  Ṗ           - pop (remove tail)
   Ḋ          - dequeue (remove head)
    s2        - split into twos
       Ø+     - literal [1,-1]
      +       - add (vectorises)
           Ðḟ - filter discard those for which:
          /   -   reduce by:
         >    -     greater than?

Interessante, non sapevo che Jelly non avesse il supporto per la data. È questo il solito approccio? Usi giorni dall'epoca?
dana,

Giorni dall'epoca, credo, sono usati da alcuni sistemi (forse Excel). Secondi dall'epoca è più comune (ad es. Unix). Sono appena andato con qualcosa che sembra coprire i requisiti, anche se in modo abbastanza lassista.
Jonathan Allan,

Boo, potresti calcolare le date manualmente . ; P Giorni dall'epoca in effetti è usato più spesso per le lingue che non supportano le date. Sento che rende questa sfida MOLTO più semplice, però.
Kevin Cruijssen,

@KevinCruijssen heh, d'accordo.
Jonathan Allan,

1

C # (compilatore interattivo Visual C #) , 103 byte

x=>{var(a,_)=x[0];foreach(var(b,c)in x.OrderBy(y=>y)){if(a<b)Print((a,b.AddDays(-1)));a=c.AddDays(1);}}

Provalo online!

L'input è un elenco di tuple della data di inizio / fine. Invia ogni intervallo mancante a STDOUT.

// x: input list of start/end date tuples
x=>{
  // variable definitions...
  // a: 1 day after the end date of the previous range
  // b: start of the current range
  // c: end of the current range

  // start by deconstructing the start date of the first tuple
  // into a. a will then be a DateTime and will contain a value
  // at least a large as the smallest start date.
  var(a,_)=x[0];
  // iterate over sorted ranges
  foreach(var(b,c)in x.OrderBy(y=>y)){
    // if the day after the end of the previous range is less
    // than the start of the current range, then print the
    // missing days.
    if(a<b)
      Print((a,b.AddDays(-1)));
    // save the day after the current range to a for next iteration
    a=c.AddDays(1);
  }
}


Hah - se stampi come Embodiment of Ignorance puoi diventare davvero piccolo - Provalo online!
dana,

Bello. Anche il loro metodo di input per gli ultimi due
solo ASCII il

Beh, in realtà ... sembra davvero errato
solo ASCII il

1
Sì, ora sembra a posto
solo ASCII il

1

R , 88 byte

function(a,b=a[order(a$x),],d=c(b$x[-1]-b$y[-nrow(b)],0))data.frame(b$y+1,b$y+d-1)[d>1,]

Provalo online!

Ciò accetta un frame di dati di intervalli di date come input e genera un frame di dati con gli intervalli mancanti. Sono abbastanza sicuro che questo potrebbe essere giocato a golf di più, ma mi sono imbattuto in problemi con c, cbinde altri strippaggio la classe data.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.