Encontre os gêmeos únicos


28

Você será dado duas matrizes / Listas / vetores de inteiros não negativos A e B . Sua tarefa é a saída o mais alto número inteiro N que aparece em ambos A e B , e também é único em ambos A e B .


Casos de teste:

A, B -> Saída

[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

Respostas:


7

Geléia , 7 bytes

fċ@ÐṂ;Ṁ

Experimente online!

Como funciona

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 bytes

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

Obrigado a @seshoumara por jogar fora um byte!

Experimente online!

Como funciona

O uniq recebe entrada classificada e executa uma ou várias ações, dependendo dos sinalizadores da linha de comando.

U<<<$1e U<<<$2chame a função Ucom o primeiro e o segundo argumento da linha de comando como entrada. Para cada um, sort -rn|uniq -ué executado, classificando a entrada numericamente ( -n) e em ordem decrescente ( -r) para uniq , que imprimirá apenas linhas exclusivas ( -u).

A saída de ambos (elementos únicos de cada matriz) é concatenada e canalizada para U D, ou seja
sort -rn|uniq -uD,. Desta vez, o uniq imprimirá apenas linhas duplicadas ( -D) e apenas a primeira repetição de cada uma.

Enquanto a página do manual diz que imprimirá todas as repetições, as -ucausas adicionadas -Dimprimirão apenas a primeira ocorrência de linhas duplicadas. Esse comportamento é normalmente alcançado com uniq -d.

Por fim, sed qfecha imediatamente, reduzindo sua entrada (elementos exclusivos de ambas as matrizes) para sua primeira linha. Como a saída foi classificada em ordem decrescente, esse é o máximo.


6

Pitão, 12 9 bytes

Tente

eS@Fm.m/d

Economizou 3 bytes graças ao Sr. Xcoder.

Explicação

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.

Agradável! Minha solução também foi de 12 bytes .
Mr. Xcoder

Jogando golfe minha solução um pouco, 9 bytes (usando eS@Fm.m/d) e tendo entrada como uma lista de duas listas.
Xcoder

@ Mr.Xcoder Isso parece diferente o suficiente para ser sua própria resposta.

Como sou o OP do desafio, reluto em publicá-lo. Você pode apenas usá-lo e dar crédito, mencionando a sua abordagem atual como uma alternativa (se querem é claro)
Mr. Xcoder



5

Casca , 7 bytes

→►≠OfEΠ

Aceita entrada como uma lista de duas listas, também funciona para qualquer número de listas (retornando o número mais alto que ocorre exatamente uma vez em cada uma, se possível). Experimente online!

Explicação

Esta é a primeira resposta da Husk para (ab) usar a nova função "máximo por" .

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

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

Experimente Online

Bash, 89 bytes

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
Use sort -rncom sed qno final em vez de tail -1barbear 1 byte. Grande achado com grep -wfbtw. 1
seshoumara 4/11

@ Shaeshmara, obrigado pela dica, na verdade eu poderia raspar 3 bytes com a opção -m1 grep.
Nahuel Fouilleul 4/11


3

J, 23 bytes

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

(-.-.@~:#]) remove de uma lista quaisquer elementos repetidos

& faça isso com os dois argumentos

([-.-.) Queremos que A cruze B. Esta é a frase equivalente: "A menos (A menos B)"

>./ Pegue o máximo

Experimente online!


Equivalentemente, você pode substituir a peça de interseção por e.~#]. Golfe esta tem provado ser difícil ... Eu tentei usar /.tecla sem sucesso ( ((1=#)/.~#~.)para a primeira parte que é de 2 bytes mais por minha conta)
cole

@ cole, sim, eu tentei uma abordagem-chave também, e também uma com auto-classificação. Eu não fui capaz de superar minha submissão acima com qualquer outra abordagem.
Jonah #

2

PowerShell , 94 bytes

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

Experimente online!

Recebe entrada $ae $bcomo matrizes. Constrói a filterque groupé o conjunto de elementos da matriz de entrada e extrai apenas aqueles com um número count -eqpara 1(ou seja, apenas aqueles que são únicos na matriz de entrada).

A próxima linha então constrói o algoritmo. Primeiro nós sort $a, depois retiramos aqueles que são -inos itens únicos de $b. Esses são então eles mesmos únicos, o maior [-1]é escolhido e nós aceitamos o .Namemesmo. Isso é deixado no pipeline e a produção está implícita.


2

Javascript (ES6), 102 86 75 71 bytes

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

Obrigado @justinMariner por ir de 102 para 86

Obrigado @tsh por ter passado de 86 para 75

Obrigado @Arnauld por ir de 75 a 71

Experimente online!


Bem-vindo ao PPCG! Tanto quanto posso dizer, isso não garante que eapareça apenas uma vez em ae b.
Martin Ender

@MartinEnder Thanks! Editou a resposta para refletir os detalhes que eu perdi!
Nate

1
Eu nunca pensei em usar lastIndexOfassim, isso é muito inteligente. Você pode obter isso em 86 bytes: Experimente online! . Confira as dicas de JS para mais.
Justin Mariner

1
Parece que o uso (g=x=>x.filter(y=>y==e).length==1)é mais curto.
tsh

1
Eu acho que este também está passando todos os casos extremos (71 bytes).
precisa

2

Haskell , 57 53 bytes

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

Experimente online!

UPD: Obrigado @Laikoni


Bem-vindo ao PPCG e Haskell, em particular! Esta é uma boa primeira resposta! Duas pequenas coisas: Você também pode declarar fcomo operador de infixo e escrever em [1|...]==[1]vez de sum[1|...]==1salvar alguns bytes.
Laikoni 3/11

Caso você ainda não os tenha visto, aqui estão alguns links que podem ser interessantes: Nossa coleção de dicas de golfe em Haskell , o guia para regras de golfe em Haskell e Of Monads and Men , nossa sala de bate-papo em Haskell.
Laikoni

1
O alinhamento !com andeconomiza mais dois bytes: Experimente online!
Laikoni 3/11

2

Wolfram Language (Mathematica) , 40 bytes

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

Experimente online!

Como funciona

Tally@#fornece uma lista dos elementos únicos da primeira entrada, juntamente com suas contagens: por exemplo, Tally[{2,2,2,6,3,5,8,2}]rendimentos {{2,4},{6,1},{3,1},{5,1},{8,1}}.

Tally@#2faz o mesmo para a segunda lista e encontra pares presentes em ambos. Em seguida, selecionamos (com Cases) pares que terminam em 1, obtendo o primeiro elemento de cada resultado, o que nos dá uma lista de todos os gêmeos únicos. Finalmente, Maxretorna o maior gêmeo único.


2

Röda , 48 bytes

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

Experimente online!

Inspirado na resposta jq de jq170727 .

Explicação:

{ /* 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 bytes

115 114 bytes

Outra solução com countByesse tempo:

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

Experimente online!

117 111 bytes

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

Experimente online!

100% F #! Qualquer ajuda é bem vinda!

6 bytes ganhos graças à notação de prefixo!

108 bytes

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

@é a função concat! Obrigado @ Ayb4btu por este algoritmo.

Experimente online!



2

Pip , 17 16 bytes

MX{_Na=_Nb=1FIa}

Essa é uma função que recebe duas listas como argumentos. Experimente online!

Explicação

  {            }  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 caracteres = 23 bytes *

Um corpo completo do programa. Solicita a lista de listas do STDIN. Funciona com qualquer número de listas. Saídas para STDOUT.

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

Experimente online!

 prompt para entrada avaliada do STDIN

{...}⌸¨  Para cada lista, chame a seguinte função para cada elemento exclusivo dessa lista, usando o elemento exclusivo como argumento à esquerda ( ) e a lista de índices de sua ocorrência como argumento à direita ( ):

≢⍵ a contagem de índices (ou seja, o número de ocorrências)

1= igual a 1

⍺⍴⍨ use isso para remodelar o elemento específico (por exemplo, fornece lista vazia se não for exclusivo)

Agora, temos duas listas de elementos exclusivos para cada lista de entrada (embora cada elemento seja uma lista e existam listas vazias como resíduo dos elementos não exclusivos).

∩/ interseção (redução)

ϵ nlist (achatar)

⌈/ max (redução)


* no clássico, contando como ⎕U2338.


1

MATL , 13 bytes

,iSY'1=)]X&X>

Experimente online! Ou Verifique todos os casos de teste .

Explicação

,      % 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 bytes

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

Forneça matrizes como parâmetros GET ae b.


Pense que você poderia trocar esses parâmetros GET por constantes.
Progrock

@Progrock Esse não é um método de entrada válido.
Titus

A pergunta frases que A e B são dadas como matrizes. E diz qualquer método razoável de entrada e saída .... não que eu possa seguir esse link facilmente. Realmente gosto da sua receita. (Bobinas de choque em obsoleto Php 5,6 embora.)
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;}

Explicação:

Experimente aqui.

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

Experimente online!

Computações se Acruzam B, então o máximo da diferença entre isso e os elementos duplicados de Ae 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]}

Sou novo aqui, então não sei se consigo remover a definição da função e apenas colocar seu conteúdo (o que me salvaria 17 bytes)

Aqui está o exemplo de trabalho: 122 121 114

122 a 121 bytes: agrupando a inicialização em um para

121 a 114 bytes: bdeve ser uma sequência


2
Bem-vindo ao PPCG! Você não pode remover a definição da função, mas poderá usar uma função lambda (eu não conheço JS, então não posso ajudá-lo com isso).
Mr. Xcoder

Obrigado por esclarecer isso. Não acho que as funções lambda possam salvar caracteres, mas vou tentar. Além disso, como você diz "Qualquer método / formato razoável de entrada e saída é permitido", posso aceitar uma string como be salvar b=''+b,?
Piyin

Eu consegui chegar a 115 bytes, embora eu não sei 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]}.
Xcoder

1
Sim, com certeza uma string de entrada seria ótimo
Mr. Xcoder

Mas esse JavaScript que você criou seria o ES5, não o ES6. Uma resposta do ES6 já está publicada, e é por isso que eu publiquei o ES5. E obrigado por responder a segunda pergunta hehe
Piyin


1

Jq 1.5 , 76 bytes

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

Expandido

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

Experimente online!

Aqui está outra solução que tem o mesmo comprimento:

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

Expandido

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

Experimente online!


1

APL, 47 bytes

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

Declara uma função anônima que aceita dois vetores, elimina elementos duplicados e localiza o maior elemento na interseção dos resultados.

A←⍺e B←⍵armazene os argumentos passados ​​para a função em Ae B.

a=bretorna um vetor com 1 em cada índice no qual aé igual a b. Se afor um escalar (ou seja, quantidade única e não um vetor), ele retornará um vetor com 1 onde quer que o elemento besteja ae 0 quando não estiver. Por exemplo:

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

{+/⍵=A}: função anônima aninhada; encontre as ocorrências do argumento em vetor Ae some-as, ou seja, encontre o número de ocorrências do argumento emA

1={+/⍵=A}¨A: aplique a função anônima aninhada a cada elemento em A e encontre os que são iguais a 1, ou seja, elementos únicos

((1={+/⍵=A}¨A)/A←⍺): tendo encontrado a localização dos elementos exclusivos, selecione apenas esses elementos no vetor original (/ seleciona entre os elementos de argumento certos cujas localizações correspondem a 1 no argumento esquerdo)

R←((1={+/⍵=A}¨A)/A←⍺)∩(1={+/⍵=B}¨B)/B←⍵: repita o processo para o segundo argumento; agora que temos apenas os elementos únicos, encontre a interseção, ou seja, elementos comuns e armazene-a em vetorR

R[⍒R]: acessar os elementos de Rem ordem decrescente

1↑R[⍒R]: pegue o primeiro elemento de Rquando ele é classificado em ordem decrescente

Caso de teste:

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=*/)+/)@(=/)

Como funciona:

Começo com o teste, onde as duas listas se sobrepõem =/(insere o teste de igualdade entre todos os membros das listas:

   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

Mais de um 1 na mesma coluna significa que o número não é exclusivo para o argumento esquerdo (6 neste caso); na linha - para o argumento correto (3)

Em seguida, resuma todas as linhas e colunas para descobrir onde estão as duplicatas:

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

Encontro o produto cartesiano das listas acima e defino os membros com mais de 1 a 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

Mascarei a matriz de igualdade c com m para encontrar os elementos únicos comuns às duas listas e multiplico o argumento esquerdo por isso.

]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

Depois, aplico a lista e encontro o elemento max:

 >./,l 
4

Experimente 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()

Experimente online!

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

Eu me inspirei na resposta de @ aloisdg. No entanto, em vez de procurar valores exclusivos nas duas matrizes, inverti a ordem das operações para que ela intersectseja a primeira e depois localizei o valor máximo dos itens que ocorrem duas vezes quando as matrizes são concatenadas e estão interceptadas. Eu posso usar <3comoCount será pelo menos 2 para qualquer valor, como será nas duas matrizes.

Agradecimentos

-1 byte, graças a @aloisdg e sua sugestão de usar Funccurry.


1
Boa ideia! Eu realmente gosto disso
aloisdg diz Reinstate Monica 4/11



0

Oitava , 57 56 bytes

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

Função anônima que recebe como entrada uma matriz de células de duas matrizes numéricas.

Experimente online!

Explicação

Para cada ( cellfun(@(x)...)) das duas matrizes de entrada, isso cria uma matriz de comparações de igualdade entre pares entre suas entradas ( x.'==x); mantém ( x(...)) apenas as entradas para as quais a soma da coluna é 1( sum(...)==1); e empacota o resultado em uma célula ( {...}). A interseção ( intersect) dos dois resultados ( {:}) é calculada e o máximo ( max(...)) é obtido.


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.