встановити перетин двох списків


10

Ваша мета - обчислити заданий перетин двох списків цілих чисел. Перетин визначається як унікальна не упорядкована група цілих чисел, що зустрічаються принаймні один раз в обох вхідних списках.

Вхідні дані

Вхід може бути у будь-якому бажаному форматі (параметр функції, stdio тощо) і складається з двох списків цілих чисел. Ви багато хто не припускає нічого про кожен список, окрім того, що він може містити будь-яке невід'ємне число цілих чисел (тобто вони несортовані, можливо, можуть містити дублікати, можуть мати різну довжину і навіть можуть бути порожніми). Передбачається, що кожне ціле число відповідатиме вашому мовному цілому цілому типу, підписаному вашою мовою, може бути довше однієї десяткової цифри та підписано.

Приклад введення:

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

Вихідні дані

Вихід - це будь-яке ціле число списків цілих чисел, що представляють заданий перетин двох списків до будь-якого потрібного формату (повернене значення, stdio тощо). Немає вимоги сортувати вихід, хоча ви можете запропонувати реалізацію, яка, як правило, завжди буде сортована. Вихід повинен утворювати дійсний не упорядкований набір (наприклад, він не повинен містити жодних повторюваних значень).

Приклади тестових випадків (зауважте, що порядок виводу не важливий):

Перші два рядки - це вхідні списки, третій - вихідний. (empty)позначає порожній список.

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

Оцінка балів

Це код гольфу; найкоротша відповідь у байтах виграє.

Стандартні отвори в петлях заборонені. Ви можете використовувати будь-які вбудовані функції, не розроблені для операцій із встановленим набором.

Заборонені вбудовані функції:

  • встановити створення / видалення дублікатів
  • встановити різницю / перехрестя / з'єднання
  • Узагальнене тестування членства (наприклад, що-небудь схоже на inключове слово в Python, indexOf-подобні функції тощо). Зауважте, що використання конструкцій "елемент foreach у списку" дозволено (якщо припустити, що вони не порушують жодного з інших обмежень), незважаючи на те, що Python повторно використовує inключове слово для створення цієї конструкції.
  • Ці заборонені вбудовані програми є "вірусними", тобто якщо є більший вбудований вміст, який містить будь-яку з цих підфункцій, аналогічно заборонено (наприклад, фільтрування за членством у списку).

Будь-які вбудовані програми, які не є у наведеному вище списку, дозволені (наприклад, сортування, ціле тестування рівності, додавання / видалення списку за індексом, фільтрування тощо).

Наприклад, візьміть наступні два приклади фрагментів (подібний 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)

Ви можете самостійно реалізувати будь-яку з цих функцій, і вони враховуватимуть ваш результат.

Ваше рішення має завершитись за розумну кількість часу (скажімо, менше ніж хвилини для будь-якого обладнання, яке ви маєте для двох списків ~ довжиною 1000 кожен).


5
До речі, плутанина та неправильна комунікація звичайні в X без Y , тому офіційно вони є одне, чого слід уникати під час написання викликів .
Денніс

2
@Dennis Так, я думаю, ця проблема справді стала однією з таких :( Коли я вперше написав це, я сподівався, що це може бути цікавою проблемою, але як тільки я почав розробляти набір правил, я повинен був просто вбити проблему.
helloworld922

Чи дозволено вбудований, який виконує кодування довжини запуску?
isaacg

Це повинно бути добре.
helloworld922

1
Чи можуть бути дублікати у висновку?
Адам

Відповіді:



4

MATL , 18 байт

YY_iti!=Xa)hStdfQ)

Спробуйте в Інтернеті!

Це працює в два етапи. Спочатку перетин обчислюється, можливо, з дублікатами. Це ґрунтується на порівнянні всіх елементів одного масиву з усіма елементами іншого та збереженні елементів першого, які присутні у другому.

Потім дублікати видаляються. Для цього масив з попереднього кроку сортується, а записи зберігаються, якщо вони відрізняються від попереднього. -infЗначення передує таким чином , що перший (тобто найнижче) значення не втрачається.

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

Желе, 13 байт

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

Спробуйте в Інтернеті!

Як це працює

Ṃ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 Виправлено зараз.
Денніс

3

гольфлуа , 68 чарів

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

який називається як

> 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

У звичайному Луа це було б

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

Так що в основному я повторюю кожен елемент двох таблиць і зберігаю лише еквівалентні значення. Використовуючи значення як ключ ( k[w]=w), я усуваю всі дублікати. Потім виводимо нову таблицю шляхом повторення індексу та значенняpairs


3

JavaScript (ES6), 66 байт

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

Без використання indexOf, оскільки я не переконаний, що це дозволено.


3

Pyth, 12 11 байт

eMrSsq#RQE8

Демонстрація

Пояснення:

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.

Сортування та rle економить один байт.
Якубе

@Jakube Я б сказав, що rle - це вбудований модуль, який видаляє дублікати.
isaacg

Він видаляє дублікати лише в тому випадку, якщо ви їх сортуєте до цього та видаляєте підрахунки часу після цього. Це трохи в сірій області, але я вважаю, що це використання словника. Це в основному набір, який зберігає додаткові дані для кожного елемента.
Якубе

@Jakube OP каже, що це добре. Дякую!
isaacg

2

bash + GNU coreutils, 184 байт

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

Виклик:

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

Вихід:

4
56
3

Виходу немає, якщо перехрестя порожнє. Цей сценарій не сортує і не перевіряє, чи не встановлено перший набір порожній. Пояснення:

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

Бонус знати: Ви можете змінити grep -o .це на випадкових рядках замість чисел.


2

Perl 6, 26 37 байт

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

використання

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

Хитра відповідь, що не конкурує

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

або якщо вам це подобається у нудній ol ' fфункції

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

Я оновив свою відповідь, щоб не використовувати .unique
Hotkeys

1
Вам не дуже потрібно, invertякщо ви замість цього приймаєте значення. 24 байти
Jo King

2

Сітківка , 63 байти

Останні два рядки видаляють дублікати. Вхід - це два списки з обмеженим пробілом, розділені комою. Вихід обмежений пробілом.

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

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

Спробуйте в Інтернеті

Якщо дозволені копії у висновку, моя програма складе 42 байти.


2

Jq 1,5 , 99 байт

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

Розширено

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
;

Це уникає використання {} об'єктів, і оскільки jq не має бітових операцій, це імітує їх масивом.

Спробуйте в Інтернеті!


2

Аксіома, 411 байт

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 і тест

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

Аксіома, 257 байт

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)

Це без використання binsearch ... Але я не знаю великих O ... Unglofed та результати:

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

Не виконано багато тестів, тому можна помилитися ...


2

Желе , 12 байт

pEÐfḢ€ĠḢ€$ị$

Спробуйте в Інтернеті!


У Tio 3,1,2,4,3,1,1,1,1,3 вхід і 3 вхід повертають вихід [1,2,3] замість [3]
RosLuP

@RosLuP Спробуйте [3]замість3
HyperNeutrino

На мою думку, було б нормально, якщо результат перетину двох списків повернеться (як і інші випадки) [], якщо результат визнано недійсним, [1] якщо 2 списку мають 1 спільне
RosLuP

@RosLuP Я не можу в цьому допомогти, ось як Jelly робить вихід. Порожня для []та елемент для одиночних списків. Ви можете перейти на сторінку вікі (атоми) та додати вбудований Python Stringify, але це робить мою відповідь довшою і суворою введення / виведення є німим
HyperNeutrino

Для мене було б нормально, якщо він приймає лише список вводу [] способом (приклад [1], [1,2,3] [], [], [] тощо) і виводить вихідний список лише у спосіб [Список] (як її вхід). Якщо в дужках для списку є {} або (), повторіть вище промову для правильної. Це лише те, що я думаю, питання, можливо, сказати інакше, і все нормально
RosLuP

2

Лушпиння , 9 байт

mo←←kIfE*

Спробуйте в Інтернеті!

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.

Дивлячись на вихідний код Husk на GitHub, k("keyon") реалізований як композиція сортування списку та групування суміжних значень, тому хоча я реально не можу знайти реалізацію "groupOn", можливо, можна припустити, що вона не є ' не робити нічого складного, оскільки Haskell - це функціональна мова, а групування суміжних рівних значень є досить простою операцією зменшення переліку зв’язаного списку. (Я можу знайти реалізацію kпідпису іншого типу "keyby", яку я міг би використати тут, перейшовши Iна= , але я не знаю Haskell , так що я не можу сказати , як саме це працює.)

Крім того, приємна маленька відповідь Брахілога, яку я придумав ще до того, як зрозумів, що всі види операцій заборонені: ⟨∋∈⟩ᵘ


2

R, 141 83 байти

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

Удосконалено Джузеппе

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

Спробуйте в Інтернеті тут тут


Це, здається, не працює. Я, мабуть, намагаюся неправильно використовувати його, тому, можливо, вам слід надати посилання, щоб спробувати його в Інтернеті! показуючи, як ним користуватися, і демонструючи, що він відповідає вимогам завдання. (Пояснення у відповіді теж не зашкодить.)
Непов’язаний рядок

ви не можете приймати входи aта bпопередньо визначені, ви повинні приймати введення, приймаючи їх як аргументи функції або від STDIN.
Джузеппе

1
Я думаю, що гравцю було б просто зробити цю функцію, як це
Джузеппе

1
@db "Заголовок" називає анонімну функцію, визначену в розділі "Код" (анонімні функції цілком прийнятні), а нижній колонтитул викликає її. Розділи заголовка, коду та нижнього колонтитулу - це цілий фрагмент коду, але лише частина в розділі "код" нараховує байти :-)
Джузеппе

1

Python3, 51 байт

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

Якщо вхідні списки можуть містити дублікати:

Python3, 67 байт

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

1

PHP ,78, 77 байт

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

Спробуйте в Інтернеті!

Без надмірностей, але відповідних правилам (я думаю).

Вихідні дані

[], []
[]

[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]
[]
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.