이전 증가 세트 시퀀스


11

배경

전 증가 세트 서열 순서의 정수 세트의 시퀀스로서 정의된다 S 1 , S 2 , , S 만족시키는 다음에스1,에스2,,에스

  • 의 비어 있지 않은 부분 집합 { 1 , 2 , ,에스나는 .{1,2,,}
  • 옵션 , S S I + 11나는< , 임의의 두 개의 연속적인 세트에 공통의 요소가 존재하지 않는 즉.에스나는에스나는+1=
  • 들면 의 평균 (평균값) S 엄격 이하의보다 S I + 1 .1나는<에스나는에스나는+1

도전

양의 정수가 주어지면 N가장 긴 ex- 증가 세트 순서의 길이를 출력하십시오 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 년 전에 Project Euler 포럼 에서 논의 되었지만, 우리는 다항식 시간 알고리즘을 제시하지 못했습니다 (의 관점에서 N). 따라서 나는 이것을 달성하거나 불가능하다는 것을 증명하는 첫 번째 제출물에 +200 현상금을 수여합니다.


나는 일주일 동안 다항식 알고리즘이나 축소를 사용하는 NP 경도 증명을 생각해 보았습니다. 여기 누구든지 이것에 대해 진행 한 적이 있습니까?
Enrico Borba

답변:


4

Brachylog , 28 바이트

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

온라인으로 사용해보십시오!

정말 느려요. 약 30 초가 걸리고 N = 312 분 후에는 완료되지 않았습니다 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-복원 모니카

@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

자바 스크립트 (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

온라인으로 사용해보십시오!

또는 가장 긴 증분 세트 시퀀스를 출력하는 이 수정 된 버전테스트하십시오 .

어떻게?

{1,2,,}

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

파이썬 3 , 205 (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 감사합니다.
Jonathan Frech
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.