在联合间隔符号中找到2个集合的交点


10

在联合间隔符号中找到2个集合的交点

给定两组描述为间隔的并集的实数,请输出这两组集合的相交的描述作为相同类型的间隔的并集。

输入集将始终包含间隔的并集,以便每个间隔以不同的整数开始和结束(即,没有间隔的度量为零)。但是,同一集合中的不同间隔可能以相同整数或重叠开始或结束。

输出集还必须是以整数开头和结尾的间隔的并集,但是即使是单个整数,输出中的间隔也不能与其他任何间隔重叠

输入可以采用任何适合您选择的语言的形式,只要它由两个成对的整数对组成。

例如,您可以将集合表示方程为:

[-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第三个示例应回答此问题。(不,自己
整理

@nimi你是对的。固定
quintopia,2015年

Answers:


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

一定喜欢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.5,2,3,3.5,4](缺少2.5)而第二个变成[1,1.5,2,2.5,3,3.5,4]


输出应与输入相同。...所以只需说您的输入还需要在每个整数之后的.0;)
quintopia

@quintopia:是的,谢谢。
nimi 2015年

2

Ruby,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 2015年

@mimi它给[[1, 4]]slice_when我认为该方法是在Ruby 2.2周围添加的。
daniero 2015年

...但应为[[1,2 ,, [3,4]]
nimi

这些集合是实数,只有区间边界是整数,所以2.2不在输入中s = [[[1,2],[3,4]], [[1,2],[3,4]]],而在输出中[[1, 4]]
nimi 2015年

嗯,你是对的。这可能已经澄清的/ emphized位的数学挑战,如自己..
达尼罗
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.