寻找独特的双胞胎


28

您将获得两个非负整数AB的数组/列表/向量。您的任务是输出出现在AB中的最高整数N,并且在AB中都唯一。


测试用例:

A,B->输出

[6],[1、6]-> 6
[1、2、3、4],[4、5、6、7]-> 4
[0,73,38,29],[38,29,73,0]-> 73
[1、3、4、6、6、9、9],[8、7、6、3、4、3]-> 4
[2,2,2,6,3,5,8,8],[8,7,5,8]-> 5
[12,19,18,289,19,17],[12,19,18,17,17,289]-> 289
[17,29,39,29,29,39,18],[19,19,18,20,17,18]-> 17
[17,29,39,29,29,39,18,18],[19,19,18,20,17,18]-> 17

Answers:


7

果冻,7个字节

fċ@ÐṂ;Ṁ

在线尝试!

怎么运行的

fċ@ÐṂ;Ṁ  Main link. Left argument: A. Right argument: B

f        Filter; keep those elements of A that appear in B.
   ÐṂ    Yield all elements of the result for which the link to left yields a
         minimal value (2).
 ċ@        Count the occurrences of the element...
     ;     in the concatenation of A and B.
      Ṁ  Take the maximum.

7

Bash + coreutils,49个字节

U()(sort -rn|uniq -u$1)
(U<<<$1;U<<<$2)|U D|sed q

感谢@seshoumara打高尔夫球1个字节!

在线尝试!

怎么运行的

uniq接受排序的输入并执行一个或多个操作,具体取决于命令行标志。

U<<<$1并以第一个和第二个命令行参数作为输入来U<<<$2调用该函数U。每sort -rn|uniq -u执行一次,对输入进行数字排序(-n)并按降序(-r)对uniq进行排序,这将仅打印唯一的行(-u)。

两者的输出(每个数组的唯一元素)被串联并通过管道传输到U D,即
sort -rn|uniq -uD。这次,uniq将仅打印重复的行(-D),并且仅打印每行的第一次重复。

虽然手册页说它将打印所有重复,但增加的-u原因-D仅打印第一次出现的重复行。通常使用来实现此行为uniq -d

最后,sed q立即退出,将其输入(两个数组的唯一元素)减少到第一行。由于输出按降序排序,因此这是最大值。


6

Pyth,12个 9字节

试试吧

eS@Fm.m/d

多亏了Xcoder先生,节省了3个字节。

说明

eS@Fm.m/d
    m  /d   Count the occurrences of each element.
     .m     Take only those that appear the minimum number of times.
  @F        Apply the above to A and B and take the intersection.
eS          Take the largest.

真好!我的解决方案也是12个字节
Xcoder先生17年

将我的解决方案简化为9个字节(使用eS@Fm.m/d),然后将输入作为两个列表的列表。
Xcoder先生17年

@ Mr.Xcoder似乎有足够不同,可以自己回答。

由于我是挑战的执行者,因此我不愿意发布它。您可以使用它并表示赞赏,并提及您当前的方法(如果需要的话)
Xcoder先生



5

外壳,7个字节

→►≠OfEΠ

将输入作为两个列表的列表,也可用于任意数量的列表(如果可能,返回每个正好出现一次的最高数字)。 在线尝试!

说明

这是Husk对(ab)使用新的“ maximum by”函数的第一个答案

→►≠OfEΠ  Implicit input, say [[3,2,1,3],[1,2,3,4]]
      Π  Cartesian product: [[3,1],[2,1],[3,2],[2,2],[1,1],[3,3],[1,2],[3,1],[3,4],[2,3],[1,3],[3,2],[2,4],[3,3],[1,4],[3,4]]
    fE   Keep those that have equal elements: [[2,2],[1,1],[3,3],[3,3]]
   O     Sort: [[1,1],[2,2],[3,3],[3,3]]
 ►≠      Find rightmost element that maximizes number of other elements that are not equal to it: [2,2]
→        Take last element: 2

4

Bash + coreutils,60个字节

f()(sort -rn<<<"$1"|uniq -u);grep -m1 -wf<(f "$1") <(f "$2")

在线试用

Bash,89个字节

c()(for e;{((e^$1||r++,2^r));});for x in $1 $2;{((x<r))||c $x $1||c $x $2||r=$x;};echo $r

蒂奥


1
最后使用sort -rnwith sed q而不是tail -1剃除1个字节。grep -wf顺便说一句很棒的发现。+1
seshoumara

@seshoumara,谢谢您的提示,实际上,我可以使用-m1 grep选项剃掉3个字节。
Nahuel Fouilleul


3

J,23个字节

>./@([-.-.)&(-.-.@~:#])

(-.-.@~:#]) 从列表中删除任何重复的元素

& 对两个参数都这样做

([-.-.) 我们希望A与B相交。这是等效的短语:“ A减(A减B)”

>./ 以最大

在线尝试!


同样,您可以将交集部分替换为e.~#]。事实证明打高尔夫球很难。我尝试使用/.-key失败(((1=#)/.~#~.)对于我来说,第一部分的长度增加了2个字节)
cole

@cole,是的,我也尝试了一种关键方法,并且也采用了自我分类的方法。但是,我无法用其他任何方法超越我的提交。
乔纳

2

PowerShell,94字节

param($a,$b)filter f($x){$x|group|?{$_.count-eq1}}
(f($a|sort|?{$_-in((f $b).Name)}))[-1].Name

在线尝试!

接受输入$a$b作为数组。构造一个将输入数组元素在一起的a filtergroup并仅拉出具有count -equal的元素1(即,仅输入数组中唯一的元素)。

然后,下一行构造算法。首先我们sort $a,然后取出那些是-in独特的项目$b。然后将它们自身唯一化,[-1]选择最大的,然后我们选择.Name它们。剩下的就在管道上,输出是隐式的。


2

Javascript(ES6),102 86 75 71字节

a=>b=>Math.max(...a.map(e=>(g=x=>x.map(y=>y-e||x--,x=1)|!x)(a)*g(b)*e))

感谢@justinMariner从102变为86

感谢@tsh从86提升到75

感谢@Arnauld从75升至71

在线尝试!


欢迎来到PPCG!据我所知,这并不能确保e仅在a和中显示一次b
Martin Ender

@MartinEnder谢谢!编辑答案以反映我错过的细节!
Nate

1
我从来没有想过lastIndexOf那样使用,那非常聪明。您可以将其减少到86个字节:在线尝试!。进一步了解JS技巧
贾斯汀·马里纳

1
似乎使用(g=x=>x.filter(y=>y==e).length==1)更短。
tsh

1
认为 也通过了所有极端情况(71个字节)。
Arnauld

2

Haskell57 53字节

x?y|let v!x=filter(==v)x==[v]=maximum[a|a<-x,a!x,a!y]

在线尝试!

UPD:谢谢@Laikoni


欢迎来到PPCG,尤其是Haskell高尔夫!这是一个不错的第一答案!两件小事情:您也可以声明f为infix运算符并编写[1|...]==[1]而不是sum[1|...]==1保存一些字节。
Laikoni '17

在你还没有看到他们已经情况下,这里有一些链接,这可能是有趣的:我们的收藏在Haskell打高尔夫球的技巧,将指导高尔夫在Haskell规则作者单子和人,我们的Haskell的聊天室。
Laikoni '17

1
!联可and节省另外两个字节:在线尝试!
Laikoni '17

2

Wolfram语言(Mathematica),40个字节

Max@Cases[Tally@#⋂Tally@#2,{x_,1}:>x]&

在线尝试!

怎么运行的

Tally@#给出了第一个输入的唯一元素及其计数的列表:例如Tally[{2,2,2,6,3,5,8,2}]yields {{2,4},{6,1},{3,1},{5,1},{8,1}}

Tally@#2对第二个列表执行相同操作,并找到两个列表中都存在的对。然后,我们选择以Cases结尾的(对)对1,并获取每个结果的第一个元素,从而为我们提供了所有唯一双胞胎的列表。最后,Max返回最大的唯一双胞胎。


2

Röda,48个字节

{m={|n|sort|count|[_]if[_=n]};[_()|m 1]|m 2|max}

在线尝试!

jq170727的jq答案启发。

说明:

{ /* Anonymous function, takes input from the stream */
  m={|n|        /* Local function m with parameter n: */
    sort|count| /*   Count unique values in the stream */
    [_]if[_=n]  /*   For each value, push it to the stream if its count is n */
  };
  [      /* For each list in the stream: */
    _()| /*   Flat it (push its values to the stream) */
    m 1  /*   Push values that appear only once to the stream */
  ]|
  m 2|   /* Push values that appear twice to the stream */
  max    /* Find the max value in the stream */
}

2

F#(.NET核心)117 115 114 111 108个字节

115114字节

countBy这次的另一个解决方案是:

let u x=x|>Seq.countBy id|>Seq.filter(fun a->snd a=1)|>Seq.map fst|>set
let f x y=Set.intersect(u x)(u y)|>Seq.max

在线尝试!

117111字节

let u x=x|>Seq.filter(fun a->x|>Seq.filter((=)a)|>Seq.length=1)|>set
let f x y=Set.intersect(u x)(u y)|>Seq.max

在线尝试!

100%F#!欢迎任何帮助!

前缀表示法赢得了6个字节!

108字节

let f a b=Set.intersect(set a)(set b)|>Seq.filter(fun x->a@b|>Seq.filter(fun y->y=x)|>Seq.length<3)|>Seq.max

@是concat函数!谢谢@ Ayb4btu使用此算法。

在线尝试!



2

17 16字节

MX{_Na=_Nb=1FIa}

该函数需要两个列表作为参数。在线尝试!

说明

  {            }  Define function, args are a & b:
            FIa    Filter elements of a on this function:
   _Na              Count of element in a
      =_Nb          equals count of element in b
          =1        equals 1
                  This gives a function that returns a list of unique twins
MX                Modify it to take the max and return that instead

2

APL(Dyalog),18个字符= 23个字节*

完整的程序主体。提示输入来自STDIN的列表。适用于任意数量的列表。输出到STDOUT。

⌈/∊∩/{⊂⍺⍴⍨1=≢⍵}⌸¨⎕

在线尝试!

 提示输入来自STDIN的评估输入

{}⌸¨ 对于每个列表,使用该唯一元素作为左参数(),并将其出现的索引列表作为右参数(),对该列表中的每个唯一元素调用以下函数

≢⍵ 索引总计(即出现次数)

1= 等于1

⍺⍴⍨ 使用它来重塑特定元素(即,如果不唯一,则给出空列表)

现在,对于每个输入列表,我们都有两个唯一元素列表(尽管每个元素都是一个列表,并且有空列表作为非唯一元素的残差)。

∩/ 交集(减少)

ε NLIST(扁平化)

⌈/ 最大(减少)


*经典,计数⎕U2338


1

MATL,13字节

,iSY'1=)]X&X>

在线尝试!验证所有测试用例

说明

,      % Do twice
  i    %   Take input: array
  S    %   Sort array
  Y'   %   Run-length encode: pushes array of values and array of run lengths
  1=   %   Compare each run length with 1
  )    %   Use as logical index. This keeps only values that have appeared once
]      % End
X&     % Intersection of the two arrays
X>     % Maximum of array. Implicitly display

1

PHP,98字节

<?foreach(($c=array_count_values)($_GET[a])as$a=>$n)$n-1||$c($_GET[b])[$a]-1||$a<$r||$r=$a;echo$r;

提供数组作为GET参数ab


Think you could swap those GET params for constants.
Progrock

@Progrock That´s no valid input method.
Titus

The question phrases that A and B are given as arrays. And says any reasonable input and output method.... not that I can follow that link easily. Really like your recipe. (Chokes in obsolete Php 5.6 though.)
Progrock

1

Java 8, 133 bytes

a->b->{long r;for(java.util.Collections c=null;;a.remove(r))if(b.contains(r=c.max(a))&c.frequency(a,r)*c.frequency(b,r)==1)return r;}

Explanation:

Try it here.

a->b->{                  // Method with two ArrayList<Long> parameters and long return-type
  long r;                //  Result-long
  for(java.util.Collections c=null; 
                         //  Create a java.util.Collections to save bytes
      ;                  //  Loop indefinitely
       a.remove(r))      //    After every iteration, remove the current item
    if(b.contains(r=c.max(a)) 
                         //   If the maximum value in `a` is present in `b`,
       &c.frequency(a,r)*c.frequency(b,r)==1)
                         //   and this maximum value is unique in both Lists:
      return r;          //    Return this value
                         //  End of loop (implicit / single-line body)
}                        // End of method

1

R, 73 bytes

function(A,B)max(setdiff(intersect(A,B),c(A[(d=duplicated)(A)],B[d(B)])))

Try it online!

Computes A intersect B, then the maximum of the difference between that and the duplicated elements of A and B.


1

JavaScript ES5, 122 121 114 bytes

function f(a,b){for(i=a.sort().length;--i+1;)if(a[i]!=a[i+1]&&a[i]!=a[i-1]&&!(b.split(a[i]).length-2))return a[i]}

I'm new here, so I don't really know if I can remove the function definition and just put its contents (which would save me 17 bytes)

Here's the working example: 122 121 114

122 to 121 bytes: Wrapping initialization in a for

121 to 114 bytes: b has to be a string


2
Welcome to PPCG! You cannot remove the function definition, but you might be able to use a lambda function instead (I don't know JS so I cannot help you with that).
Mr. Xcoder

Thanks for clearing that out. I don't think lambda functions can save any characters, but I'll try. Also, since you say "Any reasonable Input and Output method / format is allowed", could I accept an string as b and save b=''+b,?
Piyin

I did manage to get to 115 bytes although I don't know JavaScript: f=(a,b)=>{for(b=''+b,i=a.sort().length;--i+1;)if(a[i]!=a[i+1]&&a[i]!=a[i-1]&&!(b.split(a[i]).length-2))return a[i]}.
Mr. Xcoder

1
Yeah sure a string input would be fine
Mr. Xcoder

But that JavaScript you came up with would be ES5, not ES6. An ES6 answer is already posted, which is why I posted the ES5. And thanks for answering the second question hehe
Piyin


1

Jq 1.5, 76 bytes

def m(n):[.[indices(.[])|select(length==n)[]]]|unique[];[map(m(1))|m(2)]|max

Expanded

def m(n): # function to emit elements of multiplicity n
  [
    .[                         # select elements with
         indices(.[])          # number of indices in the array
       | select(length==n)[]   # equal to specified multiplicity
    ]
  ] | unique[]                 # emit deduped values
;

[
    map(m(1))   # collect multiplicity 1 elements from each array
  | m(2)        # collect multiplicity 2 elements
] | max         # choose largest of these elements

Try it online!

Here is another solution which is the same length:

def u:[keys[]as$k|[.[$k]]-(.[:$k]+.[$k+1:])]|add;map(u)|.[0]-(.[0]-.[1])|max

Expanded

def u: # compute unique elements of input array
  [
      keys[] as $k                   # for each index k
    | [.[$k]] - (.[:$k]+.[$k+1:])    # subtract other elements from [ .[k] ]
  ]                                  # resulting in [] if .[k] is a duplicate
  | add                              # collect remaining [ .[k] ] arrays
;
  map(u)                             # discard duplicates from each input array
| .[0]-(.[0]-.[1])                   # find common elements using set difference
| max                                # kepp largest element

Try it online!


1

APL, 47 bytes

{1↑R[⍒R←((1={+/⍵=A}¨A)/A←⍺)∩(1={+/⍵=B}¨B)/B←⍵]}

Declares an anonymous function that takes two vectors, eliminates duplicate elements, then finds the biggest element in the intersection of the results.

A←⍺ and B←⍵ store the arguments passed to the function in A and B.

a=b returns a vector with 1 in each index in which a is equal to b. If a is a scalar (i.e. single quantity and not a vector) this returns a vector with 1 wherever the element in b is a and 0 when it is not. For example:

Input: 1=1 2 3
Output: 1 0 0

{+/⍵=A}: nested anonymous function; find the occurrences of the argument in vector A and add them up i.e. find the number of occurrences of the argument in A

1={+/⍵=A}¨A: apply the nested anonymous function to each element in A and find the ones that equal 1 i.e. unique elements

((1={+/⍵=A}¨A)/A←⍺): having found the location of the unique elements, select just these elements in the original vector (/ selects from the right argument elements whose locations correspond to 1 in the left argument)

R←((1={+/⍵=A}¨A)/A←⍺)∩(1={+/⍵=B}¨B)/B←⍵: repeat the process for the second argument; now that we have just the unique elements, find the intersection i.e. common elements and store this in vector R

R[⍒R]: access the elements of R in decreasing order

1↑R[⍒R]: take the first element of R when it's sorted in decreasing order

Test case:

Input: 17 29 39 29 29 39 18 18 {1↑R[⍒R←((1={+/⍵=A}¨A)/A←⍺)∩(1={+/⍵=B}¨B)/B←⍵]} 19 19 18 20 17 18
Output: 17

1

J, 30 bytes

[:>./@,[*([*+/"1(1=*/)+/)@(=/)

How it works:

I start with testing where the two list overlap by =/ (inserts equality test between all the members of the lists:

   a =. 1 3 4 6 6 9
   b =. 8 7 6 3 4 3
   ]c=. a =/ b 
0 0 0 0 0 0
0 0 0 1 0 1
0 0 0 0 1 0
0 0 1 0 0 0
0 0 1 0 0 0
0 0 0 0 0 0

More than one 1 in the same column means that the number is not unique for the left argument (6 in this case); in the row - for the right argument (3)

Then I sum up all rows and all columns to find where are the duplicates:

   +/ c
0 0 2 1 1 1
   +/"1 c
0 2 1 1 1 0

I find the cartesian product of the above lists and set the members greater than 1 to 0.

    m =. (+/"1 c) (1=*/) +/c
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 1 1 1
0 0 0 1 1 1
0 0 0 1 1 1
0 0 0 0 0 0

I mask the equality matrix c with m to find the unique elements that are common to both lists and multiply the left argument by this.

]l =. a * m * c
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 4 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0

Then I flatten the list and find the max element:

 >./,l 
4

Try it online!


1

C# (.NET Core), 66+31=97 65+31=96 bytes

a=>b=>a.Intersect(b).Where(x=>a.Concat(b).Count(y=>y==x)<3).Max()

Try it online!

+31 bytes for using System;using System.Linq;

I took inspiration from @aloisdg's answer. However, instead of searching for unique values in both arrays, I inverted the order of operations so that intersect is first, and then find the max value of the items that occur twice when the arrays are concatenated and are in their intersect. I can use <3 as Count will be at least 2 for any value, as it will be in both arrays.

Acknowledgements

-1 byte thanks to @aloisdg and his suggestion to use Func currying.


1
Nice idea! I really like it
aloisdg says Reinstate Monica



0

Octave, 57 56 bytes

@(x)max(intersect(cellfun(@(x){x(sum(x'==x)==1)},x){:}))

Anonymous function that takes as input a cell array of two numerical arrays.

Try it online!

Explanation

For each (cellfun(@(x)...)) of the two input arrays, this creates a matrix of pairwise equality comparisons between its entries (x.'==x); keeps (x(...)) only the entries for which the column sum is 1 (sum(...)==1); and packs the result in a cell ({...}). The intersection (intersect) of the two results ({:}) is computed, and the maximum (max(...)) is taken.


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.