Пошук прогалин у діапазонах дат


15

Дано список діапазонів дат rяк введення, виведення або повернення будь-яких діапазонів, у яких не знайдено r.

Для цього прикладу введення буде у YYYY-MM-DDформаті.

Скажімо, у вас є три діапазони дат:

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

Видно, що між 2019-04-05і між ними існує розрив 2019-06-01.

Вихід буде таким розривом: [2019-04-06, 2019-05-31]

Правила

  • Введення та виведення даних можуть бути у будь-якому розумному форматі дати чи збору, якщо це буде послідовно.
  • Припустимо, вхід не впорядкований.
  • Ваш діапазон дат не повинен бути [latest, earliest], але він повинен дотримуватися правила 2.
  • Припустимо, що немає даних, що перетинаються у введенні

Випробування:

Вхід: [[2019-01-01, 2019-02-01],[2019-02-02, 2019-04-05],[2019-06-01, 2019-07-01]]

Вихід: [[2019-04-06, 2019-05-31]]


Вхід: [[2019-01-01, 2019-02-01],[2018-02-02, 2018-04-05],[2019-06-01, 2019-07-01]]

Вихід: [[2018-04-06, 2018-12-31], [2019-02-02, 2019-05-31]]


Вхід: [[2019-01-01, 2019-02-01],[2019-02-02, 2019-03-02],[2019-03-03, 2019-07-01]]

Вихід: []


Вхід: [[2019-01-01, 2019-02-01], [2019-11-02, 2019-11-20]]

Вихід: [[2019-02-02, 2019-11-01]]


Вхід: [[2019-01-01, 2019-02-01],[2019-02-03, 2019-04-05]]

Вихід: [[2019-02-02, 2019-02-02]]або[[2019-02-02]]


5
Я пропоную переробити всі приклади дат у формат ISO, YYYY-MM-DDоскільки поточний формат для багатьох людей чужий і ще більше ускладнює розбір через використання малих днів місяця≤12.
Adám

@ Adám Хороша ідея, оновлено.
Олівер

Чи можемо ми прийняти дані як дати .NET OLE Automation?
Адам

@ Adám Так. Будь-який розумний формат дати прийнятний.
Олівер

1
Чи будуть замовлені дати? Також, протягом пари побачень, чи пізніший буде останнім?
Втілення

Відповіді:


4

APL (Dyalog Extended) , 28 25 24 байт

Функція анонімного мовчазного префікса. Аргумент та результат - це матриці двох стовпців числових днів із епохи, кожен рядок представляє діапазон.

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

Спробуйте в Інтернеті! Функція Inпопереднього процесора перетворюється зі списку пар 3-елементних списків (дати в порядку порядку ISO) у матрицю з двома стовпцями IDN, Міжнародні дні номерів (дні з 1899-12-31). Функція Outпостпроцесора перетворюється з матриці IDN в матрицю 3-елементних списків.

 сортувати рядки за зростанням

1⌽ циклічно обертайте дати на один крок ліворуч,
⍢, коли похитуєтесь (згладжуєтесь) - після цього переставляйте форму до початкової форми

1 ¯1+ додайте одне і негативне,
⍤1 використовуючи цей список для кожного рядка
 результату
{} наступної лямбда:
 аргумент
-⍨/ віднімає ліву дату від правої дати,
1< маску в рядку, коли відмінності перевищують один (тобто, коли діапазони не є суміжними)
⍵⌿⍨ фільтр рядки за цією маскою


3

C # (Visual C # Interactive Compiler) , 108 байт

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

Виводиться друком у форматі DD/MM/YYYY 12:00:00 AMDD/MM/YYYY 12:00:00 AM. Викличе виняток IndexOutOfRange, що добре за мета-консенсусом.

Спробуйте в Інтернеті!

Якщо ми сприймемо вклад у вигляді днів з епохи Unix, ми можемо звести це до ...

83 байти

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

Спробуйте в Інтернеті!

Ми можемо ще більше погорнути це /u:System.Arrayпрапором, бо ...

78 байт

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

Спробуйте в Інтернеті!





2

PHP, 208 197 190 177 байт

ошатний корінець сидів на стіні ... хоча новий підхід мав досить певний потенціал для гольфу.

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

функція приймає масив діапазонів [початок, кінець] у форматі ISO, друкує інтервали проміжків. Спробуйте в Інтернеті .


зламатися

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

Желе , 13 байт

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

У желе (на даний момент) немає вбудованих дат, тому для цього використовуються дні з моменту епохи.
Список вхідних діапазонів (пари цілих чисел) може бути в змішаному порядку та змішаним напрямком.
Результат - список діапазонів висхідних груп у порядку зростання.

Спробуйте в Інтернеті!(формати нижнього колонтитулу, щоб показати порожній список як[] )

Як?

Примітка. Це спирається на впевненість у тому, що "немає даних, що перетинаються у введенні", як зазначено в правилах.

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?

Цікаво, що я не знав, що в Jelly не було підтримки на побачення. Це звичайний підхід? Використовуйте дні з епохи?
Dana

Я вважаю, що дні з епохи використовуються деякими системами (можливо, Excel). Секунди з часів епохи частіші (наприклад, Unix). Я просто пішов із чимось, що, схоже, покриває вимоги, хоч і досить мляво.
Джонатан Аллан

Бу, дати можна було обчислити вручну . ; P Дні з часів епохи справді частіше використовується для мов, які не підтримують дати. Я відчуваю, що це робить цей виклик ЛОТИ легше, хоча.
Кевін Круїссен

@KevinCruijssen хе, погодився.
Джонатан Аллан

1

C # (Visual C # Interactive Compiler) , 103 байти

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

Спробуйте в Інтернеті!

Введення - це список кортезів дати початку / закінчення. Виводить кожен пропущений діапазон в 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);
  }
}


Ха-ха - якщо ти робиш друк на зразок Втілення Невідомості, ти можеш отримати дуже мало - Спробуйте в Інтернеті!
Dana

Приємно. Також wtf їх метод введення для двох останніх
лише для ASCII

Ну насправді ... це виглядає дійсно неправильно
лише ASCII

1
Так, це виглядає нормально
лише ASCII,

1

R , 88 байт

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

Спробуйте в Інтернеті!

Це приймає кадр даних діапазонів дат як вхідний та виводить кадр даних із діапазонами, які відсутні. Я досить впевнений , що це може бути golfed більше, але я зіткнувся з питаннями c, cbindі інших розкривних клас дати.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.