Код-Гольф: перестановки

21

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

Питон (95 символов) :

p=lambda s:s and sum(map(lambda e:map(lambda p:[e]+p,p(filter(lambda x:x!=e,s))),s),[]) or [[]]

Было бы неплохо быть побежденным на одном языке, но реализации на других языках приветствуются!

zxul767
источник

Ответы:

10

Питон - 76 символов

Дольше, чем у Гнибблера, но реализует вещи с нуля.

p=lambda x:x and[[a]+b for a in x for b in p([c for c in x if c!=a])]or[[]]
ugoren
источник
Мне нравится использование здесь пониманий. Это действительно упрощает код, который я опубликовал!
zxul767
9

J, 11 символов

(i.@!@#A.[)

Использование:

   (i.@!@#A.[) 1 3 5
1 3 5
1 5 3
3 1 5
3 5 1
5 1 3
5 3 1

Объяснение:

i.@!@# использует три глагола, чтобы вернуть список от 0 до (! n) -1, где n - количество элементов в данном списке.

[возвращает сам список. В примере показано, что дает 0 1 2 3 4 5 A. 1 3 5.

A.возвращает одну возможную перестановку второго списка для каждого элемента в первом списке (вид - здесь дано правильное объяснение ).

Gareth
источник
Предоставить ссылку на информацию о J?
Спарр
1
@Sparr На сайте J есть несколько хороших руководств - изучение J и J для программистов на C - и страница, охватывающая словарный запас .
Гарет
8

Питон - 55 символов

from itertools import*
p=lambda x:list(permutations(x))
gnibbler
источник
Не совсем то, на что я надеялся, что люди напишут ... но полезно знать, что Python имеет такие утилиты в стандартной библиотеке.
zxul767
4
@ zxul767: зачем изобретать велосипед? Использование стандартной библиотеки окажется невероятно эффективным ... (и в этом случае делает лаконичный код при игре в гольф ;-)
ChristopheD
8

Хаскелл, 44 43

p[]=[[]]
p l=[e:r|e<-l,r<-p$filter(/=e)l]

По сути, это то же самое, что и решение Угорена, но Хаскелл лучше разбирается в списках!


Конечно, это также может сделать

30

import Data.List
p=permutations


Более эффективный подход, который не требует сравнения на равенство:

92

import Data.List
p[]=[[]]
p l=(\(l,(e:r))->map(e:)$p(l++r))=<<(init$zip(inits l)(tails l))

Как следствие, этот также работает, когда в списке есть повторяющиеся элементы.

перестал поворачиваться против часовой стрелки
источник
4
Самое приятное в этом то, что 44-х строчное решение haskell с пониманием списка короче, чем решение на python, которое просто использует стандартную библиотеку.
монадический
p=Data.List.permutations, Хотя это похоже на обман. Также,Data.List.permutations не выводит перестановки в лексикографическом порядке.
Джон Дворак,
1
p[]=[[]]Вместо этого вы можете написать в качестве базового варианта, сохранив два байта.
Линн
@ Маурис: правильно! Я почему-то предположил, что пустой список будет иметь нулевую перестановку по определению, но с 0! = 1 это явно не имеет никакого смысла. Наличие пустого базового варианта намного приятнее.
перестал поворачиваться против часовой стрелки с
3

в Q (48)

g:{$[x=1;y;raze .z.s[x-1;y]{x,/:y except x}\:y]}

Пример использования:

q)g[3;1 2 3]
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
sinedcm
источник
2

Рубин - 23 символа

f=->x{p *x.permutation}

например f[[1,2,3]] выводит это .

но использование [].permutationпохоже на обман, поэтому:

Рубин - 59 символов

f=->a{a.size<2?[a]:a.flat_map{|x|f[(a-x=[x])].map{|y|x+y}}}

проверено с

100.times.all?{arr=(1..99).to_a.sample(rand(5)); arr.permutation.to_a==f[arr]}
=> true
jsvnm
источник
Если вы хотите, вы можете продемонстрировать свой код, используя такой сайт, как IdeOne: ideone.com/crvtD
Мистер Лама
1
Почему использование встроенных языковых функций было бы обманом?
Марк Томас
@ Марк, возможно, не обманывает, но не доставляет особого удовольствия написать функцию, которая просто вызывает встроенную функцию. Как например: «написать функцию для сортировки массива» ->f(array) { return array.sort(); }
jsvnm
2

Питон - 58 символов

Чуть короче, чем у Угорена, взяв набор в качестве входных данных:

p=lambda x:x and[[y]+l for y in x for l in p(x-{y})]or[[]]
Жюль Оллеон
источник
2

C, 270 243 239 символов

#define S t=*a;*a=a[i];a[i]=t;
#define R o=p(n,r-1,a+1,o,r-2,0)
int*p(n,r,a,o,i,t)int*a,*o;{if(!r)for(;n;--n)*o++=*--a;else{R;for(;i;--i){S R;S}}return o;}
P(n,a)int*a;{int N=1,i=n;for(;i;N*=i--);return p(n,n,a,malloc(N*n*8),n-1,0)-N*n;}

Функция P (n, a) возвращает указатель на n! перестановки, упакованные одна за другой в один гигантский массив.

Майкл Рэдфорд
источник
1
Несколько советов: <malloc.h> isn't needed (ignore the warnings). sizeof n` равно 4 (переносимость хорошая, но короче приятнее). Используйте дополнительные параметры в качестве переменных (например p(n,a,N,i)). int*p(..)int*a,o;, Использование глобальных переменных вместо параметров и возвращаемых значений часто помогает.
Угорен
@ugoren, спасибо за советы. До сих пор я не видел, как побрить других персонажей, используя глобалы. (И, эй, функция поточно-ориентированная как есть!)
Майкл Рэдфорд,
2

К, 30 байт

{x@v@&((#x;1)~^=:)'v:!(#x)##x}

Нет встроенных!

kirbyfan64sos
источник
1

JS - 154 146 символов

function f(x){var a=[],m;(m=x.length)>1?f(x.slice(1)).map(function(y){for(l=m;l--;a.push(y.slice(0,l).concat(x[0],y.slice(l))));}):a=[x];return a}

Тест: f([1,2,3,4,5]).map(function(a){return a.join('')}).join('\n')возвращает это .

JiminP
источник
1

р

Поскольку мы говорим о перестановках, позвольте мне показать хотя бы одно решение в R:

library(gtools);v=c(3,4,5);permutations(length(v),length(v),v)
Paolo
источник
1

Perl 188

Нет библиотечных подпрограмм, нет рекурсии

sub p{$l=(@_=sort split'',shift)-1;while(print@_){$k=$j=$l;--$k while($_[$k-1]cmp$_[$k])>=0;$k||last;--$j while($_[$k-1]cmp$_[$j])>=0;@_[$j,$k-1]=@_[$k-1,$j];@_[$k..$l]=reverse@_[$k..$l]}}
ardnew
источник
1

Скала 30:

def p(s:Seq[_])=s.permutations 

Scala 195, quick'n'dirty, без перестановок из библиотеки:

def c(x:Int,t:List[_]):List[_]={val l=t.size
val o=x%l
if(l>1){val r=c(x/l,t.tail)
r.take(o):::(t.head::r.drop(o))}else
t}
def p(y:List[_])=(0 to(1 to y.size).product).foreach(z=>println(c(z,y)))

val y=List(0,1,2,3)
p(y)

Scala 293, полноценный, безопасный тип итератор:

class P[A](val l:Seq[A])extends Iterator[Seq[A]]{
var c=0
val s=(1 to l.size).product
def g(c:Int,t:List[A]):List[A]={
val n=t.size
val o=c%n
if(n>1){val r=g(c/n,t.tail)
r.take(o):::(t.head::r.drop(o))
}else
t}
def hasNext=c!=s
def next={c+=1
g(c-1,l.toList)}
}
for(e<-new P("golf"))println(e)
Пользователь неизвестен
источник
1

Питон - 50 символов

import itertools
list(itertools.permutations("123"))
Джаред Барроуз
источник
Почему это будет отклонено 5 лет спустя?
Джаред Берроуз
1

Pyth, 4 байта

L.pb

Да, Pyth был создан после того, как этот вызов был опубликован и все. Это все еще действительно круто. : D

Живая демоверсия.

Чтение со стандартного ввода короче:

.pQ
kirbyfan64sos
источник
1

JavaScript 143 136 134 123

function p(s,a="",c="",i,z=[]){a+=c,i=s.length
!i?z.push(a):0
for(;i--;s.splice(i,0,c))p(s,a,c=s.splice(i,1),0,z);return z}

var perms = p([1,2,3]);

document.getElementById('output').innerHTML = perms.join("\n");
<pre id="output"></pre>

wolfhammer
источник
Я думаю, что вы могли бы получить 8 байт, выполнив: js function p(s,a="",c="",i,z=[]){ вместо js function p(s,a,c,i,z){if(!z)a=c="",z=[]
ColdK
Спасибо ColdK. Это сработало и теперь на 8 байт короче.
Вольфхаммер
0

Python, 53 байта

from itertools import*;lambda x:list(permutations(x))
Оливер Ни
источник
1
Это в основном дубликат другого представленного ответа . Я предполагаю, что вы придумали это самостоятельно (и вы играли в гольф лучше), но я подумал, что стоит указать на дубликат.
0

K (ок) , 3 байта

Решение

prm

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

Объяснение:

Это 3-байтовый встроенный ярлык для следующей встроенной 47-байтовой функции:

{[x]{[x]$[x;,/x ,''o'x ^/:x;,x]}@$[-8>@x;!x;x]}

... который можно сократить до 23 байт, если мы знаем, что в качестве входных данных получаем список целых чисел:

{$[x;,/x,''o'x^/:x;,x]} / golfed built in
{                     } / lambda function with implicit input x
 $[ ;             ;  ]  / if[condition;true;false]
   x                    / if x is not null...
             x^/:x      / x except (^) each-right (/:) x; create length-x combinations
           o'           / call self (o) with each of these
       x,''             / x concatenated with each-each of these results (this is kinda magic to me)
     ,/                 / flatten list
                    ,x  / otherwise enlist x (enlisted empty list)
streetster
источник
0

Аксиома, 160 байт

p(a)==(#a=0=>[[]];r:=[[a.1]];r:=delete(r,1);n:=#a;m:=factorial n;m>1.E7=>r;b:=permutations n;for j in 1..m repeat(x:=b.j;r:=concat([a.(x.i)for i in 1..n],r));r)

ungolfed

--Permutation of a
pmt(a)==
     #a=0=>[[]]
     r:=[[a.1]]; r:=delete(r,1) -- r has the type List List typeof(a)
     n:=#a
     m:=factorial n
     m>1.E7=>r
     b:=permutations(n)         --one built in for permutation indices 
     for j in 1..m repeat
        x:=b.j
        r:=concat([a.(x.i) for i in 1..n],r)
     r

Все это вызывает одну библиотечную функцию, которая дает перестановку по индексу (только целые числа как перестановка как перестановки в [1], перестановки в [1,2], перестановки в [1,2,3] и т. Д.). Так что достаточно получить эти наборы индексов и построения списков; Нужно отметить, что это, кажется, скомпилировано хорошо для каждого Списка типа X

(4) -> p([1,2,3])
   Compiling function p with type List PositiveInteger -> List List
      PositiveInteger
   (4)  [[1,2,3],[1,3,2],[3,1,2],[2,1,3],[2,3,1],[3,2,1]]
                                          Type: List List PositiveInteger
(5) -> p([x^2,y*x,y^2])
   Compiling function p with type List Polynomial Integer -> List List
      Polynomial Integer
   (5)
      2      2    2  2        2  2            2  2        2  2    2      2
   [[x ,x y,y ],[x ,y ,x y],[y ,x ,x y],[x y,x ,y ],[x y,y ,x ],[y ,x y,x ]]
                                       Type: List List Polynomial Integer
(6) -> p([sin(x),log(y)])
   Compiling function p with type List Expression Integer -> List List
      Expression Integer
   (6)  [[sin(x),log(y)],[log(y),sin(x)]]
                                       Type: List List Expression Integer
(7) -> m:=p("abc")::List List Character
   Compiling function p with type String -> Any
   (7)  [[a,b,c],[a,c,b],[c,a,b],[b,a,c],[b,c,a],[c,b,a]]
                                                Type: List List Character
(8) -> [concat(map(x+->x::String, m.j))  for j in 1..#m]
   (8)  ["abc","acb","cab","bac","bca","cba"]
                                                        Type: List String
РосЛУП
источник
У вас есть ссылка на переводчика Аксиома? Я хотел бы добавить его в Try It Online! Похоже, интересный язык.
Caird Coneheringaahing
0

Japt , 1 байт

á

Переводчик Japt

Это натолкнулось и не дало ответа Япта, поэтому я решил, что я продолжу и добавлю один. áприменительно к массиву и без каких-либо аргументов является встроенным для «получить все перестановки». -RФлаг , используемый в ссылке интерпретатор только модифицирует , как печатается результат.

Камил Дракари
источник
0

APL (NARS), 39 символов, 78 байтов

{1≥k←≢w←,⍵:⊂w⋄↑,/{w[⍵],¨q w[a∼⍵]}¨a←⍳k}

тестовое задание:

  q←{1≥k←≢w←,⍵:⊂w⋄↑,/{w[⍵],¨q w[a∼⍵]}¨a←⍳k}
  q 1 2 3
1 2 3  1 3 2  2 1 3  2 3 1  3 1 2  3 2 1 
  q 'abcd'
abcd abdc acbd acdb adbc adcb bacd badc bcad bcda bdac bdca cabd cadb cbad cbda cdab cdba dabc dacb dbac dbca dcab dcba 
RosLuP
источник
0

05AB1E - 2 1 байт с

œ

Входные данные должны быть массивом / списком.

Объяснение:

œ //Takes all the permutations of the elements in the top of the stack (the input is a list, so it would work)

Сохранил байт благодаря Эрику Аутгольферу

MilkyWay90
источник
Вы можете использовать входные данные как один список, не нужно разделять их новыми строками.
Эрик Outgolfer
Спасибо! Теперь я могу сократить это до одного байта!
MilkyWay90