간격의 연합


15

구간 목록이 주어지면 구간의 합집합을 수행하고 중복을 줄입니다. 즉, 겹치는 부분이 줄어 듭니다. ( [a, b] U [c, d] = [a, d]if b > c) 모든 간격에서 모든 a <b를 가정합니다 [a, b]. 입력 간격 목록-> 출력 간격 목록의 함수로 구현하십시오. 가장 짧은 코드가 승리합니다. 기존 라이브러리를 사용할 수 없습니다.

설명 :

  • 열린 간격과 닫힌 간격은 구별되지 않습니다.
  • 정수가 아닌 실수의 간격. ( [2, 3], [4, 5] -> [2, 3], [4, 5])
  • 출력 간격을 정렬 할 필요가 없습니다
  • 입력이 중요하지 않은 경우의 순서
  • 잘못된 입력은 [a, b]어디에서나 b >= a입력 간격 순서 및 입력 간격 수와 관련이 없습니다.
  • 정의되지 않은 동작에 오류 메시지를 표시하지 않아도됩니다.

예 (번호 줄 포함)

 [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
예제에서와 같이 간격이 항상 정렬됩니까?
피터 올슨

1
[2, 3], [4, 5]가 겹치지 않거나 [2, 4], [4, 5]도 어떻습니까? 둘 다 2345를 산출합니다.
mellamokb

2
간격은 정수 세트에만 있습니까?
Lowjacker

2
1) [4,5], [1,2] 법적 입력이 있습니까? 2) [2,3], [4,5]의 출력이 [2,5] 또는 [2,3], [4,5] 여야합니까? 3) [2,3], [3,4]의 출력이 [2,4] 또는 [2,3], [3,4] 여야합니까?
MtnViewMark

1
설명을 해주셔서 감사합니다. "정렬 할 필요가 없습니다"는 무엇을 의미합니까? 출력을 정렬 할 필요가 없습니까? 아니면 입력이 이미 정렬되어 있습니까?
MtnViewMark

답변:


2

골프 스크립트, 32

[{1$1$*-2%~2->{*$[(\)\;]}{}if}*]
  • 블록을 선호하면 2자를, 명명 된 블록을 선호하면 4를 추가하십시오.
  • 입력과 출력은 쌍의 배열입니다. 예 : [[2 4] [3 5]]
  • 입력이 첫 번째 요소에 의해 정렬된다고 가정합니다.
  • "인접한"범위를 압축합니다 ([2 4] [5 6]-> [2 6])
  • 첫 GolfScript 노력. 조언 및 썩은 과일에 감사드립니다.

전체 테스트 프로그램 :

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

예제 호출 :

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

4

하스켈 (103)

하스켈에게는 너무 장황하다고 생각합니다. 정렬 기능에 대한 Hoa Long Tam에게 감사합니다.

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)?[]

Haskell에서 간격은 a에서 b로 표시됩니다 [a..b]. 내 표기법은 수학 표기법과 매우 유사합니다. 다음과 같이 사용하십시오.

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

3

좋아, 여기에 250 자의 균열이 있습니다.

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

이 함수는 int 배열을 가져 와서 그 자리에서 작동합니다. 배열은 0으로 종료되며 간격은 임의의 순서로 제공 될 수 있습니다.

샘플 출력 :

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) 

샘플 프로그램 :

#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 them로 이어져야 (1,11) (13,18)하지 않습니까?
사용자가 알 수 없음

@user unknown : 같은 것을 생각했을 것입니다.하지만 명령어가 겹치는 경우에만 결합한다고 말합니다. 따라서 (1, 4) (5, 6)은 규칙에 따라 결합되지 않습니다 ([a, b] U [c, d] = [a, d] if b > c). 그리고 그 문제에 대해서는 (1, 5) (5, 6)조차도 결합되지 않을 것입니다.
mellamokb

"간격 목록을 제공하고, 합집합을 수행하고, 겹침을 and줄이십시오 " 겹침을 줄이십시오 if they overlap. 확인-다음 that means ...방향을 다시 반대 방향으로 가리 킵니다.
사용자가 알 수 없음

@user unknown : 동의합니다. 그것이 내가 질문에 대해 그것에 대해 언급 한 이유입니다. 잘만되면 OP가 응답합니다 :)
mellamokb

2

파이썬, 100 자

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

생성

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

간격의 모든 끝점을 가져 와서 다른 간격 안에있는 것을 제거하고 고유 화 및 정렬 한 후 쌍을 이룹니다.



2

하스켈, 55 자

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

입력이 정렬되지 않은 경우 88 자 :

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

시운전 :

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

"기존 라이브러리를 사용할 수 없습니다"는 가져 오기 List및 호출을 금지한다고 가정합니다 sort. 이것이 합법적이라면 분류되지 않은 버전보다 71 자만 가능합니다.


List패키지에서 가져 오는 Haskell98것만으로도 충분합니다.
FUZxxl

2

스칼라, 272 자

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

용법:

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

배열을 작성하고 간격 시작마다 1을, 간격 끝마다 -1을 삽입합니다. 그런 다음 카운터를 통해 값을 카운터에 추가하여 카운터가 0에서 1까지 단계를 시작할 때마다 시작하고 1에서 0까지 단계를 끝내면 끝을 출력합니다. 불필요하게 복잡 할 수 있습니다.

산출:

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

1

(146) (92) (90)

정규식 엔진을 사용하여 창의적으로 90 자 이하로 골프

하위 u {map $ h [$ _] = 1, @ $ _ [0] .. @ $ _ [1] for @_; $ w. = $ _ + 0for @ h; push @ r, $-[0 ], $ + [0] -1while $ w = ~ / 1 + / g; @r}

사용 예 :

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

이 코드를 조금 설명하겠습니다.

이 서브 루틴은 arrayref의 배열을받습니다. 각 배열은 간격의 시작과 끝의 두 요소를 포함하는 배열을 가리 킵니다. ([2, 4], [3, 6], [8, 9])

모든 aref에 대해 first에서 last까지 요소의 배열을 생성합니다 ($_->[0] .. $_->[1]). 그런 다음 map을 사용하여 @h에서 이러한 색인의 요소를 1로 설정합니다.

(@_) {
    지도 {$ h [$ _] = 1} ($ _-> [0] .. $ _-> [1]);
}

그 후, @h명확성을 위해 아래에 하이픈으로 표시된 (간격에 대한) 또는 undef를 포함합니다.

색인 : 012 34 5678 9
@h :--11 11 1-1 1

다음으로 @h에서 문자열을 작성하고 0을 추가하여 undef를 더 유용한 것으로 바꿉니다 (undef + 0 = 0).

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

$ w에는 011111011지금 포함되어 있습니다.

이제 정규식 엔진을 약간 남용 할 때입니다.

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

성공적으로 일치 한 후 @-및 @ + 배열에는 각 일치의 시작 및 끝 위치가 각각 포함됩니다. 0 번째 요소는 전체 경기에 사용됩니다 (첫 번째는 $ 1, 두 번째는 $ 2 등).

$+[0] 일치하지 않는 첫 번째 문자의 위치가 실제로 포함되므로 하나를 빼야합니다.

@r(2, 6, 8, 9)지금 포함 합니다.

@r

하위 반환 @r합니다.


실제 [2,3],[4,5]수율 에는 적용되지 않습니다2 5
Xcali

1

스칼라 305 279 문자

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

기도:

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 바이트

⟦₂ᵐcod~c~⟦₂ᵐ

온라인으로 사용해보십시오!

입력 변수를 통해 목록을 목록으로 출력하고 출력 변수를 통해 목록을 출력하는 유쾌하게 선언적인 솔루션입니다.

        ~⟦₂ᵐ    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

클로저, 138 바이트

#(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)))

입력이 더 융통성있는 경우, 즉 간격의 시작점 목록과 간격의 끝점 목록 인 경우 119 바이트로 단축됩니다 .

#(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)))

더 좋은 방법이 있어야합니다.



당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.