Penomoran Permutasi

9

Tantangan

Untuk sekumpulan integer n, tulis sebuah program yang akan menampilkan indeks leksikografinya.

Aturan

  • Input hanya boleh berupa satu set bilangan bulat non-negatif unik yang dipisahkan oleh spasi.
  • Anda harus menampilkan indeks leksikografis (kisaran 0 hingga n! -1 inklusif) dari permutasi.
  • Tidak ada perpustakaan permutasi atau permutasi bawaan yang dapat digunakan.
  • Anda tidak boleh membuat set permutasi atau subset permutasi input untuk membantu Anda menemukan indeks.
  • Anda juga tidak bisa menambah atau mengurangi permutasi yang diberikan ke permutasi berikutnya / sebelumnya (secara leksikografis).
  • Poin bonus (-10 byte) jika Anda menemukan cara untuk menyelesaikan ini tanpa menggunakan faktorial.
  • Runtime harus kurang dari 1 menit untuk n = 100
  • Kode terpendek dengan jumlah byte menang
  • Pemenang dipilih Selasa (22 Juli 2014)

Lebih Lanjut Tentang Permutasi

Contohnya

0 1 2 --> 0
0 2 1 --> 1
1 0 2 --> 2
1 2 0 --> 3
2 0 1 --> 4
2 1 0 --> 5
0 1 2 3 4 5 6 7 --> 0
0 1 2 3 4 5 7 6 --> 1
0 1 2 3 4 6 5 7 --> 2
1 3 5 17        --> 0
781 780 779 13  --> 23
81 62 19 12 11 8 2 0 --> 40319
195 124 719 1 51 6 3 --> 4181
Kyle McCormick
sumber
1
Bisakah kita punya lebih banyak waktu sampai pemenang dipilih? Tiga hari terlalu sedikit waktu.
xnor

Jawaban:

4

GolfScript, 12 (22 karakter - 10 bonus)

~]0\.,{.,@*\.(@$?@+\}*

Poin bonus untuk tidak menggunakan faktorial. Masukan harus diberikan pada STDIN dalam format yang diuraikan dalam pertanyaan. Anda dapat mencoba kodenya secara online .

Howard
sumber
Haha tidak cukup apa yang saya cari ketika saya mengatakan "tanpa menggunakan faktorial" tapi saya kira itu penting. Kudos
Kyle McCormick
4

CJam, 31, dengan faktorial

q~]{__(f<0+:+\,,(;1+:**\(;}h]:+
jimmy23013
sumber
Kenapa saya masih mendapatkan upvote? Jawaban GolfScript dapat ditulis ulang dalam CJam dengan hanya 23 karakter.
jimmy23013
6
Karena orang menyukai jawaban Anda.
seequ
1

Python 2 (77 = 87-10)

p=map(int,raw_input().split())
s=0
while p:s=s*len(p)+sorted(p).index(p.pop(0))
print s

Bisa dibaca Banyak built-in. Wow.

Kami menggunakan fakta bahwa indeks leksikografi permutasi adalah penjumlahan dari elemen permutasi dari jumlah inversi di atas elemen tersebut (nilai setelahnya tetapi di bawahnya) dikalikan dengan faktorial dari jumlah elemen sesudahnya. Daripada mengevaluasi istilah ekspresi polinomial seperti ini dengan istilah, kami menggunakan sesuatu yang mirip dengan metode Horner .

Daripada membalik-balik indeks array, kami berulang kali menghapus elemen pertama dari daftar dan memproses elemen yang tersisa. Ekspresi sorted(p).index(p.pop(0))menghitung jumlah inversi yang melewati indeks pertama dengan mengambil posisinya di daftar yang diurutkan, sementara pada saat yang sama melakukan penghapusan.

Sayangnya, saya harus menggunakan Python 2 dan mengambil 4 karakter lagi raw_input (meskipun -1 untuk print) karena dalam Python 3 map(int,...)menghasilkan objek peta, yang tidak mendukung operasi daftar,

Tidak
sumber
1

Pyth (13 = 23-10)

JVPwdWJ=Z+*ZlJXovNJ;J)Z

Port of jawaban Python saya .

Terjemahan Python (dengan beberapa hal yang tidak relevan difilter):

Z=0
J=rev(split(input()," "))
while J:
 Z=plus(times(Z,len(J)),index(order(lambda N:eval(N),J),J.pop()))
print(Z)

Nomor input tetap string tetapi diurutkan sebagai int dengan menggunakan eval sebagai kuncinya. Daftar ini dibalik sehingga popmengambil bagian depan daripada bagian belakang.

Tidak
sumber
1

Cobra - 202

Jelas Cobra tidak benar-benar bersaing dalam hal ini.

class P
    var n=0
    var t=CobraCore.commandLineArgs[1:]
    def main
        .f(.t[0:0])
    def f(l as List<of String>)
        if.t.count==l.count,print if(.t<>l,'',.n+=1)
        else,for i in.t.sorted,if i not in l,.f(l+[i])
Suram
sumber
0

J, 5 byte (15 - 10)

#\.#.+/@(<{.)\.

Ini berjalan dalam waktu O ( n 2 ) dan dapat menangani n = 100 dengan mudah.

Pemakaian

   f =: #\.#.+/@(<{.)\.
   f 0 1 2
0
   f 0 2 1
1
   f 1 0 2
2
   f 1 2 0
3
   f 2 0 1
4
   f 2 1 0
5
   f 0 1 2 3 4 5 6 7
0
   f 0 1 2 3 4 5 7 6
1
   f 0 1 2 3 4 6 5 7
2
   f 1 3 5 17
0
   f 781 780 779 13
23
   f 81 62 19 12 11 8 2 0
40319
   f 195 124 719 1 51 6 3
4181
   NB. A. is the builtin for permutation indexing
   timex 'r =: f 927 A. i. 100'
0.000161
   r
927

Penjelasan

#\.#.+/@(<{.)\.  Input: array P
             \.  For each suffix of P
          {.       Take the head
         <         Test if it is greater than each of that suffix
     +/@           Sum, count the number of times it is greater
#\.              Get the length of each suffix of P
   #.            Convert to decimal using a mixed radix
mil
sumber