결합 간격 표기법으로 2 세트의 교집합 찾기


10

결합 간격 표기법으로 2 세트의 교집합 찾기

구간의 합집합으로 기술 된 두 세트의 실수가 주어지면,이 두 세트의 교차점에 대한 설명을 동일한 유형의 구간의 합집합으로 출력하십시오.

입력 집합은 각 간격이 서로 다른 정수로 시작하고 끝나도록 간격의 합집합으로 구성됩니다 (즉, 간격이 측정 값이 0이 아님). 그러나 동일한 세트의 다른 간격은 동일한 정수 또는 겹침으로 시작하거나 끝날 수 있습니다.

또한 출력 집합은 정수로 시작하고 끝나는 간격의 합집합이어야하지만 단일 정수에서도 출력의 간격이 다른 간격과 겹치지 않아야 합니다.

입력은 두 개의 정수 쌍 목록으로 구성되어 있으면 선택한 언어에 적합한 형식을 사용할 수 있습니다.

예를 들어 세트 방정식를 다음과 같이 나타낼 수 있습니다 .

[-10,-4]u[1,5]u[19,20]

또는

[[-10,-4],[1,5],[19,20]]

또는

[-10,-4;1,5;19,20]

출력 표시는 입력 표시와 동일해야합니다 (두 개가 아닌 하나의 간격 목록 만 제외).

예 / 테스트 사례 :

입력:

[[[-90,-4],[4,90]],[[-50,50]]]

산출:

[[-50,-4],[4,50]]

다시 말해, 우리는 -90과 -4 사이의 모든 실수와 4와 90 사이의 모든 실수를 포함하는 집합과 -50과 50 사이의 모든 실수를 포함하는 집합을 교차시킵니다. 교차는 모두를 포함하는 집합입니다 -50과 -4 사이의 실수와 4와 50 사이의 모든 실수.보다 시각적 인 설명 :

-90~~~~~-4  4~~~~~90   intersected with
    -50~~~~~~~~50        yields:
    -50~-4  4~~50

입력:

"[-2,0]u[2,4]u[6,8]
[-1,1]u[3,5]u[5,9]"

산출:

"[-1,0]u[3,4]u[6,8]"

입력:

[-9,-8;-8,0;-7,-6;-5,-4]
[-7,-5;-1,0;-8,-1]

산출:

[-8,0]

유효하지 않은 출력 (동일한 세트를 나타내더라도) :

[-8,0;-7,-5;-5,0]

채점 :

이것은 이므로 다음과 같은 보너스로 잠재적으로 수정 된 바이트 단위의 가장 짧은 소스입니다.

보너스:

간격의 경계로 양수 및 음수 무한대도 지원하는 경우 -15 % 이 숫자를 나타내는 토큰을 선택할 수 있습니다. (그렇습니다, 무한대는 초현실주의 숫자입니다 .P)


각 교차 소환의 다양한 조합 세트가 오름차순으로 작성되었다고 가정 할 수 있습니까? 다시 말해서 (그러나 반대로) 다음 입력이 유효합니까? [[[4,90],[-90,-4]],[[-50,50]]]
msh210

2
@ msh210 세 번째 예는이 질문에 답해야합니다. (No. 직접 분류하십시오.)
퀴 토피아

@nimi 당신이 맞아요. 고정
퀴 토피아

답변:


3

수학, 41 바이트-15 % = 34.85

Mathematica에는 인터벌 교차를위한 기능이 내장되어 있습니다.

List@@IntervalIntersection@@Interval@@@#&

예:

In[1]:= List@@IntervalIntersection@@Interval@@@#&[{{{-90, -4}, {4, Infinity}}, {{-50,Infinity}}}]

Out[1]= {{-50, -4}, {4, Infinity}}

2
와우 ... 나는 이것을 읽지 않고 똑같은 해결책을 생각해 냈습니다. +1
LegionMammal978

Mathematica의 자동 연합을 좋아해야합니다 Interval.
mbomb007

3

하스켈, 145 바이트

import Data.List
q(a,b)=[a,a+0.5..b]
p@(a,b)%(h:t)|h==b+0.5=(a,h)%t|1<2=p:(h,h)%t
p%_=[p]
a#b|h:t<-nub$sort$intersect(q=<<a)$q=<<b=(h,h)%t|1<2=[]

사용 예 : [(-2.0,0.0),(2.0,4.0),(5.0,6.0),(6.0,8.0)] # [(-1.0,1.0),(3.0,5.0),(5.0,9.0)]-> [(-1.0,0.0),(3.0,4.0),(5.0,8.0)].

작동 방식 :

                 q=<<a            -- turn each pair in the 1st input list into
                                  -- lists with halves in between (e.g. (1,4) ->
                                  -- [1,1.5,2,2.5,3,3.5,4]) and concatenate them
                                  -- to a single list
                      q=<<b       -- same for the second input list
    nub$sort$intersect            -- sort the intersection of those lists
                                  -- and remove duplicates
h:t<-                             -- call the first element h and the rest t
                       (h,h)%t    -- start rebuilding the intervals
                          |1<2=[] -- if there's no first element h, one of the
                                  -- input lists is empty, so the output is also
                                  -- empty


p@(a,b)%(h:t)                     -- an interval p = (a,b), build from a list (h:t)
             =(a,h)%t             -- becomes (a,h)
      |h==b+1                     --   if h equals b+0.5
                    p:(h,h)%t     -- or is put in the output list, followed by
                                  --       a new interval starting with (h,h)
      |1<2                        --   otherwise
p%_=[p]                           -- base case of the interval rebuilding function 

나는 "반"-values을 가하고있어 x.5내가 구별 할 필요가 있기 때문에, 목록 (1,2),(3,4)에서 (1,4). 그렇지 않으면 x.5둘 다 될 것입니다 [1,2,3,4]. 그러나 x.5첫 번째는 [1,1.5,2,3,3.5,4]부족 2.5합니다 [1,1.5,2,2.5,3,3.5,4].


출력은 입력과 동일해야합니다. ... 그래서 그냥 귀하의 의견은 각 정수 후 0.0을 필요로 말)
quintopia

@ 퀸 토피아 : 예, 감사합니다.
nimi

2

루비, 90 바이트

두 세트 각각을 평평한 배열로 매핑하고 해당 배열의 교차 집합을 얻은 다음 결과를 연속체 청크로 분할하고 각 청크를 첫 번째 요소와 마지막 요소에 매핑합니다. 쉬워요.

->s{a,b=s.map{|y|y.flat_map{|f,l|[*f..l]}.sort}
(a&b).slice_when{|a,b|b-a>1}.map &:minmax}

용법:

f=->s{a,b=s.map{|y|y.flat_map{|f,l|[*f..l]}.sort}
(a&b).slice_when{|a,b|b-a>1}.map &:minmax}

s = [[[-90,-4],[4,90]], [[-50,50]]]
p f[s] # => [[-50, -4], [4, 50]]

s = [[[-2,0],[2,4],[6,8]], [[-1,1],[3,5],[5,9]]]
p f[s] # => [[-1, 0], [3, 4], [6, 8]]

s = [[[-9,-8],[-8,0],[-7,-6],[-5,-4]],[[-7,-5],[-1,0],[-8,-1]]]
p f[s] # => [[-8, 0]]

당신의 프로그램은 무엇을 출력 s = [[[1,2],[3,4]], [[1,2],[3,4]]]합니까? (내 루비 버전에는이 slice_when없으므로 테스트 할 수 없습니다)
nimi

@mimi이 제공합니다 [[1, 4]]. 이 slice_when방법은 Ruby 2.2 주위에 추가되었습니다.
daniero December

...하지만되어야 [1,2], [3,4]
nimi

세트는 실수를 초과하고 간격 경계 만 정수이므로 2.2입력 s = [[[1,2],[3,4]], [[1,2],[3,4]]]이 아니라 출력에 [[1, 4]]있습니다.
nimi

흠, 맞아. clearified 봤는데 수 / 등 자신과 같이 수학적으로 장애인을위한 약간 emphized ..
daniero
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.