Znajdź unikalne bliźniaki


28

Będziesz mieć dwie tablice / lists / wektory liczb całkowitych nieujemnych A i B . Twoim zadaniem jest wyjście najwyższa liczba całkowita N , który pojawia się zarówno A i B , a także jest wyjątkowy zarówno A i B .


Przypadki testowe:

A, B -> Dane wyjściowe

[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

Odpowiedzi:


7

Galaretka , 7 bajtów

fċ@ÐṂ;Ṁ

Wypróbuj online!

Jak to działa

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 bajtów

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

Dzięki @seshoumara za grę w golfa na 1 bajcie!

Wypróbuj online!

Jak to działa

uniq pobiera posortowane dane wejściowe i wykonuje jedną lub kilka akcji, w zależności od flag wiersza poleceń.

U<<<$1i U<<<$2wywołaj funkcję Uz pierwszym i drugim argumentem wiersza poleceń jako danymi wejściowymi. Dla każdego z nich sort -rn|uniq -uwykonywany jest sortowanie danych wejściowych numerycznie ( -n) i w kolejności malejącej ( -r) dla uniq , który wypisze tylko unikalne linie (-u ).

Dane wyjściowe obu (unikalne elementy każdej tablicy) są konkatenowane i przesyłane strumieniowo do U D, tj
sort -rn|uniq -uD. Tym razem uniq wypisze tylko zduplikowane linie ( -D) i tylko pierwsze powtórzenie każdego z nich.

Podczas gdy strona podręcznika mówi, że wydrukuje wszystkie powtórzenia, dodane -upowoduje -Ddrukowanie tylko pierwszego wystąpienia zduplikowanych linii. Takie zachowanie zwykle osiąga się za pomocą uniq -d.

Wreszcie, sed qnatychmiast kończy pracę, redukując dane wejściowe (unikalne elementy obu tablic) do pierwszej linii. Ponieważ dane wyjściowe zostały posortowane w kolejności malejącej, jest to wartość maksymalna.


6

Pyth, 12 9 bajtów

Spróbuj

eS@Fm.m/d

Zaoszczędzono 3 bajty dzięki Mr. Xcoder.

Wyjaśnienie

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.

Miły! Moje rozwiązanie miało również 12 bajtów .
Pan Xcoder,

Gra w golfa trochę w dół, 9 bajtów (za pomocą eS@Fm.m/d) i przyjmuję dane wejściowe jako listę dwóch list.
Pan Xcoder,

@ Mr.Xcoder To wydaje się na tyle inne, że stanowi własną odpowiedź.

Ponieważ jestem operatorem tego wyzwania, niechętnie go publikuję. Możesz po prostu z niego skorzystać i wyrazić uznanie, wymieniając swoje obecne podejście jako alternatywę (jeśli oczywiście chcesz)
Mr. Xcoder,



5

Łuska , 7 bajtów

→►≠OfEΠ

Pobiera dane wejściowe jako listę dwóch list, działa również na dowolną liczbę list (zwracając najwyższą liczbę, która występuje dokładnie w każdej z nich, jeśli to możliwe). Wypróbuj online!

Wyjaśnienie

Jest to pierwsza odpowiedź Łuski na (ab) użycie nowej funkcji „maksimum do” .

→►≠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 bajtów

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

Wypróbuj online

Bash, 89 bajtów

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
Zastosowanie sort -rnze sed qna koniec zamiast tail -1do golenia 1 bajt. Świetne znalezisko z grep -wfbtw. +1
seshoumara,

@seshoumara, dziękuję za podpowiedź, w rzeczywistości mógłbym ogolić 3 bajty z opcją -m1 grep.
Nahuel Fouilleul


3

J, 23 bajty

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

(-.-.@~:#]) usuwa z listy wszelkie powtarzające się elementy

& zrób to z obydwoma argumentami

([-.-.) Chcemy przecinać B. Jest to równoważne zdanie: „A minus (A minus B)”

>./ Weź maks

Wypróbuj online!


Odpowiednio możesz zastąpić część przecięcia e.~#]. Gra w golfa okazała się trudna ... Próbowałem użyć /.klawisza bezskutecznie ( ((1=#)/.~#~.)dla pierwszej części, która według mnie jest o 2 bajty dłuższa)
cole

@cole, tak, próbowałem również kluczowego podejścia, a także z samoklasyfikacją. Nie byłem jednak w stanie pokonać mojego zdania powyżej żadnym innym podejściem.
Jonasz

2

PowerShell , 94 bajty

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

Wypróbuj online!

Pobiera dane wejściowe $ai $bjako tablice. Tworzy filterto groupS elementy tablicy wejście razem i ciągnie się tylko te z count -eqUAL do 1(czyli takie, które są unikalne w tablicy wejściowego).

Następny wiersz konstruuje algorytm. Najpierw sort $awyciągamy te, które są -inunikatowymi przedmiotami $b. Są one wtedy same w sobie wyjątkowe, [-1]wybierana jest największa , a my bierzemy to .Name. Pozostaje to w potoku, a dane wyjściowe są niejawne.


2

JavaScript (ES6), 102 86 75 71 bajtów

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

Dzięki @justinMariner za uzyskanie od 102 do 86

Dzięki @tsh za przejście z 86 na 75

Dzięki @Arnauld za przejście z 75 na 71

Wypróbuj online!


Witamy w PPCG! O ile mogę to stwierdzić, nie upewniam się, że epojawi się tylko raz w ai b.
Martin Ender

@MartinEnder Thanks! Zredagowałem odpowiedź, aby odzwierciedlić szczegóły, które przegapiłem!
Nate

1
Nigdy nie myślałem o lastIndexOftakim użyciu , to całkiem sprytne. Możesz zmniejszyć to do 86 bajtów: Wypróbuj online! . Sprawdź wskazówki JS, aby uzyskać więcej.
Justin Mariner,

1
Wydaje się, że używanie (g=x=>x.filter(y=>y==e).length==1)jest krótsze.
tsh

1
Myślę, że ten również przekazuje wszystkie przypadki brzegowe (71 bajtów).
Arnauld

2

Haskell , 57 53 bajtów

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

Wypróbuj online!

UPD: Dzięki @Laikoni


Witamy w szczególności w PPCG i Haskell! To miła pierwsza odpowiedź! Dwie małe rzeczy: Możesz również zadeklarować fjako operator infix i pisać [1|...]==[1]zamiast sum[1|...]==1zapisywać niektóre bajty.
Laikoni,

Jeśli jeszcze ich nie widziałeś, oto linki, które mogą być interesujące: Nasza kolekcja wskazówek golfowych w Haskell , przewodnik po regułach golfowych w Haskell oraz Of Monads and Men , nasz czat w Haskell.
Laikoni,

1
Podszewka !z andoszczędza jeszcze dwa bajty: Wypróbuj online!
Laikoni,

2

Wolfram Language (Mathematica) , 40 bajtów

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

Wypróbuj online!

Jak to działa

Tally@#podaje listę unikalnych elementów pierwszego wejścia wraz z ich liczbą: np . Tally[{2,2,2,6,3,5,8,2}]daje {{2,4},{6,1},{3,1},{5,1},{8,1}}.

Tally@#2robi to samo dla drugiej listy i znajduje pary obecne w obu. Następnie wybieramy (z Cases) parami kończącymi się na 1, biorąc pierwszy element każdego wyniku, co daje nam listę wszystkich unikalnych bliźniaków. Wreszcie Maxzwraca największy unikalny bliźniak.


2

Röda , 48 bajtów

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

Wypróbuj online!

Zainspirowany odpowiedzią jq jq170727 .

Wyjaśnienie:

{ /* 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 bajtów

115 114 bajtów

Kolejne rozwiązanie z countBytym czasem:

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

Wypróbuj online!

117 111 bajtów

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

Wypróbuj online!

100% F #! Każda pomoc jest mile widziana!

6 bajtów wygranych dzięki notacji prefiksowej!

108 bajtów

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

@jest funkcją concat! Dziękuję @ Ayb4btu za ten algorytm.

Wypróbuj online!



2

Pip , 17 16 bajtów

MX{_Na=_Nb=1FIa}

Jest to funkcja, która przyjmuje dwie listy jako argumenty. Wypróbuj online!

Wyjaśnienie

  {            }  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 znaków = 23 bajty *

Pełny korpus programu. Monity o listę list z STDIN. Działa z dowolną liczbą list. Wyjścia do STDOUT.

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

Wypróbuj online!

 monit o ocenę danych wejściowych z STDIN

{}⌸¨ Dla każdej listy wywołaj następującą funkcję dla każdego unikalnego elementu na tej liście, używając unikalnego elementu jako lewego argumentu ( ) i listy indeksów jego występowania jako prawego argumentu ( ):

≢⍵ suma indeksów (tj. liczba wystąpień)

1= równa 1

⍺⍴⍨ użyj tego, aby zmienić kształt konkretnego elementu (tj. daje pustą listę, jeśli nie jest unikalna)

Teraz mamy dwie listy unikalnych elementów dla każdej listy wejściowej (chociaż każdy element jest listą, i istnieją puste listy jako pozostałości z elementów nieunikalnych).

∩/ skrzyżowanie (redukcja)

ϵ nlist (spłaszczyć)

⌈/ max (redukcja)


* w wersji Classic, licząc jako ⎕U2338.


1

MATL , 13 bajtów

,iSY'1=)]X&X>

Wypróbuj online! Lub Zweryfikuj wszystkie przypadki testowe .

Wyjaśnienie

,      % 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 bajtów

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

Podaj tablice jako parametry GET ai b.


Pomyśl, że możesz zamienić te parametry GET na stałe.
Progrock,

@Progrock To nie jest poprawna metoda wprowadzania danych.
Tytus

Frazy pytań, które A i B są podane jako tablice. I mówi każdą rozsądną metodę wejścia i wyjścia .... nie żebym mógł łatwo podążać za tym linkiem. Naprawdę podoba ci się twój przepis. (Dławiki w przestarzałym Php 5.6.)
Progrock

1

Java 8, 133 bajty

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

Wyjaśnienie:

Wypróbuj tutaj.

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 bajty

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

Wypróbuj online!

Obliczenia Aprzecinają się B, a następnie maksymalna różnica między tym a zduplikowanymi elementami Ai B.


1

JavaScript ES5, 122 121 114 bajtów

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

Jestem tu nowy, więc tak naprawdę nie wiem, czy mogę usunąć definicję funkcji i po prostu umieścić jej zawartość (co zaoszczędziłoby mi 17 bajtów)

Oto działający przykład: 122 121 114

122 do 121 bajtów: Zawijanie inicjalizacji w a

121 do 114 bajtów: bmusi to być ciąg znaków


2
Witamy w PPCG! Nie możesz usunąć definicji funkcji, ale zamiast tego możesz użyć funkcji lambda (nie znam JS, więc nie mogę ci w tym pomóc).
Pan Xcoder,

Dzięki za wyjaśnienie. Nie sądzę, że funkcje lambda mogą zapisać dowolne znaki, ale spróbuję. Ponadto, skoro powiesz „Dowolna rozsądna metoda / format wejścia / wyjścia jest dozwolona”, czy mogę zaakceptować ciąg jako bi zapisać b=''+b,?
Piyin

I udało się dostać do 115 bajtów, chociaż nie wiem 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]}.
Pan Xcoder,

1
Tak, pewnie wejście łańcucha byłoby w porządku
Mr. Xcoder,

Ale wymyślony JavaScript to ES5, a nie ES6. Odpowiedź ES6 jest już opublikowana, dlatego opublikowałem ES5. I dzięki za odpowiedź na drugie pytanie hehe
Piyin,


1

Jq 1,5 , 76 bajtów

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

Rozszerzony

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

Wypróbuj online!

Oto inne rozwiązanie o tej samej długości:

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

Rozszerzony

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

Wypróbuj online!


1

APL, 47 bajtów

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

Deklaruje anonimową funkcję, która pobiera dwa wektory, eliminuje duplikaty elementów, a następnie znajduje największy element na przecięciu wyników.

A←⍺i B←⍵przechowuj argumenty przekazane do funkcji w Ai B.

a=bzwraca wektor z 1 w każdym indeksie, w którym ajest równa b. Jeśli ajest skalarem (tj. Pojedynczą wielkością, a nie wektorem), to zwraca wektor z 1, gdziekolwiek element bjest, ai 0, gdy nie jest. Na przykład:

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

{+/⍵=A}: zagnieżdżona funkcja anonimowa; znajdź wystąpienia argumentu w wektorze Ai dodaj je, tj. znajdź liczbę wystąpień argumentu wA

1={+/⍵=A}¨A: zastosuj zagnieżdżoną funkcję anonimową do każdego elementu w A i znajdź te, które są równe 1, tj. unikalne elementy

((1={+/⍵=A}¨A)/A←⍺): po znalezieniu położenia unikalnych elementów wybierz tylko te elementy w oryginalnym wektorze (/ wybiera z prawego elementu argumentu, którego położenie odpowiada 1 w lewym argumencie)

R←((1={+/⍵=A}¨A)/A←⍺)∩(1={+/⍵=B}¨B)/B←⍵: powtórz proces dla drugiego argumentu; teraz, gdy mamy tylko unikalne elementy, znajdź przecięcie, tj. wspólne elementy i zapisz je w wektorzeR

R[⍒R]: dostęp do elementów Rw malejącej kolejności

1↑R[⍒R]: weź pierwszy element R po posortowaniu w malejącej kolejności

Przypadek testowy:

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 bajtów

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

Jak to działa:

Zaczynam od testowania, w którym dwie listy nakładają się na siebie =/(wstawia test równości między wszystkimi członkami list:

   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

Więcej niż jeden 1 w tej samej kolumnie oznacza, że ​​liczba nie jest unikalna dla lewego argumentu (w tym przypadku 6); w rzędzie - dla właściwego argumentu (3)

Następnie sumuję wszystkie wiersze i wszystkie kolumny, aby znaleźć, gdzie są duplikaty:

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

Znajduję iloczyn kartezjański z powyższych list i ustawiam członków na wartości większe niż 1 na 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

Maskuję macierz równości c za pomocą m, aby znaleźć unikalne elementy wspólne dla obu list i pomnożyć przez to lewy argument.

]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

Następnie spłaszczam listę i znajduję element max:

 >./,l 
4

Wypróbuj online!


1

C # (.NET Core) , 66 + 31 = 97 65 + 31 = 96 bajtów

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

Wypróbuj online!

+31 bajtów dla using System;using System.Linq;

Czerpałem inspirację z odpowiedzi @ aloisdg. Jednak zamiast szukać unikalnych wartości w obu tablicach, odwróciłem kolejność operacji, tak że intersectjest to pierwsza, a następnie znajduję maksymalną wartość elementów, które występują dwa razy, gdy tablice są konkatenowane i znajdują się na przecięciu. Mogę użyć <3jak Countbędzie co najmniej 2 dla dowolnej wartości, tak jak będzie w obu tablicach.

Podziękowanie

-1 bajt dzięki @aloisdg i jego sugestii używania Funccurry.


1
Dobry pomysł! Naprawdę to lubię
aloisdg mówi Przywróć Monikę



0

Oktawa , 57 56 bajtów

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

Anonimowa funkcja, która przyjmuje jako dane wejściowe tablicę komórek dwóch tablic numerycznych.

Wypróbuj online!

Wyjaśnienie

Dla każdej ( cellfun(@(x)...)) z dwóch tablic wejściowych tworzy to macierz porównań równości par pomiędzy jej wpisami ( x.'==x); utrzymuje ( x(...)) tylko wpisy, dla których suma kolumn to 1( sum(...)==1); i pakuje wynik do komórki ( {...}). Obliczane jest przecięcie ( intersect) dwóch wyników ( {:}) i max(...)przyjmowane jest maksimum ( ).


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.