Sözcük ekleme şeklinde sıralanmış sırada başa ekle ekleme permütasyonu kümesi oluşturun


14

Aşağıdaki yordamla oluşturulabilecek sayıların permütasyonu olarak, başa ekli bir uzunluk dizisi tanımlayın :n1, 2, ..., n

  • Numara ile başlayın 1.

  • - arasındaki her sayı 2için n, bu sayıyı dizinin başına veya sonuna yerleştirin ( başlığın başına veya sonuna ekleyin , dolayısıyla dizinin adı).

Örneğin, bu, uzunluk 4'ün başına bir ek ekleme dizisi oluşturmanın geçerli bir yoludur:

1
21     [beginning]
213    [end]
2134   [end]

Göreviniz bir numara alacak bir program veya fonksiyon oluşturmaktır nden 3üzere 30girdi olarak ve yazdırabilir veya uzunluktaki tüm başa getirebilir-ekleme dizileri dönmek n9 temsil edilecek Yukarıdaki dizeleri ve değil listeler, sayılar çıktılıyorsanız (sözlük sırasını içinde a-udize uzunluğunu korumak için harf olarak ). Örneğin, bu sipariş şöyledir n = 4:

1234  [RRR]
2134  [LRR]
3124  [RLR]
3214  [LLR]
4123  [RRL]
4213  [LRL]
4312  [RLL]
4321  [LLL]

Genel olarak, uzunluk olarak 2 n-1 başa ekli permütasyon vardır n.

Kodunuzda kendi dilinizde yerleşik bir sıralama işlevi kullanamazsınız. Bunu herhangi bir dilde yapmak için en kısa program kazanır.


Ben çıktı biçimi gereksinimi, özellikle harflere dönüşüm hayranı değilim a-u. Sadece sayı listelerini çıkarabilir miyiz?
15'te xnor

3
Bir süre sonra cevap kabul etmek isteyebilirsiniz, çünkü bazı insanlar kabul edilmiş bir cevabı varsa soruyu cevaplama eğilimindedir.
Doktor

1
Yani cevabı yanlış kabul ettiniz ..
Doktor

2
FryAmTheEggman cevabını sizinkini düzenlemeden 21 dakika önce yayınladı.
Joe Z.

2
@Optimizer Bunun en tuhaf yol olduğunu düşünmüyorum - FryAmTheEggman'ın cevabı sizinkinden 21 dakika önce 19 bayt uzunluğundaydı. Bu onu en erken gönderilen en kısa cevap yapar.
Joe Z.

Yanıtlar:


10

CJam, 22 20 19 17 bayt

]]l~{)f+_1fm>|}/p

Kod genişletme :

]]                   "Put [[]] onto stack. What we will do with this array of array is";
                     "that in each iteration below, we will first append the next";
                     "number to all present arrays, then copy all the arrays and";
                     "move the last element to first in the copy";
  l~                 "Read input number. Lets call it N";
    {         }/     "Run this code block N times ranging from 0 to N - 1";
     )f+             "Since the number on stack starts from 0, add 1 to it and append";
                     "it to all arrays in the array of array beginning with [[]]";
        _1fm>        "Copy the array of array and move last element from all arrays";
                     "to their beginning";
             |       "Take set union of the two arrays, thus joining them and eliminating";
                     "duplicates. Since we started with and empty array and started adding";
                     "numbers from 1 instead of 2, [1] would have appeared twice if we had";
                     "simply done a concat";
                p    "Print the array of arrays";

Nasıl çalışır :

Bu, kodun bir hata ayıklama sürümüdür:

]]l~ed{)edf+ed_ed1fm>ed|ed}/edp

Girdi için nasıl çalıştığını görelim 3:

[[[]] 3]                                 "]]l~"            "Empty array of array and input";
[[[]] 1]                                 "{)"              "First iteration, increment 0";
[[[1]]]                                  "{)f+"            "Append it to all sub arrays";
[[[1]] [[1]]]                            "{)f+_"           "Copy the final array of array";
[[[1]] [[1]]]                            "{)f+_1fm>"       "shift last element of each";
                                                           "sub array to the beginning";
[[[1]]]                                  "{)f+_1fm>|}"     "Take set based union";
[[[1]] 2]                                "{)"              "2nd iteration. Repeat";
[[[1 2]]]                                "{)f+"
[[[1 2]] [[1 2]]]                        "{)f+_";
[[[1 2]] [[2 1]]]                        "{)f+_1fm>";
[[[1 2] [2 1]]]                          "{)f+_1fm>|}";
[[[1 2] [2 1]] 3]                        "{)";
[[[1 2 3] [2 1 3]]]                      "{)f+"
[[[1 2 3] [2 1 3]] [[1 2 3] [2 1 3]]]    "{)f+_";
[[[1 2 3] [2 1 3]] [[3 1 2] [3 2 1]]]    "{)f+_1fm>";
[[[1 2 3] [2 1 3] [3 1 2] [3 2 1]]]      "{)f+_1fm>|}";
[[[1 2 3] [2 1 3] [3 1 2] [3 2 1]]]      "{)f+_1fm>|}/";

Buradan çevrimiçi deneyin


6

Haskell, 47 bayt

f 1=[[1]]
f n=(\x->map(++[n])x++map(n:)x)$f$n-1

1
Liste kavrayışına geçmek birkaç bayt tasarruf sağlar: f n=[[n:x,x++[n]]|x<-f$n-1]>>=id(code-golfers concat işlevini kullanarak >>=id).
nimi

1
@nimi ama yanlış sırada r
gurur haskeller

@proudhaskeller: Ah canım, spesifikasyonu yeterince dikkatli okumadım. Düzeltmeye çalıştım ve @ alephalpha'nın sürümü ile aynı uzunlukta dört farklı yol buldum, bu yüzden bir iyileştirme sunamıyorum. f n=[x++[n]|x<-f$n-1]++[n:x|x<-f$n-1], f n=map(++[n])(f$n-1)++[n:x|x<-f$n-1], f n=map(++[n])(f$n-1)++map(n:)(f$n-1),f n=(++[n])#n++(n:)#n;p#i=map p$f$i-1
nimi

5

Python 2, 68

f=lambda n:[[1]]*(n<2)or[x*b+[n]+x*-b for b in[1,-1]for x in f(n-1)]

Sayı listelerinin bir listesini çıkarır.

Özyinelemeli bir çözüm. İçin n==1çıktı [[1]]. Aksi takdirde, ntüm (n-1)izinlerin başına veya sonuna ekleyin. Prepending, permütasyonu sözlükbilimsel olarak eklemekten daha sonra yapar, böylece permütasyonlar sıralanır.

"Boolean" başlangıca mı yoksa sonuna bmı koyulacağını kodlar [n]. Aslında, listenin geri kalanını xifadede taşıyoruz x*b+[n]+x*-b. Koymak bolarak -1veya 1çarpılır bir liste beri olumsuzlaştırılmasıyla kullanım çevirme sağlayan -1boş listedir.


4

Pyth, 19

usCm,+dH+HdGr2hQ]]1

Buradan çevrimiçi deneyin

Bu stdin'den girdi alan tam bir programdır.

Bu, xnor'ın çözümüne benzer şekilde çalışır, ancak değerleri biraz bozuk olarak üretir, bu yüzden yeniden sıralanmalıdırlar. Her seviyede olan şey, önceki her bir değer listesinin sonuna ve başlangıcına yeni bir değer eklenmiş olması ve bunların her birinin bir listede bir araya getirilmiş 2 demet halinde sarılmasıdır. Örneğin, ilk adım bunu yapar:

[[1]]
[([1,2], [2,1])]

Ardından, bu tuples listesi sıkıştırılır (ve en dıştaki listeyi kaldırmak için toplanır). İlk durumda, listede sadece bir değer olduğu için bu, yukarıdan kaydırılmamış değeri verir.

2-> 3 gösterilen adımlar:

([1,2], [2,1])
[([1,2,3],[3,1,2]),([2,1,3],[3,2,1])]
([1,2,3],[2,1,3],[3,1,2],[3,2,1])

2

Mathematica, 57 54 49 bayt

f@1={{1}};f@n_:=#@n/@f[n-1]&/@Append~Join~Prepend

Misal:

f[4]

{{1, 2, 3, 4}, {2, 1, 3, 4}, {3, 1, 2, 4}, {3, 2, 1, 4}, {4, 1, 2, 3} , {4, 2, 1, 3}, {4, 3, 1, 2}, {4, 3, 2, 1}}


2

J, 26 bayt

   0|:<:((,,.,~)1+#)@[&0,.@1:

   (0|:<:((,,.,~)1+#)@[&0,.@1:) 3
1 2 3
2 1 3
3 1 2
3 2 1

FUZxxl sayesinde 1 baytlık iyileştirme .


Değiştirin ,.için ,"1bir karakter için.
FUZxxl

1

Pyth, 34 33 31 29

Temelde bir çeviri XNOR 'ın Python cevap . Pyth ile hala harika değilim, bu yüzden iyileştirme önerileri bekliyoruz.

yTamsayıların listesini döndürmek için bir işlev tanımlar .

L?]]1<b2smm++*kdb*k_dy-b1,1_1

Güncelleme: FryAmTheEggman sayesinde 2 bayt kaydedildi .

Açıklama:

L                                  define a function y with argument b that returns
 ?*]]1<b2                          [[1]] if b < 2 else
         s                         sum(
          m                        map(lambda d:
           m                       map(lambda k:
            ++*kdb*k_d             k*d + [b] + k*-d
                      y-b1         , y(b - 1))
                          ,1_1)    , (1, -1))

Bazı pyth şeyler: -b1olabilir tb, [1_1)olabilir ,1_1(ancak işlevi kapatmak için gereken baytları saymanız yeterlidir, ancak kapatmadan arayamayacak olsanız bile, yakın braketi düşebilirsiniz) ve bint'e bir liste eklerken pyth otomatik olarak listeye dönüştüğü için bir listeye sarmanıza gerek yoktur .
FryAmTheEggman

İkinci haritayı el ile yaparak birkaç bayt kaydetmenin bir yolunu buldum [1,-1]. Özellikle mantığı basitleştirdiğinizde kısa bir şeyi sabit kodlamak için bayt kaydedebilirim. Ben olsunL?]]1<b2sCm,+db+bdytb
FryAmTheEggman

@FryAmTheEggman Bunu kendi cevabınız olarak eklemek isteyebilirsiniz. Bu sadece harika.
PurkkaKoodari

Tamam, ben göndermeden önce CJam yenmek için denemek istedim ama zip hile gönderme hak için yeterince ilginç sanırım. Pyth ile iyi şanslar;)
FryAmTheEggman

1

Saf Bash, 103

Umduğumdan daha uzun:

a=1..1
for i in {2..9} {a..u};{
((++c<$1))||break
a={${a// /,}}
a=`eval echo $a$i $i$a`
}
echo ${a%%.*}

1

JavaScript (ES6) 73 80

@ Optimizer'ın güzel çözümünün JavaScript uygulaması.

Özyinelemeli (73):

R=(n,i=1,r=[[1]])=>++i>n?r:r.map(e=>r.push([i,...e])+e.push(i))&&R(n,i,r)

Yinelemeli (74):

F=n=>(i=>{for(r=[[1]];++i<=n;)r.map(e=>r.push([i,...e])+e.push(i))})(1)||r

Firefox / FireBug konsolunda test et

R(4)

[[1, 2, 3, 4], [2, 1, 3, 4], [3, 1, 2, 4], [3, 2, 1, 4], [4, 1, 2, 3] , [4, 2, 1, 3], [4, 3, 1, 2], [4, 3, 2, 1]]


0

Java çözümüm:

public static void main(String[] args) {
    listPrependAppend(4);
}

private static void listPrependAppend(int n) {
    int total = (int) Math.pow(2, n - 1);
    int ps;
    boolean append;
    String sequence;
    String pattern;

    for (int num = 0; num < total; num++) {
        sequence = "";
        pattern = "";
        append = false;
        ps = num;
        for (int pos = 1; pos < n + 1; pos++) {
            sequence = append ? (pos + sequence) : (sequence + pos);
            append = (ps & 0x01) == 0x01;
            ps = ps >> 1;
            if (pos < n) {
                pattern += append ? "L" : "R";
            }
        }
        System.out.format("%s\t[%s]%n", sequence, pattern);
    }
}

Oh fark, şimdi diğer cevapları gördükten sonra en kısa cevap için ne demek istediğini anlıyorum.
Brett Ryan

2
Çözümünüz saygın, özlü ve kendi başına iyi sunulmuş olsa da, bunun eldeki probleme tam olarak aday olmadığı doğru.
Joe Z.

1
@BrettRyan Gereksiz boşluğu kaldırarak ve tek karakterlik değişken adları kullanarak kodunuzu çok daha kısaltabilirsiniz. Bunun yerine falsebenzer bir şeyle de değiştirebilirsiniz 5<4.
ProgramFOX

1
Teşekkürler beyler. İlk kod zorluklarına katılma girişimim oldu. Sadece bazı programlama zorlukları arıyordum ve hedefin en kısa çözümü elde etmek olduğunu fark etmedim. :) Katılmama izin verdiğin için teşekkürler.
Brett Ryan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.