Ex-Увеличивающаяся последовательность набора


11

Фон

Последовательность возрастающих множеств порядка определяется как последовательность целочисленных множеств S 1 , S 2 , , S n, которая удовлетворяет следующему:NS1,S2,,SN

  • Каждый является непустым подмножеством { 1 , 2 , , N } .Sя{1,2,,N}
  • Для , S яS я + 1 = , т.е. любые две последовательные наборы не имеют общих элементов.1я<NSяSя+1знак равно
  • Для среднее (среднее значение) S i строго меньше, чем среднее значение S i + 1 .1я<NSяSя+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

правила

Применяются стандартные правила . Побеждает самая короткая действительная передача в байтах.

премия

Эта проблема обсуждалась здесь на форуме Project Euler около 4 лет назад, но нам не удалось придумать доказуемый алгоритм за полиномиальное время (в терминах N). Поэтому я присуждаю премию +200 к первому представлению, которое достигнет этого, или докажу его невозможность.


Я потратил больше недели, пытаясь придумать алгоритм за полиномиальное время или доказательство NP-твердости, используя сокращение. Кто-нибудь здесь добился прогресса в этом?
Энрико Борба

Ответы:


4

Брахилог , 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 упомянул об этом в другом комментарии), но я, вероятно, несколько недель назад придумал что-нибудь подобное! Мне нравится, как (как и большинство ответов на брахилог), в конце концов, это выглядит как аккуратное подтверждение самого вопроса.
sundar - Восстановить Монику

@sundar, вы всегда можете вернуться к нему позже и попытаться заново найти решение!
Фатализировать

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 байт

Наивный и довольно медленный рекурсивный поиск. Требуется около 15 секунд, чтобы вычислить 7 первых слагаемых в 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

Попробуйте онлайн!

или протестируйте эту модифицированную версию, которая выводит самую длинную последовательность из возрастающего набора.

Как?

{1,2,...,N}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 3 , 205 197 184 182 байта

  • Сохранено восемь двадцать один байт благодаря овам .
  • Сохранено два байта благодаря функциюcatcat .
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*

Попробуйте онлайн!


Использование 197 байтовsum вместо chain.from_iterable.
овс

@ceilingcat Спасибо.
Джонатан Фрех
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.