Kode golf permutasi terbaik

14

Tantangan

Diberikan bilangan bulat n ≥ 4 , menghasilkan permutasi bilangan bulat [0, n-1] dengan properti yang tidak memiliki dua bilangan bulat berurutan yang bersebelahan. Nilai permutasi piadalah jumlah abs(pi[i] - i)untuk semua indeks i.

Contohnya

  • (1, 3, 0, 2) memiliki nilai 6
  • (0, 2, 4, 1, 3) memiliki nilai 6
  • (0, 2, 4, 1, 3, 5) memiliki nilai 6
  • (0, 2, 4, 1, 5, 3, 6) memiliki nilai 8

Skor jawaban Anda

Skor jawaban Anda adalah jumlah nilai permutasi Anda n = 4 .. 14ditambah jumlah byte yang digunakan oleh kode Anda. Semakin rendah skor, semakin baik. Kode Anda harus memberikan output yang valid untuk semua nilai tersebut n.

Anda harus dapat menjalankan pengiriman sampai selesai di mesin Anda.

Dalam hal ikatan, waktu pengeditan terakhir yang menghasilkan skor yang relevan akan menjadi penentu.

Bukankah ini pertanyaan yang sama dengan yang ini ?

Jawaban untuk pertanyaan terkait tidak akan kompetitif untuk pertanyaan ini karena mereka tidak berupaya untuk mengoptimalkan nilai permutasi. Misalnya untuk n=10, permutasi yang [1, 3, 5, 7, 9, 0, 2, 4, 6, 8]diberikan oleh sebagian besar jawaban di sana memberikan nilai 30. Anda dapat melakukan jauh lebih baik dari itu.

Untuk bagian permutasi dari pertanyaan, nilai optimal keseluruhan paling banyak 120. (Terima kasih kepada @Laikoni.) Sedangkan jawaban Dennis untuk pertanyaan sebelumnya skor 222 . (Terima kasih kepada @ user202729.)

Anush
sumber
4
@JoKing setiap jawaban dapat diporting tanpa perubahan, tetapi skor akan sangat buruk dalam tantangan ini. Memposting kode dalam tantangan ini setara dengan memposting kode dari tinjauan kode ke tantangan kode-golf.
Stewie Griffin
2
Mencampur jumlah yang berbeda dalam skor memang bisa menjadi masalah. Jawaban dengan algoritme terbaik biasanya dapat porting ke bahasa apa pun, dalam hal ini skor dikurangi menjadi golf kode normal.
Angs
4
Nilai optimal adalah [6,6,6,8,10,12,12,12,14,16,18]untuk skor 120. Menariknya pola ini dapat ditemukan di A078706 .
Laikoni
3
Ok, itu mulai berbeda dari A078706dengan n=17, yang dapat memiliki skor 20.
Laikoni
4
Saya bisa memahami tantangan dengan jelas dan tidak ambigu. Jika Anda tidak setuju dan memilih untuk menutup, tinggalkan komentar di sini.
user202729

Jawaban:

7

Jelly , 36 34 33 32 31 30 byte, hasil: 120

Terima kasih kepada Dennis untuk -1 byte! (secara implisit dengan memperbaiki bug Jelly, meskipun fitur tersebut mendahului tantangan)

ðRḟISị“Ƥ¿‘Ʋœ?$;@µ2x5~4¦ṁ_4$Ä’

Fitur baru: akumulasi jumlah ( Ä).

Cobalah online!

Gunakan pengindeksan 1.

Mengambil waktu linier juga.


Program C ++ ini menghasilkan permutasi terkecil secara leksikografis, dengan asumsi bahwa | i - p i | ≤ lebar (di mana lebar adalah konstanta hardcoded) untuk semua 0 ≤ i <n , dengan kompleksitas waktu sekitar O (lebar 2 × 2 2 × lebar × n) (yang hanya O (n) untuk lebar tetap ): Cobalah online !


Bagaimana?

  1. Tulis program C ++ yang mencoba menyelesaikan masalah secara optimal.
  2. Amati polanya. Kami mencatat bahwa urutan semua elemen kecuali 4 yang terakhir adalah awalan dari

    0 2 4 1 3 5 7 9 6 8 10 12 14 11 13 15 17 19 16 18 20 22 24 21 23 25 ...
    
  3. Menghitung perbedaan inkremental urutan.

    2 2 -3 2 2 2 2 -3 2 2 2 2 -3 2 2 2 2 -3 2 2 2 2 -3 2 2
    

    Catat periode 5.

  4. Implementasi Jelly:

    • n-4 elemen pertama diambil dari urutan di atas. O (n) .
    • Untuk 4 elemen terakhir, cukup paksa semua 24 kemungkinan . O (1) .

      (catatan: Saya tidak lagi memaksa semua 24 kemungkinan dari versi 32-byte)

pengguna202729
sumber
Ah, Anda menggunakan awalan yang berbeda dengan saya. Milik saya dimulai 0 2 4 1 3 5 8 6, dan memiliki faktor percabangan yang lebih besar tetapi tidak memiliki pola sederhana.
Peter Taylor
7

CJam (60 byte + 120 = 180 skor)

{_5/4*8e!961=7_)er<:A\,^e!{A\+}%{2ew::-:z1&!},{_$.-:z1b}$0=}

Test suite online dengan skor terintegrasi

Perpanjangan hingga n = 24

Pembedahan

{
  _5/4*        e# Work out how much of the hard-coded prefix to use
  8e!961=7_)er e# Prefix [0 2 4 1 3 5 8 6]
               e# I identified this by brute forcing up to n=10 and looking for patterns
               e# I then used the identified prefix [0 2 4 1] to brute-force further
  <:A          e# Take the desired prefix of the hard-coded array, and store a copy in A
  \,^e!        e# Generate all permutations of the values in [0 .. n-1] which aren't in A
  {A\+}%       e# Prepend A to each of them
  {            e# Filter...
    2ew::-     e#   Take each difference of two consecutive elements
    :z         e#   Find their absolute values
    1&         e#   Test whether 1 is among those absolute values
    !          e#   Reject if it is
  },
  {            e# Sort by...
    _$.-       e#   Take pairwise differences of permutation with the identity
    :z         e#   Absolute values
    1b         e#   Add them (by interpreting in base 1)
  }$
  0=           e# Take the first
}
Peter Taylor
sumber
Sangat mengesankan! Saya berharap dapat menemukan bagaimana Anda melakukannya.
Anush
Apakah optimal hingga 24?
Anush
@Anush Menurut program saya, mungkin.
user202729
@ Anush, saya belum membuktikannya, tapi saya percaya itu mungkin.
Peter Taylor
Saya bahkan lebih tertarik dengan algoritma Anda!
Anush
6

Haskell , skor 146 + 89 + byte

f i|k<-mod i 4=scanl(+)1$take(i-2-k)(cycle[2,-3,2,3])++[[2],[2,2],[5,-3,2],[5,-3,2,2]]!!k

Pola berulang [1,3,0,2], terakhir mod i 4 elemen disetel dengan tangan.

Algoritma sebelumnya (132 + 116):

f i=last$filter(\a->all(`elem`a)[0..i-1]).(!!(i-1)).iterate((\l->map((:l).(+head l))[-3,2,-2,3])=<<)$pure<$>[i-3..i]

Bruteforces jumlah lompatan panjang yang benar ± 2 atau ± 3. Memilih yang terakhir yang memiliki angka yang benar di dalamnya, tampaknya berfungsi dengan baik dan jauh lebih murah daripada menerapkan skor. Tio hanya kehabisan waktu sebelum skor terakhir, yaitu 18.

Cobalah online!

Angs
sumber
2

Japt, 120 + 20 = 140

(Menyalin salah satu solusi saya dari tantangan lain akan memberi saya nilai 227)

o á k_äa d¥1ÃñxÈaYÃg

Cobalah atau gunakan versi ini untuk memeriksa skor. Kedua versi ini mungkin mulai memberi tahu Anda sekitar 9.


Penjelasan

o                        :Range [0,input)
  á                      :All permutations
    k_      Ã            :Remove sub-arrays that return true
      äa                 :  Get the consecutive absolute differnces
         d¥1             :  Do any equal 1?
               È  Ã      :Pass the integers in each remaining sub-array through a function
                aY       :  Get the absolute difference with the integer's index
              x          :Reduce by addition
             ñ           :Sort the main array by those values
                   ñ     :Return the first sub-array
Shaggy
sumber
9
" Anda harus dapat menjalankan kiriman Anda sampai selesai pada mesin Anda. " Apakah Anda serius memproses proses 87E9 permutasi 14 elemen dalam dua jam sejak pertanyaan itu diposting?
Peter Taylor
3
Selain itu, pertimbangkan bahwa Japt didasarkan pada Javascript, dapatkah ia benar-benar menangani permutasi 87E9? Pertanyaan ini mengatakan bahwa array Javascript dapat memiliki panjang paling banyak ~ 4E9. Apakah Japt memiliki fungsi menghasilkan atau sesuatu ... \
user202729
2

Ruby , skor 120 + 112 106 91 82 byte

->n{(0...n).map{|a|a+(a+2)%5-([[],[],[0,4,3],[-1,4,4,4],[1,1,6,1]][n%5][a-n]||2)}}

Cobalah online!

Urutannya pada dasarnya (a-2)+(a+2)%5.

Jika n mod 5 bukan 0 atau 1, 3 atau 4 elemen terakhir berbeda.

Ini masih setengah-kode, selalu menemukan solusi terbaik, mungkin bisa bermain golf sedikit lagi, tapi saya sudah kehabisan ide.

GB
sumber
1

JavaScript (Node.js) , skor 148 + 109 73 byte

n=>[...Array(n)].map(_=>l=!m|l>n%5+2&&l>m+2?[+m,m=l+2][0]:l+2,m=n>4,l=~m)

Cobalah online! Penjelasan: lmelacak nomor terakhir yang dihasilkan dan mmelacak nomor berikutnya dari paritas yang berlawanan dengan l; setelah lmelebihi m+2variabel dipertukarkan. Penyesuaian dilakukan pada awal urutan sehingga urutan yang panjangnya bukan kelipatan 5 tidak melewatkan angka, dan penyesuaian lainnya dibuat untuk n=4.

Neil
sumber