結合区間表記で2つのセットの共通部分を見つける


10

結合区間表記で2つのセットの共通部分を見つける

区間の和集合として記述された2つの実数セットが与えられた場合、これら2つのセットの共通部分の説明を、同じタイプの区間の和集合として出力します。

入力セットは常に、各インターバルが異なる整数で開始および終了するように、インターバルの和集合で構成されます(つまり、どのインターバルにもメジャーゼロはありません)。ただし、同じセット内の異なる間隔は、同じ整数で開始または終了したり、重複したりする場合があります。

出力セットは、整数で開始および終了する間隔の和集合でもある必要がありますが、出力の間隔は、単一の整数でも他の間隔と重複することはできません

入力は、整数のペアの2つのリストで構成されている限り、選択した言語に適した任意の形式を取ることができます。

たとえば、次のようにセット方程式を表すことができます。

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

またはとして:

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

またはとして:

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

出力表現は、入力表現と同じでなければなりません(2つではなく1つの間隔のリストであることを除いて)。

例/テストケース:

入力:

[[[-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 2015

2
@ msh210 3番目の例はこの質問に答えるべきです。(いいえ。自分で並べ替えてください。)
quintopia

@nimiそうだね。修正済み
quintopia

回答:


3

Mathematica、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 2015

Mathematicaの自動結合が大好きIntervalです。
mbomb007

3

Haskell、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 

私は「半分」 -値を入れているx.5私は区別する必要があるため、リストに(1,2),(3,4)から(1,4)。なしx.5では両方ともなります[1,2,3,4]x.5、1つ目は[1,1.5,2,3,3.5,4](欠けている2.5)2つ目になり[1,1.5,2,2.5,3,3.5,4]ます。


出力は入力と同じでなければなりません。...だから、各整数の後にも入力に.0が必要だと言ってください;)
quintopia

@quintopia:はい、ありがとうございます。
nimi 2015

2

Ruby、90バイト

2つのセットのそれぞれをフラット配列にマップし、それらの配列のセットの共通部分を取得してから、結果を連続したチャンクにスライスし、各チャンクを最初と最後の要素にマップします。かんたん。

->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
はが

@mimiそれが与える[[1, 4]]。このslice_whenメソッドは、Ruby 2.2のどこかに追加されたと思います。
daniero

...ただし、[[1,2]、[3,4]]である必要があります
nimi 2015

セットは実数を超えており、間隔の境界のみが整数であるため2.2、入力s = [[[1,2],[3,4]], [[1,2],[3,4]]]ではなく出力にあります[[1, 4]]
nimi 2015

うーん、あなたは正しいです。それは私のような数学的に挑戦された人のために少し明確化/強調されたかもしれません..
daniero
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.