Ex-Artan Set Sırası


11

Arka fon

Bir ex artan resim dizisi emri tamsayı setlerinin bir dizi olarak tanımlanmıştır aşağıdaki durumundadır:S 1 , S 2 , , S nNS1,S2,,Sn

  • Her , boş olmayan bir alt kümesidir . { 1 , 2 , , N }Si{1,2,,N}
  • İçin , örneğin, herhangi bir iki ardışık kümeleri ortak olan herhangi bir öğe bulunmaktadır.S iS i + 1 = 1i<nSiSi+1=
  • İçin , ortalama (ortalama değer) kesinlikle daha az boşluk uzunluğundan fazla olduğu .S i S i + 11i<nSiSi+1

Meydan okuma

Pozitif bir tamsayı verildiğinde N, en uzun eski artan sıralı sipariş sırasının uzunluğunu çıktılayın N.

Test senaryoları

Bunlar, Project Euler kullanıcı thundre sonuçlarına dayanmaktadır .

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

kurallar

Standart kuralları geçerlidir. Bayt cinsinden en kısa geçerli gönderim kazanır.

Ödül

Bu sorun yaklaşık 4 yıl önce Project Euler forumunda tartışıldı , ancak (açısından N) kanıtlanabilir bir polinom-zaman algoritması bulamadık . Bu nedenle, bunu başaran ya da imkansızlığını kanıtlayan ilk gönderime +200 ödül vereceğim.


Bir hafta boyunca bir indirgeme kullanarak bir polinom-zaman algoritması veya NP sertlik kanıtı bulmaya çalıştım. Burada kimse bu konuda ilerleme kaydetti mi?
Enrico Borba

Yanıtlar:


4

Brachylog , 28 bayt

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

Çevrimiçi deneyin!

Bu gerçekten çok yavaş. Yaklaşık 30 saniye sürer N = 3ve 12 dakika sonra tamamlanmadı N = 4.

açıklama

⟦₁                             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.

Daha hızlı sürüm, 39 bayt

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

Bilgisayarımda bu yaklaşık 50 saniye sürüyor N = 4.

Rastgele bir permütasyon almak yerine altkümelerin alt kümelerini ortalamaya göre sıralamamız dışında bu aynı programdır. Yani {⟨+/l⟩/₁/₁}ᵒyerine kullanıyoruz p.

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

Ben sadece yüzer ve tamsayılar (değeriyle ama sipariş yüklemleri ile tipine göre karşılaştırma kullandığım bu yüzden de yok olduğu bir saçma hata olduğunu çünkü bir şamandıra ortalamasını almak gerekir <ᵈdeğil <₁hem ortalamalarını karşılaştırmak için; ikincisi olduğunu gerektirecektir çalışmak için çift ters hile).


Yavaş yavaş bu bir (@JonathanAllan diğer yorumda söz çünkü) mücadele için benim yol çalışmak planlıyordu, ama muhtemelen böyle bir şey ile geliyor haftalar sonra! Sonunda nasıl (çoğu Brachylog cevapları gibi) sadece sorunun kendisinin düzgün bir şekilde yeniden ifade edilmesine benziyor.
sundar - Monica'yı

@ sundar daha sonra her zaman geri dönebilir ve bir çözümü yeniden keşfetmeye çalışabilirsiniz!
ölümcül

3

CJam (81 bayt)

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

Çevrimiçi demo . 4Makul bir zamanda girdi için yürütmek gerekir , ancak daha yüksek girişlerle denemek olmaz.

teşrih

{                 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
}

1

JavaScript (ES6), 175 bayt

Saf ve oldukça yavaş bir özyinelemeli arama. TIO'daki ilk 7 terimi hesaplamak yaklaşık 15 saniye sürer.

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

Çevrimiçi deneyin!

veya en uzun ex-artan set sırasını veren bu değiştirilmiş versiyonu test edin.

Nasıl?

Biz ilk POWERSET hesaplamak ve depolamak :a{1,2,,n}a

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

Özyinelemeli kısım:

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()

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.