Mantan Menambah Urutan Set

11

Latar Belakang

Sebuah mantan peningkatan set urutan urutan didefinisikan sebagai urutan bilangan bulat set yang memenuhi berikut:S 1 , S 2 , , S nNS1,S2,,Sn

  • Setiap adalah bagian yang tidak kosong dari . { 1 , 2 , , N }Si{1,2,,N}
  • Untuk , , yaitu setiap dua set berturut-turut tidak memiliki elemen yang sama.S iS i + 1 = 1i<nSiSi+1=
  • Untuk , rata-rata (nilai rata-rata) benar-benar kurang dari .S i S i + 11i<nSiSi+1

Tantangan

Diberikan bilangan bulat positif N, menampilkan panjang urutan urutan peningkatan terlama yang terlama N.

Uji kasus

Ini didasarkan pada hasil oleh Project Euler pengguna thundre .

1 => 1 // {1}
2 => 2 // {1} {2}
3 => 3 // {1} {2} {3}
4 => 5 // {1} {2} {1,4} {3} {4}
5 => 7 // {1} {2} {1,4} {3} {2,5} {4} {5}
6 => 10 // {1} {2} {1,4} {3} {1,4,5} {2,3,6} {4} {3,6} {5} {6}
7 => 15 // {1} {2} {1,4} {3} {1,2,7} {3,4} {1,2,5,7} {4} {1,3,6,7} {4,5} {1,6,7} {5} {4,7} {6} {7}
8 => 21
9 => 29
10 => 39
11 => 49
12 => 63
13 => 79
14 => 99
15 => 121
16 => 145
17 => 171
18 => 203
19 => 237
20 => 277
21 => 321
22 => 369
23 => 419
24 => 477
25 => 537

Aturan

Aturan standar berlaku. Pengajuan terpendek yang valid dalam byte menang.

Karunia

Masalah ini telah dibahas di sini di forum Project Euler sekitar 4 tahun yang lalu, tetapi kami gagal menghasilkan algoritma waktu polinomial yang dapat dibuktikan (dalam hal N). Oleh karena itu, saya akan memberikan hadiah +200 kepada kiriman pertama yang mencapai ini, atau membuktikan ketidakmungkinannya.

Bubbler
sumber
Saya telah menghabiskan lebih dari seminggu mencoba untuk membuat algoritma waktu polinomial atau bukti kekerasan NP menggunakan pengurangan. Adakah yang sudah membuat kemajuan di sini?
Enrico Borba

Jawaban:

4

Brachylog , 28 byte

⟦₁⊇ᶠk⊇pSs₂ᶠ{c≠&⟨+/l⟩ᵐ<ᵈ}ᵐ∧Sl

Cobalah online!

Ini sangat lambat. Butuh sekitar 30 detik untuk N = 3, dan itu tidak selesai setelah 12 menit N = 4.

Penjelasan

⟦₁                             Take the range [1, …, Input]
  ⊇ᶠk                          Find all ordered subsets of that range, minus the empty set
     ⊇                         Take an ordered subset of these subsets
      pS                       Take a permutation of that subset and call it S
       Ss₂ᶠ                    Find all substrings of 2 consecutive elements in S
           {           }ᵐ      Map for each of these substrings:
            c≠                   All elements from both sets must be different
              &⟨+/l⟩ᵐ            And the average of both sets (⟨xyz⟩ is a fork like in APL)
                     <ᵈ          Must be in strictly increasing order
                         ∧Sl   If all of this succeeds, the output is the length of L.

Versi lebih cepat, 39 byte

⟦₁⊇ᶠk⊇{⟨+/l⟩/₁/₁}ᵒSs₂ᶠ{c≠&⟨+/l⟩ᵐ<₁}ᵐ∧Sl

Ini membutuhkan sekitar 50 detik di komputer saya untuk N = 4.

Ini adalah program yang sama kecuali kami mengurutkan subset dari subset dengan rata-rata alih-alih mengambil permutasi acak. Jadi, kami menggunakan {⟨+/l⟩/₁/₁}ᵒbukan p.

{         }ᵒ     Order by:
 ⟨+/l⟩             Average (fork of sum-divide-length)
      /₁/₁         Invert the average twice; this is used to get a float average

Kita perlu mendapatkan rata-rata float karena saya baru saja menemukan bug konyol di mana float dan integer tidak membandingkan berdasarkan nilai tetapi dengan tipe dengan predikat pemesanan (ini juga mengapa saya menggunakan <ᵈdan tidak <₁membandingkan kedua rata-rata; yang terakhir akan mengharuskan trik inversi ganda untuk bekerja).

Fatalisasi
sumber
Saya berencana untuk perlahan-lahan memperbaiki cara untuk mengatasi yang satu ini (karena @Jonathan Allan menyebutkannya di komentar lain), tapi saya mungkin berminggu-minggu di belakang dengan hal-hal seperti ini! Saya suka bagaimana (seperti kebanyakan jawaban Brachylog) pada akhirnya hanya tampak seperti pernyataan ulang yang rapi dari pertanyaan itu sendiri.
sundar - Reinstate Monica
@sundar Anda selalu dapat kembali lagi nanti dan mencoba menemukan kembali solusinya!
Fatalkan
3

CJam (81 byte)

{YY@#(#{{2bW%ee{)*~}%}:Z~{)Z__1b\,d/\a+}%$}%{_,1>{2ew{z~~&!\~=>}%0&!}{,}?},:,:e>}

Demo online . Seharusnya mengeksekusi untuk input 4dalam waktu yang wajar, tetapi saya tidak akan mencobanya dengan input yang lebih tinggi.

Pembedahan

{                 e# Declare a block (anonymous function)
  YY@#(#          e# There are 2^N subsets of [0, N), but the empty subset is problematic
                  e# so we calculate 2^(2^N - 1) subsets of the non-empty subsets
  {               e# Map integer to subset of non-empty subsets:
    {             e#   Define a block to map an bitset to its set indices; e.g. 9 => [0 3]
      2bW%ee      e#     Convert to base 2, reverse, and index
      {)*~}%      e#     If the bit was set, keep the index
    }:Z           e#   Assign the block to variable Z
    ~             e#   Evaluate it
    {             e#   Map those indices to non-empty subsets of [0, N):
      )Z          e#     Increment (to skip the empty set) and apply Z
      __1b\,d/    e#     Sum one copy, take length of another, divide for average
      \a+         e#     Wrap the subset and prepend its average value
    }%
    $             e#   Sort (lexicographically, so by average value)
  }%
  {               e# Filter out subsets of subsets with conflicts:
    _,1>{         e#   If the length is greater than 1
      2ew         e#     Take each consecutive pair of subsets
      {           e#     Map:
        z~        e#       Zip and expand to get [score1 score2] [subset1 subset2]
        ~&!\      e#       No element in common => 1
        ~=        e#       Different scores => 0
        >         e#       1 iff both constraints are met
      }%
      0&!         e#     1 iff no consecutive pair failed the test
    }{
      ,           e#   Otherwise filter to those of length 1
    }?
  },
  :,:e>           e# Map to size of subset and take the greatest
}
Peter Taylor
sumber
1

JavaScript (ES6), 175 byte

Pencarian rekursif yang naif dan agak lambat. Membutuhkan waktu sekitar 15 detik untuk menghitung 7 persyaratan pertama pada TIO.

n=>(a=[...Array(n)].reduce(a=>[...a,...a.map(y=>[x,...y],x=n--)],[[]]),g=(p,b=a,n)=>a.map(a=>(m=a.map(n=>s+=++k*b.includes(n)?g:n,s=k=0)&&s/k)>p&&g(m,a,-~n),r=r>n?r:n))(r=0)|r

Cobalah online!

atau uji versi modifikasi ini yang menghasilkan urutan rangkaian peningkatan terlama yang terlama.

Bagaimana?

{1,2,,n}a

a = [...Array(n)].reduce(a =>
  [...a, ...a.map(y => [x, ...y], x = n--)],
  [[]]
)

Bagian rekursif:

g = (                         // g = recursive function taking:
  p,                          //   p = previous mean average
  b = a,                      //   b = previous set
  n                           //   n = sequence length
) =>                          //
  a.map(a =>                  // for each set a[] in a[]:
    (m = a.map(n =>           //   for each value n in a[]:
      s +=                    //     update s:
        ++k * b.includes(n) ? //       increment k; if n exists in b[]:
          g                   //         invalidate the result (string / integer --> NaN)
        :                     //       else:
          n,                  //         add n to s
      s = k = 0)              //     start with s = k = 0; end of inner map()
      && s / k                //   m = s / k = new mean average
    ) > p                     //   if it's greater than the previous one,
    && g(m, a, -~n),          //   do a recursive call with (m, a, n + 1)
    r = r > n ? r : n         //   keep track of the greatest length in r = max(r, n)
  )                           // end of outer map()
Arnauld
sumber
1

Python 3 , 205 197 184 182 byte

  • Disimpan delapan dua puluh satu byte berkat ovs .
  • Disimpan dua byte berkat ceilingcat .
f=lambda N,c=[[1]]:max([len(c)]+[f(N,c+[n])for k in range(N)for n in combinations(range(1,N+1),k+1)if not{*c[-1]}&{*n}and sum(c[-1])/len(c[-1])<sum(n)/len(n)]);from itertools import*

Cobalah online!

Jonathan Frech
sumber
197 byte menggunakan sumsebagai gantinya chain.from_iterable.
Ovs
@ceilingcat Terima kasih.
Jonathan Frech