Tarih Aralıklarında Boşluk Bulma


15

Tarih aralıklarının bir listesi rgirdi, çıktı veya dönüş olarak bulunmayan aralıklar olarak verilir r.

Bu örnek uğruna girdi YYYY-MM-DDformatta olacaktır .

Diyelim ki üç tarih aralığınız var:

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

2019-04-05Ve arasında bir boşluk olduğunu görebilirsiniz 2019-06-01.

Çıktı şu boşluk olacaktır: [2019-04-06, 2019-05-31]

kurallar

  • Giriş ve çıkış, tutarlı olduğu sürece makul herhangi bir tarih veya toplama biçiminde olabilir.
  • Girişin sipariş edilmediğini varsayın.
  • Tarih aralığınızın olması gerekmez [latest, earliest], ancak kural 2'ye uyması gerekir.
  • Girdide çakışan tarih olmadığını varsayalım

Test Durumları:

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

Çıktı: [[2019-04-06, 2019-05-31]]


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

Çıktı: [[2018-04-06, 2018-12-31], [2019-02-02, 2019-05-31]]


Giriş: [[2019-01-01, 2019-02-01],[2019-02-02, 2019-03-02],[2019-03-03, 2019-07-01]]

Çıktı: []


Giriş: [[2019-01-01, 2019-02-01], [2019-11-02, 2019-11-20]]

Çıktı: [[2019-02-02, 2019-11-01]]


Giriş: [[2019-01-01, 2019-02-01],[2019-02-03, 2019-04-05]]

Çıktı: [[2019-02-02, 2019-02-02]]veya[[2019-02-02]]


5
Mevcut örnek YYYY-MM-DDbirçok kişiye yabancı olduğundan ve ayın küçük günleri kullanıldığından ayrıştırılmayı daha da zorlaştırdığından, tüm örnek tarihleri ​​ISO biçiminde yeniden çalışmanızı öneririm.
Adám

@ Adám İyi fikir, güncellendi.
Oliver

.NET OLE Otomasyon Tarihleri ​​olarak girdi alabilir miyiz?
Adám

@ Adám Evet. Herhangi bir makul tarih biçimi kabul edilebilir.
Oliver

1
Tarihler sipariş edilecek mi? Ayrıca, bir çift tarih içinde, bir sonraki tarih olacak mı?
Cehaletin Somutlaştırılması

Yanıtlar:


4

APL (Genişletilmiş Dyalog) , 28 25 24 bayt

Anonim zımni önek fonksiyonu. Argüman ve sonuç, her dönem bir aralığı temsil eden bir çağdan beri gün sayılarının 2 sütunlu matrisleridir.

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

Çevrimiçi deneyin! InIDN'lerin 2 sütun matrisine 3-eleman listeleri (ISO amacıyla hurma) çiftlerinin bir listesini ön-işlemci fonksiyonu dönüştürür Günü Numaraları (1899-12-31 itibaren gün). Out3-eleman listelerinin matrisine IDN'lerin bir matristen sonrası işlemci fonksiyonu dönüştürür.

 artan sıraları sırala

1⌽
⍢, ravelled (düzleştirilmiş) iken  tarihleri ​​bir adım sola döngüsel olarak döndürün - daha sonra orijinal şekline yeniden şekil verin

1 ¯1+ bir ve bir negatif eklemek
⍤1 her satır için bu listesini kullanarak
 sonucunun
{... } aşağıdaki lambda:
 bağımsız değişken
-⍨/ çıkarma sağ tarihi, sıra sıra gelen tarih el sol
1< farklılıkların bir (yani aralıklar bitişik değildir) aşan maske
⍵⌿⍨ filtresi o maskenin satırları


3

C # (Visual C # Etkileşimli Derleyici) , 108 bayt

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

Biçimde yazdırarak çıktılar DD/MM/YYYY 12:00:00 AMDD/MM/YYYY 12:00:00 AM. Meta konsensüs başına iyi olan bir IndexOutOfRange istisnasına neden olur.

Çevrimiçi deneyin!

Unix döneminden bu yana günler halinde girdi alırsak, bunu ...

83 bayt

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

Çevrimiçi deneyin!

Biz bu, /u:System.Arraybayrak ile daha da aşağı golf olabilir ...

78 bayt

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

Çevrimiçi deneyin!


2

Perl 5, 130 bayt

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

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, 208197190177 bayt

iri parça tıknaz bir duvara oturdu ... ama yeni yaklaşımın golf potansiyeli vardı.

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

işlevi ISO formatında [start, end] aralık dizisi alır, boşluk aralıkları yazdırır. Çevrimiçi deneyin .


Yıkmak

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

Jöle , 13 bayt

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

Jelly'in (şu anda) yerleşik tarihleri ​​yoktur, bu nedenle çağdan beri geçen günleri kullanır.
Aralıkların girdi listesi (tamsayı çiftleri) karışık sırada ve karışık yönlerde olabilir.
Sonuç, artan sırada artan aralıkların bir listesidir.

Çevrimiçi deneyin! (boş bir listeyi şu şekilde göstermek için altbilgi biçimleri[])

Nasıl?

Not: Bu, kurallarda belirtildiği gibi "girdide çakışan tarihlerin bulunmaması" güvencesine dayanır.

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?

İlginçtir, Jelly'in tarih desteği olmadığını bilmiyordum. Bu olağan bir yaklaşım mı? Dönemden bu yana günler mi kullanıyorsunuz?
dana

Dönemden beri günler, sanırım, bazı sistemler tarafından kullanılıyor (Excel belki). Dönemden bu yana geçen saniye daha yaygındır (örn. Unix). Sadece oldukça gevşek olsa da, gereksinimleri karşılayan bir şeyle gittim.
Jonathan Allan

Boo, tarihleri ​​elle hesaplayabilirsin . ; P Dönemden beri, tarihleri ​​desteklemeyen diller için gerçekten daha sık kullanılır. Yine de bu meydan okumayı çok daha kolaylaştırıyor gibi hissediyorum.
Kevin Cruijssen

@KevinCruijssen heh, kabul etti.
Jonathan Allan

1

C # (Visual C # Etkileşimli Derleyici) , 103 bayt

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

Çevrimiçi deneyin!

Giriş, başlangıç ​​/ bitiş tarihi gruplarının bir listesidir. Her eksik aralığı STDOUT'a çıktılar.

// 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 - Embriyonun Cehaleti gibi bir baskı yaparsanız gerçekten küçültebilirsiniz - Çevrimiçi deneyin!
dana

Güzel. Ayrıca wtf son iki için giriş yöntemi
sadece ASCII-sadece

Aslında ... bu gerçekten yanlış görünüyor
sadece ASCII

1
Evet, şimdi iyi görünüyor
sadece ASCII

1

R , 88 bayt

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

Çevrimiçi deneyin!

Bu, tarih aralıklarının veri çerçevesini girdi olarak alır ve eksik aralıkları olan bir veri çerçevesini çıkarır. Oldukça emin bu daha golfed olabilir, ama ben ile sorunlarla karşılaştıysanız c, cbindtarih sınıfını sıyırma ve diğerleri.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.