Znajdowanie luk w zakresach dat


15

Podano listę zakresów dat rjako dane wejściowe, wyjściowe lub zwracające wszelkie zakresy, których nie znaleziono w r.

Na potrzeby tego przykładu dane wejściowe będą miały YYYY-MM-DDformat.

Załóżmy, że masz trzy zakresy dat:

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

Widać, że istnieje przerwa między 2019-04-05i 2019-06-01.

Wynik będzie taki: [2019-04-06, 2019-05-31]

Zasady

  • Dane wejściowe i wyjściowe mogą mieć dowolny rozsądny format daty lub kolekcji, o ile są spójne.
  • Załóż, że dane wejściowe nie są uporządkowane.
  • Twój zakres dat nie musi być [latest, earliest], ale musi być zgodny z regułą 2.
  • Załóżmy, że dane wejściowe nie pokrywają się

Przypadki testowe:

Wejście: [[2019-01-01, 2019-02-01],[2019-02-02, 2019-04-05],[2019-06-01, 2019-07-01]]

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


Wejście: [[2019-01-01, 2019-02-01],[2018-02-02, 2018-04-05],[2019-06-01, 2019-07-01]]

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


Wejście: [[2019-01-01, 2019-02-01],[2019-02-02, 2019-03-02],[2019-03-03, 2019-07-01]]

Wynik: []


Wejście: [[2019-01-01, 2019-02-01], [2019-11-02, 2019-11-20]]

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


Wejście: [[2019-01-01, 2019-02-01],[2019-02-03, 2019-04-05]]

Wyjście: [[2019-02-02, 2019-02-02]]lub[[2019-02-02]]


5
Proponuję przerobić wszystkie przykładowe daty do formatu ISO, YYYY-MM-DDponieważ obecny format jest obcy dla wielu osób, a jeszcze trudniejszy do przeanalizowania ze względu na użycie małych dni miesiąca ≤12.
— Adám

@ Adám Dobry pomysł, zaktualizowany.
— Oliver

Czy możemy przyjąć dane jako daty automatyzacji OLE .NET?
— Adám

@ Adám Tak. Dowolny rozsądny format daty jest dopuszczalny.
— Oliver

1
Czy terminy zostaną zamówione? Czy w ciągu kilku dat późniejsza będzie ostatnia?
— Embodiment of Ignorance

Odpowiedzi:


4

APL (Dyalog Extended) , 28 25 24 bajtów

Anonimowa ukryta funkcja prefiksu. Argument i wynik to 2-kolumnowe macierze liczb dni od epoki, każdy wiersz reprezentuje zakres.

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

Wypróbuj online! Funkcja Inpreprocesora konwertuje z listy par list 3-elementowych (daty w kolejności ISO) na 2-kolumnową macierz IDN, międzynarodowe numery dni (dni od 1899-12-31). Funkcja Outpostprocesora konwertuje z macierzy IDN na macierz list 3-elementowych.

∧ sortuj rzędy rosnąco

1⌽ cyklicznie obracaj daty o jeden krok w lewo,
 ⍢, gdy jesteś zniszczony (spłaszczony) - następnie przekształć z powrotem do pierwotnego kształtu

1 ¯1+ dodaj jeden i jeden ujemny,
⍤1 używając tej listy dla każdego wiersza
∘ wyniku
{… } następującej lambdy:
 ⍵ argument
 -⍨/ odejmij datę po lewej stronie od daty po prawej stronie,
 1< maskę w wierszach, gdzie różnice przekraczają jeden (tzn. gdy zakresy nie sąsiadują)
 ⍵⌿⍨ filtr rzędy przy tej masce


3

C # (interaktywny kompilator Visual C #) , 108 bajtów

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

Wysyła przez wydruk w formacie DD/MM/YYYY 12:00:00 AMDD/MM/YYYY 12:00:00 AM. Powoduje wyjątek IndexOutOfRange, który jest w porządku zgodnie z meta konsensusem.

Wypróbuj online!

Jeśli weźmiemy wkład w postaci dni od epoki unixu, możemy sprowadzić to do ...

83 bajty

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

Wypróbuj online!

Możemy zagrać w golfa jeszcze bardziej z /u:System.Arrayflagą, ponieważ ...

78 bajtów

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

Wypróbuj online!


2

Perl 5, 130 bajtów

/-(\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 bajtów

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 bajtów

gruby, gruby siedział na ścianie ... choć nowe podejście miało całkiem spory potencjał golfowy.

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

funkcja przyjmuje tablicę zakresów [początek, koniec] w formacie ISO, drukuje interwały odstępów. Wypróbuj online .


awaria

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

Galaretka , 13 bajtów

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

Galaretka (obecnie) nie ma wbudowanych dat, więc korzysta z dni od epoki.
Lista wejściowa zakresów (par liczb całkowitych) może być w kolejności mieszanej i kierunkach mieszanych.
Wynikiem jest lista rosnących zakresów w kolejności rosnącej.

Wypróbuj online!(formaty stopek, aby wyświetlić pustą listę jako [])

W jaki sposób?

Uwaga: Opiera się to na zapewnieniu, że „dane wejściowe nie nakładają się”, zgodnie z zasadami.

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?

Co ciekawe, nie wiedziałem, że Jelly nie ma wsparcia daty. Czy to jest zwykłe podejście? Używać dni od epoki?
— dana

Wierzę, że dni od epoki są używane przez niektóre systemy (być może Excel). Sekundy od epoki są bardziej powszechne (np. Unix). Po prostu poszedłem z czymś, co wydaje się pokrywać wymagania, choć dość luźne.
— Jonathan Allan

Boo, możesz ręcznie obliczyć daty . ; P Dni od epoki są rzeczywiście częściej używane dla języków, które nie obsługują dat. Wydaje mi się, że dzięki temu to wyzwanie jest DUŻO łatwiejsze.
— Kevin Cruijssen

@KevinCruijssen heh, zgodził się.
— Jonathan Allan

1

C # (interaktywny kompilator Visual C #) , 103 bajty

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

Wypróbuj online!

Dane wejściowe to lista krotek daty początkowej / końcowej. Wysyła każdy brakujący zakres do 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 - jeśli drukujesz jak Embodiment of Ignorance, możesz stać się naprawdę mały - wypróbuj online!
— dana

Ładny. Również wtf ich metoda wprowadzania dla dwóch ostatnich
— tylko ASCII

Cóż, właściwie ... to wygląda naprawdę niepoprawnie
— tylko ASCII

1
Tak, teraz wygląda dobrze
— tylko ASCII

1

R , 88 bajtów

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

Wypróbuj online!

Pobiera to ramkę danych zakresów dat jako dane wejściowe i wysyła ramkę danych z brakującymi zakresami. Jestem dość pewien, że to może być grałem więcej, ale wpadłem na problemy z c, cbindi innych odpędzania klasy Date.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.