Все неупорядоченные пары между элементами массива

11

Задача:

Вернуть массив со всеми возможными парами между элементами массива.

пример

От a=["a", "b", "c", "d"];возвращения b=[["a","b"],["a","c"],["a","d"],["b","c"],["b","d"],["c","d"]].

Пары могут быть в любом порядке, если включены все возможные комбинации и, очевидно ["b","d"], то же самое ["d","b"].

вход

Массив уникальных строковых элементов, состоящих из символов из класса [a-z].

Выход

2d массив, содержащий все возможные пары элементов входного массива.

Тестовые случаи

input=["a","b","c"];
//output=[["a","b"],["a","c"],["b","c"]]

input=["a","b","c","d","e"];
//output=[["a","b"],["a","c"],["a","d"],["a","e"],["b","c"],["b","d"],["b","e"],["c","d"],["c","e"],["d","e"]]

Примечание: я не смог найти дубликат для этой задачи. Если есть, сообщите мне с комментарием, чтобы оставить вопрос.

alexandros84
источник
2
Мне не ясно, что происходит, когда входные значения повторяются или находятся не в отсортированном порядке. Там помогут несколько более общих тестовых случаев.
xnor
@ Adám Не дурак, который включает в себя 2 списка.
г-н Xcoder
Эта проблема исключает спаривание элемента с самим собой, даже более не дублирующееся.
CalculatorFeline
@xnor не думал о повторении ценностей, потому что моя первоначальная проблема на работе была связана с уникальным набором людей. Я думаю, я должен добавить уникальность в качестве условия?
alexandros84
@ alexandros84 Уникальность будет в порядке. Что должно ["c","b","a"]вернуться?
xnor

Ответы:

5

Желе , 2 байта

Œc

Попробуйте онлайн!

HyperNeutrino
источник
Вы ниндзя меня - просто распечатайте вывод, используя что-то вроде нижнего ÇK€Yколонтитула.
Джонатан Аллан
@JonathanAllan О, спасибо!
HyperNeutrino
8

Haskell , 29 байт

f(a:b)=map((,)a)b++f b
f _=[]

Попробуйте онлайн! Пример использования: f ["a","b","c"]доходность [("a","b"),("a","c"),("b","c")].


С помощью флага -XTupleSectionsэто можно сократить до 27 байтов, однако этот флаг необходимо будет посчитать:

f(a:b)=map(a,)b++f b
f _=[]

Попробуйте онлайн!

Laikoni
источник
Я думаю, что вы можете сохранить один байт, изменив регистр be на f l=l.
Kritzefitz
@Kritzefitz Боюсь, это не сработает, так как два пустых списка имеют разные типы, поэтому программа проверки типов в Haskell будет жаловаться.
Лайкони
Хорошая точка зрения. Я не думал об этом.
Kritzefitz
6

Mathematica, 14 байтов

#~Subsets~{2}&

вход

[{"a", "b", "c"}]

J42161217
источник
Я собирался сделать это :(
CalculatorFeline
5

vim, 50 48

AX<esc>qqYplX@qq@qqrYpllDkxh@rq:g/./norm@r<cr>:g/X/d<cr>dG

Принимает вход в виде

abcd

и выводит как

ad
ac
ab
bd
bc
cd

объяснение

Сначала AX<esc>добавляется Xк входу, чтобы обрабатывать ввод 2-длины, что необходимо по причинам, которые вскоре станут понятны.

Затем идет первый рекурсивный макрос вида qq...@qq@q. (Запишите макрос q, запустите себя снова в конце, завершите запись, затем запустите сам один раз.) В теле макроса Ypдублируется текущая строка, lвыделяется макрос, если строка теперь имеет длину один символ, и Xудаляет первый символ в строке. Это имеет конечный результат производства

abcdX
abcX
abX
aX
X
X

XПока игнорируем s, все, что нам нужно сделать, это abcdX, например, превратиться в ab / ac / ad / aX. Это достигается с помощью второго рекурсивного макроса qr...@rq.

В этом макросе мы сначала дублируем строку ( Yp), затем удаляем все, кроме первых двух символов, перемещая вправо two ( ll) и удаляя до конца строки ( D). Так как курсор теперь находится на втором символе строки, kxбудет удален второй символ из предыдущей строки, который оказался тем, который был просто связан с первым символом в строке. Затем этот процесс повторяется, начиная с начала строки ( h) столько раз, сколько необходимо из-за рекурсивной природы макроса.

Теперь это просто вопрос запуска макроса в каждой строке, что может быть достигнуто с помощью :g/./norm@r(я не уверен, почему это ведет себя иначе, чем :%norm@r, но достаточно сказать, что последний работает не так, как задумано). Строки с Xудаляются с помощью :g/X/d, и пустые строки в конце слева в результате построения rмакроса очищаются dG.

Дверная ручка
источник
Отличный ответ. Мне потребуется время, чтобы пройти через это.
alexandros84
3

Python, 53 байта

2 байта сохранены благодаря @CalculatorFeline

lambda a:[(x,y)for i,x in enumerate(a)for y in a[:i]]

Попробуйте онлайн!

Уриэль
источник
1
a[i+1:]можноa[:i]
CalculatorFeline
Наличие длинного имени пользователя облегчает короткие комментарии, просто упоминая вышеупомянутого пользователя.
CalculatorFeline
3

Октава , 49 48 байтов

@(x)[imag(y=(y=triu(x+j*x',1))(~~y)) real(y) '']

Анонимная функция, которая избегает встроенной функции ( nchoosek).

Попробуйте онлайн!

объяснение

x+j*x'использует широковещательную передачу для построения матрицы комплексных чисел, где действительная и мнимая части - это все пары кодовых точек из входных данных x.

y=triu(...,1)сохраняет верхнюю треугольную часть, исключая диагональ, оставляя остальные элементы равными нулю. Результат присваивается переменной y.

y=(...)(~~y)сохраняет ненулевые элементы в форме вектора столбца, который назначается переменной y.

imag(...)и real(...)извлечь реальные и мнимые части.

[... ... ''] преобразует обратно в символ для построения вывода.

Луис Мендо
источник
Ницца! Весь вызов действительно интересный. Мне потребовалось около полутора часов, чтобы придумать код es5 (показанный ниже). Я счастлив, что это вызвало столько интересных ответов ..
alexandros84
2

Python ≥ 2.7, 55 байт

lambda l:list(combinations(l,2))
from itertools import*

repl.it!

Мистер Xcoder
источник
2

Perl 6 , 17 байт

*.combinations(2)

Вот так, это длинное имя метода.

Шон
источник
2

Pyth , 7 4 байта

-3 байта благодаря Лики Нун !

.cQ2

Попробуйте онлайн!

notjagan
источник
1
.cQ2?
Утренняя монахиня
@LeakyNun Я мог поклясться, что была функция, которая выполняла именно то, что нужно для этой задачи, но я видел это только .Cпри просмотре списка. Хорошо поймал!
notjagan
2

Рубин , 38 34 24 байта

->x{[*x.combination(2)]}

Спасибо Seims за идею, которая сэкономила 10 байтов.

Попробуйте онлайн!

гигабайт
источник
1
->x{x.combination(2).to_a}сохраняет некоторые байты :)
Seims
1

JavaScript ES6, 52 байта

a=>a.map((x,i)=>a.slice(0,i).map(y=>[x,y])).slice(1)

Если бы было flatMapчто-то подобное , это сэкономило бы много байтов.

Downgoat
источник
Эй, хороший ответ! проверьте мой ответ es5, пока я изучаю ваш, если хотите. любая обратная связь будет оценена (позитивно / конструктивно хаха)
alexandros84
1
Массивы в Firefox 30 могут имитировать плоскую карту, например a=>[for(x of[...a])for(y of(a.shift(),a))[x,y]].
Нил
@ Нейл, там есть действительно продвинутый синтаксис ... Мне нужно по крайней мере три вещи, чтобы понять ваше выражение. А именно, оператор распространения, что такое массивы и что такое [x, y] в конце (до сих пор не нашли ответа на этот вопрос).
alexandros84
1
@ alexandros84 В [x,y]конце это просто, это просто массив букв.
Нил
1
Кроме того, оператор распространения существует только для копирования массива, поскольку я изменяю его внутри цикла.
Нил
1

Python , 55 байт

f=lambda s:[(s[0],j)for j in s[1:]]+f(s[1:])if s else[]

Попробуйте онлайн!

Дольше, чем другие ответы Python, но он использует другую технику, поэтому я думаю, что это стоит опубликовать.

musicman523
источник
У меня нет времени, чтобы проверить, я надеюсь, что это действительно другая техника, потому что я проголосовал.
alexandros84
Я думаю, что это очень похожий подход к ответу @ ovs на Python 3.
Нил
1

Python, 64 байта

f=lambda a:sum((list(zip(a, a[i:]))for i in range(1,len(a))),[])
Джоэл Корнетт
источник
1

Clojure, 42 байта

#(set(for[i % j(remove #{i}%)](set[i j])))

Возвращает набор наборов :)

NikoNyrh
источник
1

Python, 74 байта

f=lambda a:[(c,d) for i,c in enumerate(a) for j,d in enumerate(a) if i<j]
Орен
источник
1
Добро пожаловать в PPCG! Вы можете изменить это следующим образом: 1) заменить 2-символьные имена переменных на 1-символьные 2) удалить ненужные пробелы 3) это фрагмент, вам нужно превратить его в лямбду, функцию или полную программу
Erik the Outgolfer
Гольф от 10 байтов: 64 байта
г-н Xcoder
1

Javascript (ES 5), от 108 до 78 байт

Я публикую свой ответ сегодня, но, очевидно, обещаю не принимать мой собственный ответ:

x=input;
a=[];

for(n=0;n<(x.length-1);n++){for(i=n+1;i<(x.length);i++){a.push([x[n],x[i]]);}}
alexandros84
источник
1
Добро пожаловать в PPCG; мы ожидаем , что материалы будут golfed, включая удаление ненужных пробелов
HyperNeutrino
Ty. Мне было интересно также следующее: я должен был включить x = input; а = []; в моем ответе или нет? Я отредактирую завтра.
alexandros84
Вы можете просто отправить функцию или выполнить полную программу. Поскольку вы используете a, вам нужно определить его, но вы можете сделать функцию x.
HyperNeutrino
намного лучше, теперь @HyperNeutrino.
alexandros84
1
Я думаю, что вы можете исключить несколько точек с запятой и пустую строку, чтобы сэкономить место. Я также думаю, что вы можете изменить for(i=n+1;i<(x.length);i++)на for(i=n;++i<x.length;). Кроме того, вы можете изменить n<(x.length-1);n++наn++<x.length-1
musicman523
0

J , 17 байт

({~$#:I.@,)#\</#\

Попробуйте онлайн!

объяснение

({~$#:I.@,)#\</#\  Input: string S
               #\  Get the length of each prefix of S
           #\      Get the length of each prefix of S again
             </    Test using greater than (<) between each
         ,         Flatten
      I.@          Find the indices where the value is 1
   $               Shape of that table
    #:             Convert the indices to the base represented by the shape
 {~                Index into S at those values
миль
источник