Ex-zunehmende Set-Sequenz

11

Hintergrund

Eine ex-zunehmende Mengenfolge der Ordnung ist definiert als eine Folge von ganzzahligen Mengen S 1 , S 2 , , S n, die die folgenden Bedingungen erfüllt:NS1,S2,,Sn

  • Jedes ist eine nicht leere Teilmenge von { 1 , 2 , , N } .Si{1,2,,N}
  • Für ist S iS i + 1 = , dh zwei aufeinanderfolgende Sätze haben keine gemeinsamen Elemente.1i<nSiSi+1=
  • Für ist der Mittelwert (Mittelwert) von S i streng kleiner als der von S i + 1 .1i<nSiSi+1

Herausforderung

Geben Sie bei einer positiven Ganzzahl Ndie Länge der längsten ex-zunehmenden Satzreihenfolge aus N.

Testfälle

Diese basieren auf den Ergebnissen des Project Euler-Benutzers 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

Regeln

Es gelten die Standardregeln für . Die kürzeste gültige Übermittlung in Bytes gewinnt.

Kopfgeld

Dieses Problem wurde hier im Project Euler-Forum vor ungefähr 4 Jahren diskutiert , aber wir konnten keinen nachweisbaren Polynom-Zeit-Algorithmus (in Bezug auf N) entwickeln. Daher werde ich der ersten Einreichung, die dies erreicht, +200 Kopfgeld gewähren oder ihre Unmöglichkeit beweisen.

Bubbler
quelle
Ich habe über eine Woche lang versucht, einen Polynom-Zeit-Algorithmus oder einen NP-Härte-Beweis mit einer Reduktion zu entwickeln. Hat hier jemand Fortschritte gemacht?
Enrico Borba

Antworten:

4

Brachylog , 28 Bytes

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

Probieren Sie es online aus!

Das ist verdammt langsam. Dauert ungefähr 30 Sekunden N = 3und wurde nach 12 Minuten für nicht abgeschlossen N = 4.

Erläuterung

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

Schnellere Version, 39 Bytes

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

Dies dauert auf meinem Computer ungefähr 50 Sekunden N = 4.

Dies ist das gleiche Programm, außer dass wir die Teilmenge der Teilmengen nach Durchschnitt sortieren, anstatt eine zufällige Permutation vorzunehmen. Also verwenden wir {⟨+/l⟩/₁/₁}ᵒstatt p.

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

Wir müssen einen Float-Durchschnitt ermitteln, da ich gerade einen lächerlichen Fehler entdeckt habe, bei dem Floats und Ganzzahlen nicht nach Wert, sondern nach Typ mit Ordnungsprädikaten verglichen werden (dies ist auch der Grund, warum ich beide Durchschnittswerte verwende <ᵈund nicht <₁vergleiche; letzteres würde dies erfordern doppelter Inversionstrick zur Arbeit).

Fatalisieren
quelle
Ich hatte vor, mich langsam auf den Weg zu machen, um dieses Problem anzugehen (da @JonathanAllan es in dem anderen Kommentar erwähnt hat), aber ich bin wahrscheinlich Wochen zurück, um mir so etwas auszudenken! Mir gefällt, wie (wie die meisten Antworten von Brachylog) es am Ende nur wie eine ordentliche Wiederholung der Frage selbst aussieht.
Sundar - Reinstate Monica
@sundar Sie können später jederzeit darauf zurückkommen und versuchen, eine Lösung wiederzuentdecken!
Fatalize
3

CJam (81 Bytes)

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

Online-Demo . Es sollte für die Eingabe 4in einer angemessenen Zeit ausgeführt werden, aber ich würde es nicht mit höheren Eingaben versuchen.

Präparation

{                 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
quelle
1

JavaScript (ES6), 175 Byte

Eine naive und eher langsame rekursive Suche. Es dauert ungefähr 15 Sekunden, um die 7 ersten Terme auf TIO zu berechnen.

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

Probieren Sie es online aus!

oder testen Sie diese modifizierte Version , die die längste ex-zunehmende Set-Sequenz ausgibt.

Wie?

{1,2,,n}a

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

Rekursiver Teil:

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
quelle
1

Python 3 , 205 197 184 182 Bytes

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*

Probieren Sie es online aus!

Jonathan Frech
quelle
197 Bytes mit sumanstelle von chain.from_iterable.
ovs
@ceilingcat Danke.
Jonathan Frech