ユニークな双子を見つける


28

2つの配列/リスト/非負整数のベクトルABが与えられます。あなたの仕事は、出力の整数最高であるNの両方に表示されていることをAB、及び両方でもユニークである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]、[8、7、6、3、4、3]-> 4
[2、2、2、6、3、5、8、2]、[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

回答:


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

1バイトのゴルフをしてくれた@seshoumaraに感謝します!

オンラインでお試しください!

使い方

uniqはソートされた入力を受け取り、コマンドラインフラグに応じて1つまたは複数のアクションを実行します。

U<<<$1そしてU<<<$2関数を呼び出しU、入力として第1及び第2のコマンドライン引数と。それぞれについて、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

Mr. 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

ソリューションを少し9バイト(を使用してeS@Fm.m/d)掘り下げ、入力を2つのリストのリストとして取得します。
ミスターXcoder

@ Mr.Xcoderそれは、それ自身の答えになるほど十分に異なるようです。

私はチャレンジのOPであるため、投稿することに消極的です。あなただけの代替(もちろんしたい場合)のように、あなたの現在のアプローチに言及、それを使用して信用を与えることができます
ミスターXcoder



5

、7バイト

→►≠OfEΠ

入力を2つのリストのリストとして受け取り、任意の数のリストに対しても機能します(可能であれば、それぞれに1回だけ発生する最大数を返します)。 オンラインでお試しください!

説明

これは、新しい「maximum by」関数を(ab)使用する最初のハスクの回答です。

→►≠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

TIO


1
1バイトを削る代わりに、最後にsort -rnwith sed qを使用しtail -1ます。grep -wfちなみに素晴らしい発見。+1
seshoumara

@seshoumara、ヒントをありがとう、実際、-m1 grepオプションで3バイトを削ることができました。
ナウエルフイユル


3

J、23バイト

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

(-.-.@~:#]) リストから繰り返し要素を削除します

& 両方の引数にこれを行います

([-.-.) AはBと交差します。これは同等のフレーズです:「Aマイナス(AマイナスB)」

>./ マックスを取る

オンラインでお試しください!


同様に、交差部分をに置き換えることができますe.~#]。これをゴルフするのは難しいことがわかっています... /.-keyを使用して成功しませんでした(((1=#)/.~#~.)最初の部分は私のカウントでは2バイト長くなります)
コール

@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配列として受け取ります。構築しfilterているgroupと共に、入力配列要素をSとのみを有するもの引き出しcount -eqにUALを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))

102から86に到達してくれてありがとう@justinMariner

86から75に到達してくれてありがとう@tsh

75から71に到達してくれてありがとう@Arnauld

オンラインでお試しください!


PPCGへようこそ!私の知る限りていることを確認していません、これを言うことができるようにe一度だけでショーアップaしてb
マーティン・エンダー

@MartinEnderありがとう!私が見逃した詳細を反映するように答えを編集しました!
ネイト

1
私はlastIndexOfそのような使用を考えたことがありません、それはかなり賢いです。これを86バイトまで減らすことができます:オンラインで試してみてください!。詳細については、JSのヒントをご覧ください。
ジャスティンマリナー

1
使用する方(g=x=>x.filter(y=>y==e).length==1)が短いようです。
tsh

1
私が考える この1つは、すべてのエッジケース(71バイト)を通過しています。
アーノールド

2

Haskell57 53バイト

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

オンラインでお試しください!

UPD:ありがとう@Laikoni


特にPPCGとHaskellゴルフへようこそ!これはいい最初の答えです!2つの小さなこと:いくつかのバイトを節約する代わりに、f中置演算子として宣言して書き込むこともできます。[1|...]==[1]sum[1|...]==1
ライコニ

私達のコレクション:あなたはすでにそれを見ていない場合は、ここでは面白いかもしれませんいくつかのリンクですHaskellでのヒントをゴルフハスケルのルールゴルフへのガイドモナドと男性のうち、当社のHaskellのチャットルームで。
ライコニ

1
インライン化!andさらに2バイト節約:オンラインで試してみてください!
ライコニ

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@#22番目のリストについても同じことを行い、両方に存在するペアを見つけます。次に、でCases終わるペアを(で)1取り出し、各結果の最初の要素を取得します。これにより、すべての一意の双子のリストが得られます。最後にMax、最大の一意の双子を返します。


2

ローダ、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 Core)117 115 114 111 108バイト

115 114バイト

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

オンラインでお試しください!

117 111バイト

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}

これは、引数として2つのリストを受け取る関数です。オンラインでお試しください!

説明

  {            }  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に等しい

⍺⍴⍨ それを使用して特定の要素の形状を変更します(つまり、一意でない場合は空のリストを提供します)

これで、各入力リストに一意の要素の2つのリストができました(ただし、各要素はリストであり、一意でない要素の残余として空のリストがあります)。

∩/ 交差点(縮小)

ϵ nlist(平坦化)

⌈/ 最大(削減)


* Classicでは、としてカウントされ⎕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パラメーターaおよびとして提供しますb


これらのGETパラメーターを定数に交換できると思います。
プログロック

@Progrock有効な入力メソッドはありません。
タイタス

AとBが配列として与えられる質問フレーズ。そして、合理的な入力および出力方法を言います。本当にあなたのレシピが好きです。(しかし、廃止されたPhp 5.6でチョーク。)
プログロック

1

Java 8、133バイト

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;}

説明:

ここで試してみてください。

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

JavaScript ES5、 122 121 114バイト

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]}

私はここに新しいので、関数定義を削除してその内容を置くことができるかどうかは本当にわかりません(17バイト節約できます)

これが実際の例です: 122 121 114

122〜121バイト:forでの初期化のラッピング

121〜114バイト:b文字列でなければなりません


2
PPCGへようこそ!関数定義を削除することはできませんが、代わりにラムダ関数を使用できる場合があります(JSがわからないため、支援できません)。
ミスターXcoder

それをクリアしてくれてありがとう。ラムダ関数が文字を保存できるとは思いませんが、試してみます。また、「合理的な入力および出力方法/形式は許可されます」と言うので、文字列を受け入れてb保存できb=''+b,ますか?
ピイン

JavaScriptがわからないのに、なんとか115バイトに達しました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]}
ミスターXcoder

1
うん必ず文字列入力は罰金だろう
氏Xcoder

しかし、あなたが思いついたJavaScriptはES6ではなくES5です。ES6の回答がすでに投稿されているため、ES5を投稿しました。2番目の質問に答えてくれてありがとうhehe
Piyin


1

Jq 1.5、76バイト

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

拡大

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

オンラインでお試しください!

同じ長さの別のソリューションを次に示します。

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

拡大

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

オンラインでお試しください!


1

APL、47バイト

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

2つのベクトルを取る匿名関数を宣言し、重複する要素を削除してから、結果の共通部分で最大の要素を見つけます。

A←⍺そしてB←⍵、関数に渡される引数を格納しAB

a=ba等しい各インデックスに1を持つベクトルを返しますb。if aがスカラー(つまり、ベクトルではなく単一の量)の場合、要素がb存在aする場合は1で、そうでない場合は0のベクトルを返します。例えば:

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

{+/⍵=A}:ネストされた匿名関数。ベクトル内の引数の出現を見つけ、Aそれらを合計します。すなわち、引数の出現回数を見つけますA

1={+/⍵=A}¨A:Aの各要素にネストされた匿名関数を適用し、1に等しい要素、つまり一意の要素を見つけます

((1={+/⍵=A}¨A)/A←⍺):一意の要素の位置を見つけたので、元のベクトルでこれらの要素のみを選択します(/位置が左引数の1に対応する右引数要素から選択します)

R←((1={+/⍵=A}¨A)/A←⍺)∩(1={+/⍵=B}¨B)/B←⍵:2番目の引数に対してプロセスを繰り返します。ユニークな要素だけができたので、共通の要素、つまり共通の要素を見つけてベクトルに保存しますR

R[⍒R]:の要素Rに降順でアクセスします

1↑R[⍒R]R降順でソートされるときの最初の要素を取得します

テストケース:

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バイト

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

使い方:

2つのリストが重複するテストから開始します=/(リストのすべてのメンバー間に同等性テストを挿入します:

   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

同じ列に複数の1がある場合は、左の引数(この場合は6)に対して番号が一意ではないことを意味します。行内-正しい引数(3)

次に、すべての行とすべての列を合計して、重複箇所を見つけます。

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

上記のリストのデカルト積を見つけ、1より大きいメンバーを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

等式行列cをmでマスクして、両方のリストに共通する一意の要素を見つけ、これに左引数を掛けます。

]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

次に、リストをフラット化し、max要素を見つけます。

 >./,l 
4

オンラインでお試しください!


1

C#(.NET Core)66 + 31 = 97 65 + 31 = 96バイト

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

オンラインでお試しください!

+31バイト using System;using System.Linq;

@aloisdgの答えからインスピレーションを得ました。ただし、両方の配列で一意の値を検索する代わりに、intersect最初に操作の順序を逆にしてから、配列が連結されて交差しているときに2回発生する項目の最大値を見つけます。使うことができます<3ようにCount、それが両方の配列であろうように、任意の値の少なくとも2あろう。

謝辞

@aloisdgとFuncカレーを使用することを提案してくれた-1バイト。


1
良いアイデア!私は本当にそれが好き
aloisdgは回復モニカ言う


ではカリーあなたは1バイトを獲得することができます!オンラインでお試しください!
aloisdgによると、Reinstate Monica

0

オクターブ57 56バイト

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

2つの数値配列のセル配列を入力として受け取る匿名関数。

オンラインでお試しください!

説明

cellfun(@(x)...)2つの入力配列の各()に対して、エントリ(x.'==x)間のペアごとの等値比較の行列が作成されます。x(...)列の合計が1sum(...)==1)であるエントリのみを保持します()。結果をセル({...})にパックします。intersect2つの結果の交差(){:}が計算され、最大値(max(...))が取得されます。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.