การค้นหาช่องว่างในช่วงวันที่


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-052019-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ความคิดที่ดีได้รับการอัปเดต
โอลิเวอร์

เราจะรับอินพุตเป็น. NET OLE Automation Dates ได้หรือไม่
อดัม

@ Adámใช่ รูปแบบวันที่ที่เหมาะสมเป็นที่ยอมรับ
โอลิเวอร์

1
จะสั่งซื้อวันที่หรือไม่ นอกจากนี้ภายในคู่ของวันหนึ่งภายหลังจะมีอายุ
ศูนย์รวมแห่งอวิชชา

คำตอบ:


4

APL (Dyalog Extended) , 28 25 24 ไบต์

ฟังก์ชันนำหน้าเงียบโดยไม่ระบุชื่อ อาร์กิวเมนต์และผลลัพธ์คือเมทริกซ์ 2 คอลัมน์ของตัวเลขวันตั้งแต่ยุคแต่ละแถวแสดงช่วง

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

ลองออนไลน์! Inฟังก์ชั่นก่อนการประมวลผลแปลงจากรายการของคู่ของรายการ 3 องค์ประกอบ (วันที่ในการสั่งซื้อ ISO) ไปยังเมทริกซ์ 2 คอลัมน์ IDNs หมายเลขระหว่างวัน (วันนับตั้งแต่ 1899/12/31) Outฟังก์ชั่นโพสต์โปรเซสเซอร์แปลงจากเมทริกซ์ของ IDNs ให้เมทริกซ์ของรายการ 3 องค์ประกอบ

 เรียงแถวจากน้อยไปมาก

1⌽ หมุนวันที่ไปทางซ้ายหนึ่งขั้นตอน
⍢, ในขณะที่ ravelled (แบน) - หลังจากนั้นปรับรูปร่างกลับเป็นรูปร่างเดิม

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 ซึ่งเป็นค่าปรับต่อฉันทามติเมตา

ลองออนไลน์!

ถ้าเราใส่ข้อมูลในรูปแบบของวันตั้งแต่ยุคยูนิกซ์เราสามารถลงไปที่ ...

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

Perl 6 , 46 ไบต์

{@_.sort[1..*-2].map:{$^a+1,$^b-1 if $b>$a+1}}

ลองออนไลน์!

ใช้รายการDateคู่


มีความคิดว่าทำไมสนามกอล์ฟที่เป็นไปได้นี้ทำให้วันที่ออก
Jo King

@JoKing ผมสังเกตเห็นว่ามากเกินไปและยื่นข้อผิดพลาด
nwellnhof

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?

น่าสนใจฉันไม่รู้ว่าเจลลี่ไม่ได้รับการสนับสนุน นี่เป็นวิธีปกติหรือไม่ ใช้วันตั้งแต่กาลหรือไม่
dana

วันนับตั้งแต่ยุคผมเชื่อว่าใช้โดยบางระบบ (อาจจะ Excel) วินาทีนับตั้งแต่ยุคเป็นเรื่องปกติมากขึ้น (เช่น Unix) ฉันเพิ่งไปกับสิ่งที่ดูเหมือนจะครอบคลุมข้อกำหนดแม้ว่าจะค่อนข้างหย่อนยาน
Jonathan Allan

Boo, คุณสามารถคำนวณวันด้วยตนเอง ; P Days เนื่องจากมีการใช้งานยุคสมัยบ่อยกว่าสำหรับภาษาที่ไม่สนับสนุนวันที่ ฉันรู้สึกว่ามันทำให้ความท้าทายนี้ง่ายขึ้นมาก
Kevin Cruijssen

@KevinCruijssen heh เห็นด้วย
Jonathan Allan

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

ลองออนไลน์!

อินพุตคือรายการของ tuples วันที่เริ่มต้น / สิ้นสุด เอาต์พุตแต่ละช่วงที่หายไปถึง 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

ดี นอกจากนี้ยังมีวิธีการป้อนข้อมูลของพวกเขาสำหรับสองหลัง
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,]

ลองออนไลน์!

การทำเช่นนี้จะใช้กรอบข้อมูลของช่วงวันที่เป็นอินพุตและเอาต์พุตเฟรมข้อมูลที่มีช่วงที่ขาดหายไป ผมค่อนข้างแน่ใจว่านี้อาจจะแข็งแรงเล่นกอล์ฟมากขึ้น แต่ฉันวิ่งเข้าไปในปัญหาเกี่ยวกับc, cbindและอื่น ๆ ปอกระดับวัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.