设置两个列表的交集


10

您的目标是计算两个整数列表的集合相交。相交定义为在两个输入列表中至少发现一次的唯一无序整数组。

输入项

输入可以是所需的任何格式(功能参数,标准输入输出等),并且由两个整数列表组成。除了可能包含任何非负数的整数(即它们未排序,可能包含重复项,可能具有不同长度,甚至可能为空)之外,您可能不假设有关每个列表的任何内容。假定每个整数都适合您语言的本机带符号整数类型,长度可能超过1个十进制数字,并且已签名。

输入示例:

1 4 3 9 8 8 3 7 0
10 1 4 4 8 -1

输出量

输出是任何类似于列表的整数,代表将两个列表的交集设置为所需的任何格式(返回值,stdio等)。尽管欢迎您提供恰好总是被排序的实现,但是并不需要对输出进行排序。输出必须形成有效的无序集合(例如,它不得包含任何重复值)。

测试用例示例(请注意,输出顺序并不重要):

前两行是输入列表,第三行是输出。(empty)表示空白列表。

(empty)
(empty)
(empty)

1000
(empty)
(empty)

3 1 2 4 3 1 1 1 1 3
3 1 -1 0 8 3 3 1
1 3

1 2 1
3 3 4
(empty)

计分

这是代码高尔夫;以字节为单位的最短答案获胜。

禁止使用标准孔。您可以使用并非为类似集合的操作设计的任何内置功能。

禁止的内置功能:

  • 设置创建/删除重复项
  • 设置差异/交叉点/联合
  • 通用成员资格测试(例如,类似于inPython中的关键字,类似indexOf函数的任何东西)。请注意,尽管Python重用了in关键字来创建此构造,但仍允许使用“列表中的foreach项”构造(假定它们不违反任何其他限制)。
  • 这些禁止的内置程序是“病毒”的,即,如果有更大的内置程序包含这些子功能中的任何一个,则同样会被禁止(例如,按列表中的成员资格进行过滤)。

上面列表中没有的任何内置函数都是允许的(例如排序,整数相等性测试,列表按索引附加/删除,过滤等)。

例如,采用以下两个示例片段(类似于Python的代码):

# prohibited: filters by testing if each value in tmpList is a member of listA
result = tmpList.filter(listA)

# ok: filtering by a lambda which manually iterates over listA and checks for equality
def my_in_func(val, slist):
    for a in slist:
        if(val == a):
            return True
    return False
result = filter(lambda v: my_in_func(val, listA), tmpList)

欢迎您自己实现这些类似集合的功能,它们将计入您的分数。

您的解决方案应在合理的时间内完成(例如,对于拥有两个列表(每个长度为1000)的任何硬件,用不到一分钟的时间)。


5
顺便说一下,混淆和错误沟通在没有Y的X中很常见,这就是为什么在书写挑战时它们是要避免事情之一。
丹尼斯

2
@Dennis是的,我想这个问题确实已经成为其中的一个问题:(当我第一次写它时,我希望它可能是一个有趣的问题,但是一旦我开始制定规则集,我就应该扼杀这个挑战。
helloworld922'3

是否允许执行游程编码的内置函数?
isaacg

那应该没问题。
helloworld922

1
输出中是否可能有重复项?
亚当

Answers:



4

MATL,18字节

YY_iti!=Xa)hStdfQ)

在线尝试!

这分两个步骤进行。首先计算交点,可能有重复项。这是基于将一个数组的所有元素与另一个数组的所有元素进行比较,并将第一个元素保留在第二个元素中。

然后删除重复项。为此,对上一步中的数组进行排序,如果与上一步不同,则保留条目。-inf会预先添加一个值,以便不会丢失第一个(即最低)值。

YY_                 % push -infinity
   it               % take first input. Duplicate
     i!             % take second input. Transpose
        =           % test all combinations of elements of the two inputs for equality
        Xa          % row vector that contains true for elements of first array that 
                    % are present in the second, possibly duplicated
          )         % index into first array to keep only those elements. Now we need
                    % to remove duplicates
           h        % append -infinity
            S       % sort
             tdf    % duplicate. Find entries that differ from the preceding
                Q)  % add 1 and index into array to keep only non-duplicates

4

果冻,13个字节

=S¥Ðf
ṂrṀ{ç³ç

在线尝试!

怎么运行的

ṂrṀ{ç³ç  Main link. Arguments: A (list 1), B (list 2)

Ṃ        Yield m, the minimum of A.
  Ṁ{     Yield M, the maxmimum of A.
 r       Create an inclusive range from m to M.
    f³   Apply the helper link with right argument A.
      f  Apply the helper link with right argument B.


=S¥Ðf    Helper link. Arguments: n (integer in range), L (list, A or B)

=        Test all elements of L for equality with n.
 S       Add the results.
  ¥      Combine the two previous links into a dyadic chain.
   Ðf    Filter by the result of the sums.

@isaacg现在固定。
丹尼斯

3

golflua,68个字符

\f(a,b)k={}~@_,v p(a)~@_,w p(b)?w==v k[w]=w$$$~@_,v p(k)I.w(v," ")$$

被称为

> f({1,2,3,4},{3,4,5})
3 4
> f({3,1,2,4,3,1,1,1,1,3},{3,1,-1,0,8,3,3,1})
3 1

在常规的Lua中,这将是

function foo(a,b)
   local k={}
   for i,v in pairs(a)
      for j,w in pairs(b)
         if v==w then
            k[v] = v
         end
      end
   end
   for i,v in pairs(k)
      print(v," ")
   end
end

因此,基本上,我要遍历两个表的每个元素,并且只存储等效值。通过使用值作为键(k[w]=w),我消除了所有重复项。然后,我们通过遍历索引和值来输出新表pairs


3

JavaScript(ES6),66个字节

(a,b)=>a.filter((e,i)=>b.some(f=>e==f)&a.slice(0,i).every(f=>e-f))

不使用indexOf,因为我不相信这是允许的。


3

Pyth,12 11字节

eMrSsq#RQE8

示范

说明:

eMrSsq#RQE8
               Implicit: Q is one of the lists.
     q#RQE     For every element in the first list, filter the second list on
               equality with that element.
    s          Concatenate. We now have the intersection, with duplicates.
  rS      8    Sort and run length encode, giving counts and elements.
eM             Take just the elements.

排序和保存将节省一个字节。
雅库布

@Jakube我想说rle是一个内置函数,可删除重复项。
isaacg

如果您之前对它进行了排序,则它只会删除重复项,然后再删除rle的计数。它在灰色区域中有点,但是我认为使用字典也是如此。它基本上是一个集合,用于存储每个元素的其他数据。
雅库布

@Jakube OP说很好。谢谢!
isaacg

2

bash + GNU coreutils,184字节

[ -z "$1" ] && exit
p='{if(a[$0]++==0)print $0}'
while read A; do
while read B; do
[ $A = $B ] && echo $A
done < <(grep -oP '\d*'<<<$1|awk "$p")
done < <(grep -oP '\d*'<<<$2|awk "$p")

调用:

./codegolf.sh '12 4 654 12 3 56' '4 4 56 33 3 3 3'

输出:

4
56
3

如果交集为空,则无输出。如果第一组为空,则此脚本不会排序,并进行完整性检查。说明:

[ -z "$1" ] && exit  # Exit if first set is empty
p='{if(a[$0]++==0)print $0}' # The AWK program we will use
while read A; do   # read the list with two
while read B; do   # encapsulated loops
[ $A = $B ] && echo $A   # if they match, then print
done < <(grep -oP '\d*'<<<$1|awk "$p")
done < <(grep -oP '\d*'<<<$2|awk "$p")
# the process substitution greps the numbers and pipes them to awk. Our awk program makes them unique without sorting; it uses associative arrays with index names same as lines (our numbers here).

要知道的好处:您可以更改为grep -o .使用随机字符串而不是数字来执行此操作。


2

Perl 6中,26 37个字节

{%(@^a.grep(any(@^b)):p.invert).keys}

用法

> my &f = {%(@^a.grep(any(@^b)):p.invert).keys}
-> @a, @b { #`(Block|559823336) ... }
> f([3,1,2,4,3,1,1,1,1,3], [3,1,-1,0,8,3,3,1])
(1 3)

厚脸皮的非竞争性答案

> [3,1,2,4,3,1,1,1,1,3]  [3,1,-1,0,8,3,3,1]
set(3, 1)

或者如果您喜欢无聊的f功能

> my &f = &infix:<∩>
sub infix:<∩> (|p is raw) { #`(Sub+{<anon|130874592>}+{Precedence}|102325600) ... }
> f([3,1,2,4,3,1,1,1,1,3], [3,1,-1,0,8,3,3,1])
set(3, 1)

我更新了答案,不使用.unique
热键

1
invert如果采用这些值,则实际上并不需要。24字节
Jo King,

2

视网膜,63字节

最后两行删除重复项。输入是两个用逗号分隔的空格分隔的列表。输出以空格分隔。

+`( -?\d+)\b(.*,.*)\1\b
$1_$2
-?\d+\b|_|,

+`(-?\d+)(.*)\1
$1$2

在线尝试

如果输出中允许重复,则我的程序将为42个字节。


2

Jq 1.5,99个字节

def f(a;b):(a+b|min)as$m|[range($m;a+b|max)|[]]|.[a[]-$m][0]=1|.[b[]-$m][1]=1|.[[[1,1]]]|map(.+$m);

展开式

def f(a;b):
     (a+b|min) as $m         # find smallest value in either array
   | [range($m;a+b|max)|[]]  # create array of [] for indices [min,max]
   | .[ a[]-$m ][0]=1        # store 1 in [0] at corresponding indices of a
   | .[ b[]-$m ][1]=1        # store 1 in [1] at corresponding indices of b
   | .[[[1,1]]]              # find all the indices where we stored a 1 for a and b
   | map(.+$m)               # convert back from indices to values
;

这样可以避免使用{}对象,并且由于jq没有位操作,因此可以使用数组模拟它们。

在线尝试!


2

公理,411字节

b(x,v)==(l:=1;h:=#v;repeat(l>h=>break;m:=(l+h)quo 2;x<v.m=>(h:=m-1);x>v.m=>(l:=m+1);return m);0);g(a,b)==(if #a>#b then(v:=a;w:=b)else(v:=b;w:=a);c:=sort(v);for x in w repeat(if binSearch(x,c)~=0 then return 1);0)
f(a:List INT,b:List INT):List INT==(r:List INT:=[];#a*#b=0=>r;x:=sort(a);y:=sort(b);i:=1;repeat(i>#x=>break;v:=x.i;binSearch(v,y)=0=>(i:=i+1);r:=concat(r,v);while i<=#x and x.i=v repeat i:=i+1);r)

高尔夫和测试

--suppose v.1<=v.2<=....<=v.#v as the default function sort() produce
--   binary serch of x in v, return the index i with v.i==x
--   return 0 if that index not exist
--traslated in Axiom from C  book
--Il Linguaggio C, II Edizione 
--Brian W.Kerninghan, Dennis M.Ritchie
binSearch(x,v)==
    l:=1;h:=#v
    repeat
       l>h=>break
       m:=(l+h)quo 2
       x<v.m=>(h:=m-1) 
       x>v.m=>(l:=m+1)
       return m
    0

--N*log(N)+n*log(n)+N*n*log(n) so it is N*n*log(n) or n*N*log(N)
ListIntersection(a:List INT,b:List INT):List INT==
    r:List INT:=[];#a*#b=0=>r
    x:=sort(a);y:=sort(b)
    i:=1
    repeat
        i>#x=>break
        v:=x.i
        binSearch(v,y)=0=>(i:=i+1)
        r:=concat(r,v)
        while i<=#x and x.i=v repeat i:=i+1
    r

(5) -> f([],[])
   (5)  []
                                                       Type: List Integer
(6) -> f([1000],[])
   (6)  []
                                                       Type: List Integer
(7) -> f([3,1,2,4,3,1,1,1,1,3],[3,1,-1,0,8,3,3,1])
   (7)  [1,3]
                                                       Type: List Integer
(8) -> f([1,2,1],[3,3,4])
   (8)  []
                                                       Type: List Integer

2

公理,257字节

W(x,y)==>while x repeat y;f(a,b)==(r:List INT:=[];#a*#b=0=>r;x:=sort(a);y:=sort(b);i:=1;j:=1;repeat(j>#y=>break;W(i<=#x and x.i<y.j,i:=i+1);i>#x=>break;W(j<=#y and y.j<x.i,j:=j+1);j>#y=>break;v:=y.j;if x.i=v then(r:=concat(r,v);W(j<=#y and y.j=v,j:=j+1)));r)

这没有使用binsearch。。。但是我不知道这个大O。。。

--N*log(N)+n*log(n)+???
ListIntersection(a:List INT,b:List INT):List INT==
    r:List INT:=[];#a*#b=0=>r
    x:=sort(a);y:=sort(b)
    i:=1;j:=1
    repeat
        j>#y=>break
        while i<=#x and x.i<y.j repeat i:=i+1
        i>#x=>break
        while j<=#y and y.j<x.i repeat j:=j+1
        j>#y=>break
        v:=y.j;if x.i=v then 
                        r:=concat(r,v)
                        while j<=#y and y.j=v repeat j:=j+1
    r

(3) -> f([3,1,2,4,3,1,1,1,1,3],[3,1,-1,0,8,3,3,1])
   (3)  [1,3]
                                                       Type: List Integer
(4) -> f([],[])
   (4)  []
                                                       Type: List Integer
(5) -> f([1,2,1],[3,3,4])
   (5)  []
                                                       Type: List Integer

没有执行很多测试,所以可能会出错...


2

果冻,12字节

pEÐfḢ€ĠḢ€$ị$

在线尝试!


在Tio 3,1,2,4,3,1,1,1,1,3输入和3输入返回输出[1,2,3]而非[3]
RosLuP

@RosLuP试试[3]代替3
-HyperNeutrino

在我看来,如果2个列表的交集的结果返回(和其他情况一样),则是可以的[]如果结果是空集,[2]如果2个列表具有1个共同点
则为

@RosLuP我无能为力,这就是Jelly的输出方式。空的[]和单例列表的元素。您可以转到Wiki页面(原子)并附加内置的Python Stringify,但这会使我的回答更长,而且严格的I / O愚蠢。
HyperNeutrino

如果只接受[]方式的输入列表(例如[1],[1,2,3] [],[],[]等),并且仅以列表[]方式输出列表输出,对我来说可以(作为其输入)。如果列表的括号是{}或(),请在上面的语音中重复右一。这仅出于我的想法,问题可能会另行说明,一切都很好
RosLuP

2

外壳,9个字节

mo←←kIfE*

在线尝试!

m            Map
 o←←         taking the first element from the first element
    kI       over lists of identical values from
        *    the Cartesian product of the two input lists
      f      filtered by
       E     both elements of a pair being equal.

在GitHub上的Husk源代码中,k(“键”)实现为对列表进行排序和对相邻值进行分组的组成,因此尽管我实际上找不到“ groupOn”的实现,但可以肯定地说它没有实现因为Haskell是一种功能语言,并且将相邻的相等值分组是一个非常简单的减少链表操作,所以什么也不要做。(我可以找到k的其他类型签名“ keyby”的实现,可以在此处将其更改I=,但我不知道Haskell,所以我无法知道它的工作原理。)

另外,在意识到不允许进行各种设置操作之前,我想到了一个简短的Brachylog答案: ⟨∋∈⟩ᵘ


2

R, 141 83个字节

l=sapply(strsplit(readLines(file("stdin"))," "),as.numeric)
r=rle(sort(unlist(l)))[[2]]
r[sapply(r,function(x)any(x==l[[1]])&any(x==l[[2]]))]

朱塞佩(Giuseppe)改进

function(a,b){r=rle(sort(c(a,b)))[[2]];r[sapply(r,function(x)any(x==a)&any(x==b))]}

在线尝试 这里 这里


这似乎不起作用。不过,我可能试图用错它,所以也许您应该提供在线试用的链接展示如何使用它并证明它可以满足挑战的要求。(对答案的解释也不会有任何伤害。)
不相关的字符串

你不能假设输入ab预先定义的,你必须接受的输入,无论是把他们作为函数的参数或标准输入。
朱塞佩

1
我认为高尔夫球手将使它像这样
朱塞佩

1
@db“页眉”为“代码”部分中定义的匿名函数命名(完全可以接受匿名函数),然后页脚对其进行调用。页眉,代码和页脚部分都是一段代码,但是只有“代码”部分中的部分才计入字节数:-)
Giuseppe

1

Python3,51个字节

lambda a,b:[v for v in a if{n:1 for n in b}.get(v)]

如果输入列表可以包含重复项:

Python3,67个字节

lambda a,b:list({v:1 for v in a if {n:1 for n in b}.get(v)}.keys())

1

的PHP78,77字节

function($a,$b){foreach($a as$x)foreach($b as$y)$x==$y?$c[$x]=$x:0;return$c;}

在线尝试!

没有多余的装饰,但符合规则(我认为)。

输出量

[], []
[]

[1000], []
[]

[3,1,2,4,3,1,1,1,1,3], [3,1,-1,0,8,3,3,1]
[3,1]

[1,2,1], [3,3,4]
[]
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.