元の増加セットシーケンス


11

バックグラウンド

順序の元の増加セットシーケンスは、次の条件を満たす整数セットシーケンスとして定義されます。NS1S2Sn

  • 各は、空でないサブセットです。S{12N}
  • 以下のための、、すなわち、任意の二つの連続したセットは、共通の要素を持ちません。1<nSS+1=
  • 以下のための、平均(平均値)の厳密に以下のものよりなる。1<nSS+1

チャレンジ

正の整数を指定するとN、順序の最大の元増加セットシーケンスの長さを出力しNます。

テストケース

これらは、Project Eulerユーザー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

ルール

標準の規則が適用されます。バイト単位の最短の有効な送信が優先されます。

バウンティ

この問題は、約4年前にプロジェクトオイラーフォーラムでここで議論されましたが、証明可能な多項式時間アルゴリズム(に関してN)を思い付くことができませんでした。したがって、私はこれを達成した最初の提出物に+200の報奨金を授与するか、不可能であることを証明します。


多項式時間アルゴリズムまたはリダクションを使用したNP硬さの証明を考え出すのに1週間以上費やしました。ここで誰かがこれについて何か進歩をしましたか?
エンリコボルバ

回答:


4

Brachylog、28バイト

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

オンラインでお試しください!

これは本当に遅いです。に約30秒かかり、N = 3に12分たっても完了しませんでしたN = 4

説明

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

より高速なバージョン、39バイト

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

これには、コンピューターで約50秒かかりますN = 4

これは、ランダムな順列をとる代わりに、サブセットのサブセットを平均で並べ替える以外は同じプログラムです。したがって、の{⟨+/l⟩/₁/₁}ᵒ代わりに使用しますp

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

浮動小数点数と整数が値ではなく型によって順序述語と比較されるというばかげたバグを発見したため、浮動小数点平均を取得する必要があります(これは、両方の平均を比較<ᵈせずに使用する理由でもあり<₁ます。後者はそれを必要とします二重反転のトリックが機能します)。


@JonathanAllanが他のコメントで言及しているので、私はゆっくりとこの問題に取り組むことを計画していましたが、おそらくこのようなものを思いつくのに数週間遅れています!(ほとんどのBrachylogの回答のように)結局のところ、質問自体をきちんと修正したように見えます。
スンダ

@sundarはいつでも戻って解決策を再発見することができます!
18

3

CJam(81バイト)

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

オンラインデモ4妥当な時間内に入力を実行する必要がありますが、それ以上の入力では試しません。

解剖

{                 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バイト

素朴でかなり遅い再帰検索。TIOで最初の7つの項を計算するのに約15秒かかります。

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

オンラインでお試しください!

または、最長の増加元セットシーケンスを出力するこの修正バージョンテストします。

どうやって?

{12n}a

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

再帰部:

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

1

Pythonの3205の 197 184 182バイト

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*

オンラインでお試しください!


sum代わりに使用する197バイトchain.from_iterable
-ovs

@ceilingcatありがとうございます。
ジョナサンフレッチ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.