Auffinden von Lücken in Datumsbereichen


15

Geben Sie eine Liste von Datumsbereichen rals Eingabe, Ausgabe oder Rückgabe von Bereichen ein, die in nicht gefunden wurden r.

In diesem Beispiel erfolgt die Eingabe im YYYY-MM-DDFormat.

Angenommen, Sie haben drei Datumsbereiche:

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

Sie können sehen, dass es eine Lücke zwischen 2019-04-05und gibt 2019-06-01.

Die Ausgabe wird diese Lücke sein: [2019-04-06, 2019-05-31]

Regeln

  • Die Eingabe und Ausgabe kann in jedem vernünftigen Datums- oder Erfassungsformat erfolgen, sofern dies konsistent ist.
  • Angenommen, der Eingang ist nicht geordnet.
  • Ihr Datumsbereich muss nicht sein [latest, earliest], er muss jedoch Regel 2 entsprechen.
  • Angenommen, die Eingabe enthält keine überlappenden Daten

Testfälle:

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

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


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

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


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

Ausgabe: []


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

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


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

Ausgabe: [[2019-02-02, 2019-02-02]]oder[[2019-02-02]]


5
Ich schlage vor, alle Beispieldaten auf das ISO-Format umzustellen, YYYY-MM-DDda das aktuelle Format vielen Menschen fremd ist und das Parsen aufgrund der Verwendung von kleinen Tagen im Monat ≤ 12 noch schwieriger wird.
Adám

@Adam Gute Idee, aktualisiert.
Oliver

Dürfen wir Eingaben als .NET OLE-Automatisierungsdaten annehmen?
Adám

@ Adám Ja. Jedes vernünftige Datumsformat ist akzeptabel.
Oliver

1
Werden die Termine bestellt? Wird das spätere Datum innerhalb eines Datumspaares das letzte sein?
Verkörperung der Ignoranz

Antworten:


4

APL (Dyalog Extended) , 28 25 24 Bytes

Anonyme implizite Präfixfunktion. Argument und Ergebnis sind zweispaltige Matrizen von Tageszahlen seit einer Epoche, wobei jede Zeile einen Bereich darstellt.

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

Probieren Sie es online! Die InVorverarbeitungsfunktion konvertiert aus einer Liste von Paaren von Listen mit drei Elementen (Daten in ISO-Reihenfolge) eine zweispaltige Matrix von IDNs (International Day Numbers) (Tage seit dem 31.12.18999). Die OutPostprozessorfunktion konvertiert von einer Matrix von IDNs in eine Matrix von Listen mit drei Elementen.

 Zeilen aufsteigend sortieren

1⌽ Drehen Sie die Datteln zyklisch um einen Schritt nach links,
⍢, während Sie sie geglättet haben, und formen Sie sie anschließend wieder in ihre ursprüngliche Form zurück

1 ¯1+ Fügen Sie eine und eine negative unter
⍤1 Verwendung dieser Liste für jede Zeile
 des Ergebnisses von
{... } dem folgenden Lambda hinzu:
 Das Argument
-⍨/ subtrahieren das Datum der linken Hand vom Datum der rechten Hand, zeilenweise
1< Maske, bei der Unterschiede einen
⍵⌿⍨ Filter überschreiten (dh bei denen Bereiche nicht benachbart sind) die Zeilen von dieser Maske


3

C # (Visual C # Interactive Compiler) , 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));}

Ausgabe durch Drucken im Format DD/MM/YYYY 12:00:00 AMDD/MM/YYYY 12:00:00 AM. Verursacht eine IndexOutOfRange-Ausnahme, die gemäß Metakonsens in Ordnung ist.

Probieren Sie es online!

Wenn wir Eingaben in Form von Tagen seit der Unix-Epoche machen, können wir dies auf ...

83 Bytes

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

Probieren Sie es online!

Wir können das mit der /u:System.ArrayFlagge noch weiter nach unten spielen , denn ...

78 Bytes

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

Probieren Sie es online!


2

Perl 5, 130 Bytes

/-(\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 Bytes

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 Bytes

Hunky Chunky saß an einer Wand ... obwohl der neue Ansatz einiges an Golfpotential hatte.

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]]);}

Funktion nimmt Array von Bereichen [Start, Ende] im ISO-Format, druckt Lückenintervalle. Probieren Sie es online aus .


Nervenzusammenbruch

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

Gelee , 13 Bytes

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

Jelly hat (derzeit) keine eingebauten Daten, daher werden Tage seit der Epoche verwendet.
Die Eingabeliste der Bereiche (Paare von ganzen Zahlen) kann in gemischter Reihenfolge und in gemischten Richtungen vorliegen.
Das Ergebnis ist eine Liste aufsteigender Bereiche in aufsteigender Reihenfolge.

Probieren Sie es online! (Fußzeilenformate, um eine leere Liste als[] )

Wie?

Hinweis: Dies beruht auf der Gewissheit, dass "keine überlappenden Daten in der Eingabe vorhanden sind", wie in den Regeln angegeben.

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?

Interessant, ich wusste nicht, dass Jelly keine Date-Unterstützung hatte. Ist das der übliche Ansatz? Verwenden Sie Tage seit der Epoche?
Dana

Ich glaube, Tage seit der Epoche werden von einigen Systemen verwendet (Excel vielleicht). Sekunden seit der Epoche sind häufiger (z. B. Unix). Ich habe mich nur für etwas entschieden, das den Anforderungen gerecht zu werden scheint, wenn auch ziemlich locker.
Jonathan Allan

Boo, Sie könnten die Daten manuell berechnen . ; P Tage seit Epoche werden in der Tat häufiger für Sprachen verwendet, die keine Datumsangaben unterstützen. Ich habe das Gefühl, dass es diese Herausforderung sehr viel einfacher macht.
Kevin Cruijssen

@ KevinCruijssen heh, einverstanden.
Jonathan Allan

1

C # (Visual C # Interactive Compiler) , 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);}}

Probieren Sie es online!

Die Eingabe ist eine Liste von Start- / Enddatumstupeln. Gibt jeden fehlenden Bereich an STDOUT aus.

// 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 - wenn Sie wie Verkörperung der Ignoranz drucken, können Sie wirklich klein werden - versuchen Sie es online!
Dana

Nett. Auch wtf ihre Eingabemethode für die beiden letzteren
ASCII

Naja eigentlich ... das sieht wirklich falsch aus
ASCII

1
Ja, das sieht jetzt gut aus
ASCII

1

R 88 Bytes

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,]

Probieren Sie es online!

Dies nimmt einen Datenrahmen von Datumsbereichen als Eingabe und gibt einen Datenrahmen mit den Bereichen aus, die fehlen. Ich bin mir ziemlich sicher, dass dies mehr Golf sein könnte, aber ich bin auf Probleme gestoßen c, cbindund andere, die die Date-Klasse strippen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.