Liên minh các khoảng


15

Đưa ra một danh sách các khoảng, thực hiện kết hợp chúng và giảm chồng chéo. Điều đó có nghĩa là, các phần chồng chéo được giảm. ([a, b] U [c, d] = [a, d] nếu b > c) Giả sử tất cả a <b trong tất cả các khoảng thời gian [a, b]. Thực hiện như một chức năng của một danh sách các khoảng đầu vào -> danh sách các khoảng đầu ra. Mã ngắn nhất sẽ thắng. Bạn không thể sử dụng bất kỳ thư viện hiện có.

Làm rõ:

  • Khoảng cách mở và đóng không được phân biệt.
  • Khoảng cho số thực, không phải số nguyên. ([2, 3], [4, 5] -> [2, 3], [4, 5] )
  • Không cần sắp xếp các khoảng đầu ra
  • Thứ tự nếu đầu vào không quan trọng
  • Đầu vào bất hợp pháp chỉ là [a, b]nơib >= a , nó không liên quan gì đến thứ tự các khoảng đầu vào và số lượng khoảng đầu vào.
  • Bạn không cần hiển thị thông báo lỗi về các hành vi không xác định

Ví dụ (có dòng số)

 [2, 4], [7, 9] --> [2, 4], [7, 9]
   234
        789
-> 234  789

 [1, 5], [2, 10] --> [1, 10] (overlapping [2, 5] reduced)

   12345
    234567890
-> 1234567890
 [2, 4], [3, 6], [8, 9] -> [2, 6], [8, 9]
   234
    3456
         89
-> 23456 89

 [4, 2], [2, 2] -> (undefined behavior: against the assumption)

3
Các khoảng luôn luôn được sắp xếp như trong ví dụ của bạn?
Peter Olson

1
Tại sao không [2, 3], [4, 5] trùng nhau hoặc [2, 4], [4, 5]? Cả hai đều mang lại 2345.
mellamokb

2
Là các khoảng chỉ trên tập hợp số nguyên?
Lowjacker

2
Chúng tôi cần làm rõ một số: 1) Là [4,5], [1,2] đầu vào hợp pháp? 2) Đầu ra của [2,3], [4,5] là [2,5] hay [2,3], [4,5]? 3) Đầu ra của [2,3], [3,4] là [2,4] hay [2,3], [3,4]?
MtnViewMark

1
Cảm ơn đã làm rõ, nhưng "Không cần sắp xếp" nghĩa là gì? Rằng đầu ra không cần được sắp xếp? Hoặc là đầu vào đã được sắp xếp?
MtnViewMark

Câu trả lời:


2

GolfScript, 32

[{1$1$*-2%~2->{*$[(\)\;]}{}if}*]
  • Thêm 2 ký tự nếu bạn thích một khối, 4 nếu bạn thích một khối được đặt tên.
  • Đầu vào và đầu ra là mảng các cặp, vd [[2 4] [3 5]]
  • Giả sử rằng đầu vào được sắp xếp theo phần tử đầu tiên.
  • Thu nhỏ phạm vi "liền kề" ([2 4] [5 6] -> [2 6])
  • Nỗ lực đầu tiên của GolfScript. Tư vấn & thối quả đánh giá cao.

Chương trình kiểm tra đầy đủ:

[~](;2/[{1$1$*-2%~2->{*$[(\)\;]}{}if}*]`

Ví dụ gọi:

ruby golfscript.rb intervals.gs <<EOF
3
2 4
3 6
8 9
EOF
# Expected output: [[2 6] [8 9]]

4

Haskell (103)

Tôi nghĩ, đó là cách quá dài dòng cho Haskell. Cảm ơn Hoa Long Tâm cho chức năng phân loại của mình.

m%(x:y)|x>m=m:x:y|2>1=x:m%y;m%_=[m]
(x:y)?l|x`elem`l=y?l|0<1=x:y?(x:l);a?_=a
a∪b=foldr(%)[](a++b)?[]

Trong Haskell, một intervall từ ađến bđược ký hiệu là [a..b]. Ký hiệu của tôi rất giống với ký hiệu toán học. Sử dụng nó như thế này:

[a..b] ∪ [c..d] ∪ ... ∪ [y..z]

3

Ok, đây là 250 ký tự của tôi crack nó.

void n(int a[]){if(!a[2])return;if(a[2]<=a[1]){if(a[1]<a[3])a[1]=a[3];
int *b=a+2;while(*b=*(b+2))++b;n(a);}n(a+2);}
void m(int a[]){if(!a[2])return;if(a[0]>a[2]){int s=a[0],t=a[1];
a[0]=a[2];a[2]=s;a[1]=a[3];a[3]=t;m(a+2);m(a);n(a);}m(a+2);n(a+2);}

Hàm lấy một mảng int và hoạt động trên nó tại chỗ. Mảng được kết thúc bằng 0 và các khoảng có thể được đưa ra theo bất kỳ thứ tự nào.

Đầu ra mẫu:

input list: (7,9) (5,6) (1,4) (15,18) (13,16) (2,3) (8,11) 
output list: (1,4) (5,6) (7,11) (13,18) 

Chương trình mẫu:

#include <stdio.h>

void n(int a[]){if(!a[2])return;if(a[2]<=a[1]){if(a[1]<a[3])a[1]=a[3];
int *b=a+2;while(*b=*(b+2))++b;n(a);}n(a+2);}
void m(int a[]){if(!a[2])return;if(a[0]>a[2]){int s=a[0],t=a[1];
a[0]=a[2];a[2]=s;a[1]=a[3];a[3]=t;m(a+2);m(a);n(a);}m(a+2);n(a+2);}


/*
void n(int a[])
{
    if(!a[2])return;
    if(a[2]<=a[1]) {
        if(a[1]<a[3])
            a[1]=a[3];
        int *b=a+2;
        while(*b=*(b+2))++b;
        n(a);
    }
    n(a+2);
}

void m(int a[])
{
    if(!a[2])return;
    if(a[0]>a[2]) {
        int s=a[0],t=a[1];
        a[0]=a[2];a[2]=s;
        a[1]=a[3];a[3]=t;
        m(a+2);m(a);n(a);
    }
    m(a+2);n(a+2);
}
*/

void p(int a[]) 
{
    if(!*a) {
        printf("\n");
        return;
    }
    printf("(%d,%d) ",a[0],a[1]);
    p(a+2);
}

int main (int argc, const char * argv[]) 
{
    // Code golf entry
    // Interval Merging

    int a[] = {7,9,5,6,1,4,15,18,13,16,2,3,8,11,0};
    printf( "input list: " ); p(a);
    m(a);
    printf( "output list: " ); p(a);

    return 0;
}

perform the union of themCó nên dẫn đến (1,11) (13,18), không nên?
người dùng không xác định

@user không rõ: Tôi sẽ nghĩ điều tương tự, nhưng tôi đoán các hướng dẫn nói chỉ kết hợp nếu chúng trùng nhau. Vì vậy (1, 4) (5, 6) không được kết hợp theo quy tắc ([a, b] U [c, d] = [a, d] if b > c). Và đối với vấn đề đó, thậm chí (1, 5) (5, 6) sẽ không được kết hợp.
mellamokb

"Đưa ra một danh sách các khoảng thời gian, thực hiện kết hợp chúng và giảm chồng chéo" andgiảm chồng chéo - không if they overlap. OK - các that means ...điểm sau một lần nữa theo hướng ngược lại.
người dùng không xác định

@user không rõ: Tôi đồng ý. Đó là lý do tại sao tôi đã nhận xét về nó về câu hỏi. Hy vọng OP sẽ phản hồi :)
mellamokb

2

Python, 100 ký tự

def f(L):R=sorted(set(p for p in sum(L,[])if 1-any(x<p<y for x,y in L)));return zip(R[::2],R[1::2])
print f([[2, 4], [7, 9]])
print f([[1, 5], [2, 10]])
print f([[3, 6], [2, 4], [8, 9]])
print f([[1, 5], [3, 5], [4, 5]])

tạo ra

[(2, 4), (7, 9)]
[(1, 10)]
[(2, 6), (8, 9)]
[(1, 5)]

Lấy tất cả các điểm cuối của các khoảng, loại bỏ bất kỳ điểm nào nằm trong khoảng khác, xác định và sắp xếp chúng và ghép chúng lại.



2

Haskell, 55 ký tự

v(q@(a,b):p@(c,d):r)|c>b=q:v(p:r)|1<3=v((a,d):r);v x=x

Nếu đầu vào chưa được sắp xếp, thì 88 ký tự:

p@(a,b)§(q@(c,d):r)|b<c=p:q§r|a>d=q:p§r|1<3=(min a c,max b d)§r;p§_=[p]
u i=foldr(§)[]i

Chạy thử:

ghci> testAll v
pass: [(2,4),(7,9)] --> [(2,4),(7,9)]
pass: [(1,5),(2,10)] --> [(1,10)]
pass: [(2,4),(3,6),(8,9)] --> [(2,6),(8,9)]
ghci> testAll u
pass: [(2,4),(7,9)] --> [(2,4),(7,9)]
pass: [(1,5),(2,10)] --> [(1,10)]
pass: [(2,4),(3,6),(8,9)] --> [(2,6),(8,9)]

Tôi giả định rằng "không thể sử dụng bất kỳ thư viện hiện có" nào ngăn cản việc nhập Listvà gọi sort. Nếu đó là hợp pháp, thì phiên bản chưa được sắp xếp sẽ chỉ có 71 ký tự.


nhập Listtừ gói Haskell98sẽ đủ IMHO.
FUZxxl

2

Scala, 272 ký tự

type p=List[(Int,Int)];def f(l:p):p={var(a,s,c,o)=(new Array[Int]((l map(x=>x._2)max)+1),0,0,List[Int]());l map(x=>(a(x._1)+=1,a(x._2)-=1));while(c<a.size){s+=a(c);if(a(c)==1&&s==1)o=o:+c;if(a(c)== -1&&s==0)o=o:+c;c+=1};return(o.grouped(2).map(x=>(x.head,x.last)).toList)}

Sử dụng:

object Intervals2 extends Application
{
    type p=List[(Int,Int)];def f(l:p):p={var(a,s,c,o)=(new Array[Int]((l map(x=>x._2)max)+1),0,0,List[Int]());l map(x=>(a(x._1)+=1,a(x._2)-=1));while(c<a.size){s+=a(c);if(a(c)==1&&s==1)o=o:+c;if(a(c)== -1&&s==0)o=o:+c;c+=1};return(o.grouped(2).map(x=>(x.head,x.last)).toList)}

    print(f(List((1,2),(3,7),(4,10))))
}

Tạo một mảng và chèn 1 cho mỗi khoảng thời gian bắt đầu và -1 cho mỗi kết thúc khoảng thời gian. Sau đó, bước qua mảng thêm các giá trị vào bộ đếm xuất ra một lần khởi động mỗi khi bộ đếm bước từ 0 đến 1 và kết thúc khi bước từ 1 đến 0. Có thể phức tạp không cần thiết.

Đầu ra:

List((1,2), (3,10))

1

Perl (146) (92) (90)

đánh gôn xuống 90 ký tự, sáng tạo bằng cách sử dụng công cụ regex

phụ u {map $ h [$ _] = 1, @ $ _ [0] .. @ $ _ [1] cho @_; $ w. = $ _ + 0for @ h; đẩy @ r, $ - [0 ], $ + [0] -1 trong khi $ w = ~ / 1 + / g; @r}

ví dụ sử dụng:

my @ out1 = u ([1, 5], [2, 10]); # (1,10)
my @ out2 = u ([2, 4], [3, 6], [8, 9]); # (2, 6, 8, 9)

Hãy giải thích mã này một chút.

chương trình con này nhận được một mảng các mảng, mỗi tệp chỉ vào một mảng chứa hai phần tử, bắt đầu và kết thúc của khoảng: ([2, 4], [3, 6], [8, 9])

với mỗi aref, chúng ta tạo ra một mảng các phần tử từ đầu đến cuối ($_->[0] .. $_->[1]). sau đó chúng tôi sử dụng bản đồ để đặt các phần tử của các chỉ mục đó trong @h thành 1.

cho (@_) {
    bản đồ {$ h [$ _] = 1} ($ _-> [0] .. $ _-> [1]);
}

sau này, @hsẽ chứa một trong hai (cho các khoảng) hoặc undefs, được mô tả dưới đây là dấu gạch nối cho rõ ràng.

chỉ số: 0 1 2 3 4 5 6 7 8 9
@h: - - 1 1 1 1 1 - 1 1

tiếp theo, chúng tôi xây dựng một chuỗi từ @h, thêm 0 để thay thế undefs bằng một cái gì đó hữu ích hơn (undef + 0 = 0).

$w .= $_+0 for @h;

$ w chứa 011111011ngay bây giờ.

đã đến lúc lạm dụng công cụ regex một chút.

push @r, ($-[0], $+[0]-1) while $w=~/1+/g;

sau các trận đấu thành công, mảng @ - và @ + chứa vị trí bắt đầu và kết thúc của mỗi trận đấu; Phần tử thứ 0 được sử dụng cho toàn bộ trận đấu, đầu tiên là $ 1, thứ hai là $ 2, v.v.

$+[0] thực sự chứa vị trí của char không khớp đầu tiên, vì vậy chúng ta phải trừ đi một.

@rchứa (2, 6, 8, 9)ngay bây giờ.

@r

để làm cho phụ trở lại @r.


Không hoạt động cho [2,3],[4,5]năng suất số thực2 5
Xcali

1

Scala 305 279 ký tự không có lời mời:

type I=(Int,Int)
def l(p:I,q:I)=if(p._1<q._1)true else if(p._1>q._1)false else p._2<q._2
def r(l:List[I]):List[I]=l match{case x::y::z=>{if(y._1<=x._2&&y._2>x._2)(x._1,y._2)::r(z)else
if(y._1<=x._2&&y._2<=x._2)x::r(z)else  
x::r(y::z)}case _=>l}
def c(v:List[I])=r(v.sortWith(l))

cầu nguyện:

val i=List((7,9),(5,6),(1,4),(15,18),(13,16),(2,3),(8,11))
c(i)
res0: List[(Int, Int)] = List((1,4), (5,6), (7,11), (13,18))

1

Brachylog , 12 byte

⟦₂ᵐcod~c~⟦₂ᵐ

Hãy thử trực tuyến!

Một giải pháp khai báo thú vị, lấy đầu vào làm danh sách các danh sách thông qua biến đầu vào và xuất ra danh sách các danh sách thông qua biến đầu ra.

        ~⟦₂ᵐ    The output is a list of intervals, where each interval is a range in
      ~c        the smallest partition of
  ᵐ             each element of the input
⟦₂              converted to an inclusive range,
   c            concatenated,
    o           sorted,
     d          and deduplicated
        ~⟦₂ᵐ    for which each element of the partition is a range.

1

Clojure, 138 byte

#(let[S(set(apply mapcat range(apply map list %)))Q(sort S)](map list(for[s Q :when(not(S(dec s)))]s)(for[s(map inc Q):when(not(S s))]s)))

Điều này rút ngắn xuống còn 119 byte nếu đầu vào linh hoạt hơn, cụ thể là danh sách các điểm bắt đầu của các khoảng và một danh sách các điểm kết thúc của các khoảng:

#(let[S(set(mapcat range % %2))Q(sort S)](map list(for[s Q :when(not(S(dec s)))]s)(for[s(map inc Q):when(not(S s))]s)))

Có phải là một cách tốt hơn.


1

Japt , 18 byte

Điều này cảm thấy quá dài. I / O như được sắp xếp, mảng 2D của các khoảng.

c_ròÃòÈaY Éîg[TJ]

Thử nó


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.