imposta l'intersezione di due elenchi


10

Il tuo obiettivo è calcolare l'intersezione impostata di due elenchi di numeri interi. L'intersezione è definita come il gruppo univoco unico di numeri interi trovato almeno una volta in entrambi gli elenchi di input.

Ingresso

L'ingresso può essere in qualsiasi formato desiderato (parametro funzione, stdio, ecc.) Ed è costituito da due elenchi di numeri interi. Molti di voi non assumono nulla su ciascuna lista se non che possono contenere qualsiasi numero non negativo di numeri interi (cioè non sono ordinati, possono contenere duplicati, possono avere lunghezze diverse e possono anche essere vuoti). Si presume che ciascun numero intero si adatterà al tipo intero con segno nativo della tua lingua, può essere lungo più di 1 cifra decimale e viene firmato.

Esempio di input:

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

Produzione

L'output è qualsiasi elenco di numeri interi che rappresentano l'intersezione impostata delle due liste in qualsiasi formato desiderato (valore di ritorno, stdio, ecc.). Non è necessario che l'output sia ordinato, anche se sei il benvenuto a fornire un'implementazione che risulta essere sempre ordinata. L'output deve formare un set valido non ordinato (ad es. Non deve contenere valori duplicati).

Esempi di test (si noti che l'ordine dell'output non è importante):

Le prime due righe sono gli elenchi di input, la terza riga è l'output. (empty)indica l'elenco vuoto.

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

punteggio

Questo è il codice golf; vince la risposta più breve in byte.

Sono vietati i fori standard. È possibile utilizzare qualsiasi funzionalità integrata non progettata per operazioni simili a set.

Funzioni incorporate vietate:

  • imposta la creazione / rimozione dei duplicati
  • imposta la differenza / intersezione / unione
  • Test di appartenenza generalizzati (ad es. Qualcosa di simile alla inparola chiave in Python, indexOffunzioni simili, ecc.). Si noti che è consentito l'uso dei costrutti "foreach item in list" (supponendo che non violino nessuna delle altre restrizioni), nonostante Python riutilizzi la inparola chiave per creare questo costrutto.
  • Questi built-in vietati sono "virali", ovvero se esiste un built-in più grande contenente una di queste funzionalità secondarie, è similmente vietato (ad esempio, filtraggio in base a un abbonamento in un elenco).

Sono consentiti tutti i componenti incorporati non presenti nell'elenco precedente (ad es. Ordinamento, test di uguaglianza di numeri interi, aggiunta / rimozione di elenchi per indice, filtro, ecc.).

Ad esempio, prendi i seguenti due frammenti di esempio (codice simile a 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)

Puoi implementare tu stesso una qualsiasi di queste funzioni simili a un set e queste verranno conteggiate ai fini del tuo punteggio.

La tua soluzione dovrebbe essere completata in un ragionevole lasso di tempo (diciamo, meno di un minuto su qualunque hardware tu abbia per due liste ~ lunghezza 1000 ciascuna).


5
A proposito, confusione e cattiva comunicazione sono comuni nel do X senza Y , motivo per cui sono ufficialmente una delle cose da evitare quando si scrivono sfide .
Dennis,

2
@Dennis Sì, immagino che questo problema sia diventato davvero uno di quelli :( Quando l'ho scritto per la prima volta, speravo che potesse essere un problema interessante, ma non appena ho iniziato a elaborare un set di regole avrei dovuto semplicemente uccidere la sfida.
helloworld922,

È consentito un builtin che esegue la codifica della lunghezza di esecuzione?
Isaacg

Questo dovrebbe andare bene.
helloworld922,

1
Possono esserci duplicati nell'output?
Adám,

Risposte:



4

MATL , 18 byte

YY_iti!=Xa)hStdfQ)

Provalo online!

Funziona in due passaggi. Innanzitutto viene calcolata l'intersezione, possibilmente con duplicati. Questo si basa sul confronto di tutti gli elementi di un array con tutti gli elementi dell'altro e sul mantenimento degli elementi del primo presenti nel secondo.

Quindi i duplicati vengono rimossi. Per questo, l'array del passaggio precedente viene ordinato e le voci vengono mantenute se diverse dal precedente. Un -infvalore viene anteposto in modo tale da non perdere il primo (ovvero il valore più basso).

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

Gelatina, 13 byte

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

Provalo online!

Come funziona

Ṃ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 Risolto ora.
Dennis,

3

golflua , 68 caratteri

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

che si chiama come

> 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

In Lua normale, questo sarebbe

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

Quindi sostanzialmente sto iterando su ciascun elemento delle due tabelle e memorizzando solo i valori equivalenti. Usando il valore come chiave ( k[w]=w), sto eliminando tutti i duplicati. Abbiamo quindi generato la nuova tabella ripetendo l' indice e il valore dipairs


3

JavaScript (ES6), 66 byte

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

Senza usare indexOf, poiché non sono convinto che sia permesso.


3

Pyth, 12 11 byte

eMrSsq#RQE8

Dimostrazione

Spiegazione:

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.

L'ordinamento e il salvataggio salvano un byte.
Jakube

@Jakube Direi che rle è un builtin che rimuove i duplicati.
Isaacg,

Rimuove i duplicati solo se lo ordini prima e rimuovi i conteggi delle regole in seguito. È un po 'in una zona grigia, ma penso che lo sia anche usando un dizionario. È fondamentalmente un set che memorizza dati aggiuntivi per ciascun elemento.
Jakube

@Jakube OP dice che va bene. Grazie!
Isaacg

2

bash + GNU coreutils, 184 byte

[ -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")

Invocazione:

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

Produzione:

4
56
3

Nessun output se l'intersezione è vuota. Questo script non ordina e verifica la sanità mentale se il primo set è vuoto. Spiegazione:

[ -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).

Bonus da sapere: è possibile cambiare grep -o .per farlo con stringhe casuali anziché numeri.


2

Perl 6, 26 37 byte

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

uso

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

Sfacciata risposta non competitiva

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

o se ti piace in una noiosa ffunzione

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

Ho aggiornato la mia risposta per non usare .unique
Hotkeys

1
Non hai davvero bisogno invertse prendi invece i valori. 24 byte
Jo King

2

Retina , 63 byte

Le ultime due righe rimuovono i duplicati. L'input è costituito da due elenchi delimitati da spazi separati da una virgola. L'output è delimitato da spazi bianchi.

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

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

Provalo online

Se sono consentiti duplicati nell'output, il mio programma sarebbe di 42 byte.


2

Jq 1,5 , 99 byte

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

allargato

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
;

Questo evita di usare {}oggetti e poiché jq non ha operazioni a bit, questo li emula con un array.

Provalo online!


2

Assioma, 411 byte

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)

ungolf e prova

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

Assioma, 257 byte

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)

Questo senza l'uso di binsearch ... Ma non conosco la grande O ... Unglofed e risultati:

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

Non sono stati eseguiti molti test, quindi potrebbe essere corretto ...


2

Gelatina , 12 byte

pEÐfḢ€ĠḢ€$ị$

Provalo online!


In Tio 3,1,2,4,3,1,1,1,1,3 input e 3 input restituiscono output [1,2,3] anziché [3]
RosLuP

@RosLuP Prova [3]invece di3
HyperNeutrino il

Sarebbe ok secondo me, se il risultato dell'intersezione di 2 liste ritorni (come altri casi) [] se il risultato è impostato su vuoto, [1] se 2 liste hanno 1 in comune
RosLuP

@RosLuP Non posso farne a meno, è così che esce Jelly. Vuoto per []e l'elemento per le liste singleton. Puoi andare alla pagina wiki (atomi) e aggiungere l'integrato di Python Stringify ma ciò rende la mia risposta più lunga e l'I / O rigoroso è stupido
HyperNeutrino

Sarebbe ok per me se accettasse solo input List in [] way (esempio [1], [1,2,3] [], [], [] etc) e output dell'elenco output solo in modo List [] (come input). Se le parentesi per elenco sono {} o (), ripeti il ​​discorso sopra per quello giusto. Questo è solo per quello che penso, la domanda forse dice diversamente e tutto va bene
RosLuP

2

Buccia , 9 byte

mo←←kIfE*

Provalo online!

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.

Guardando il codice sorgente di Husk su GitHub, k("keyon") è implementato come la composizione dell'ordinamento e del raggruppamento dei valori adiacenti, quindi anche se non riesco a trovare l'implementazione di "groupOn" è probabilmente sicuro che non lo faccia ' fare qualcosa di tranquillo, dato che Haskell è un linguaggio funzionale e raggruppare valori uguali adiacenti è un'operazione piuttosto semplice di riduzione su una lista collegata. (I riesco a trovare la realizzazione di k's altro tipo di firma 'keyby', che ho potuto usare qui cambiando Ia =, ma non so Haskell quindi non posso dire esattamente come funziona.)

Inoltre, ho avuto una bella risposta a Brachylog che mi è venuta in mente prima che mi rendessi conto che le operazioni sul set di tutti i tipi erano vietate: ⟨∋∈⟩ᵘ


2

R, 141 83 byte

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

Migliorato da Giuseppe

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

Prova online Qui Qui


Questo non sembra funzionare. Probabilmente sto provando a usarlo male, quindi forse dovresti fornire un link per provarlo online! mostrando come usarlo e dimostrando che soddisfa i requisiti della sfida. (Una spiegazione sulla risposta non farebbe male.)
Unrelated String

non puoi assumere input ae bsono predefiniti, devi accettare input, prendendoli come argomenti di funzione o da STDIN.
Giuseppe,

1
Penso che il golfista sarebbe solo per rendere questa una funzione, come questa
Giuseppe

1
@db L '"intestazione" nomina la funzione anonima definita nella sezione "Codice" (le funzioni anonime sono perfettamente accettabili) e quindi il piè di pagina la chiama. Le sezioni Header, Code e Footer sono tutte un pezzo di codice, ma solo la parte nella sezione "code" conta per byte :-)
Giuseppe

1

Python3, 51 byte

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

Se gli elenchi di input possono contenere duplicati:

Python3, 67 byte

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

1

PHP ,78, 77 byte

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

Provalo online!

Niente fronzoli, ma conforme alle regole (credo).

Produzione

[], []
[]

[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]
[]
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.