연속적인 숫자없이 1부터 n까지 계산


19

정수 n( n > 1)가 제공됩니다. 당신은 반드시 정수의 많은 순열 출력하는 방법 1n있다 시작 1에서 끝 n, 그리고 한 차이가 두 개의 연속 정수가 없습니다.

당신은 전체 그래프를 가지고가는 경우 또는, K_n및 경로의 가장자리를 제거 1-2-3-...-n하면에서 해밀턴 경로를 계산해야한다 1n남아있는 그래프이다.

예제는 유효한 순열 수 f(n)를 가져 와서 n출력 하는 함수에 사용 되지만 제출은 함수 또는 프로그램 일 수 있습니다.


들면 n = 6, 가능한 해결책은1-3-5-2-4-6

그러나 1-3-5-2-6-4로 끝나지 않기 때문에 유효한 솔루션은 아닙니다 6.

실제로에 대한 n = 6솔루션 1-4-2-5-3-6은 2 개뿐입니다 ( 다른 솔루션 ).

따라서 f(6) = 2.


의 경우 n = 4에 시작하는 유일한 순열 1및 종료에 4있습니다 1-2-3-41-3-2-4. 둘 다에서는에 2인접하여 31만큼 다른 연속적인 정수를 제공합니다. 따라서 f(4) = 0.


테스트 사례

f(6) = 2
f(4) = 0
f(8) = 68
f(13) = 4462848

승리 기준

이것은 가장 짧은 답이이기는 코드 골프입니다.


7
당신은 아이들이, 당신은 단지의 얼마나 많은 순열 확인할 수 없습니다, 볼 [2..n-1]의 어떤 델타를 포함하지 1또는 -1당신이 그 (것)들을 시작으로 또한 모두 선택 안 할, 2또는 끝 n-1...
ETHproductions

1
목록은 1로 시작하고 숫자로 끝나야합니까?
Okx

3
OP는 "연속적"이 아니라 "인접한"을 의미할까요?
Stilez

6
기괴한 순서는 다음과 같습니다. algo.inria.fr/libraries/autocomb/graphs99.ps 6 페이지에 쓰여진 곳에서 Q_ser:=z + 2 z^6 + 10 z^7 + 68 z^8 + 500 z^9 + 4174 z^10 + 38774 z^11 + 397584z^12 + 4462848 z^13 + 54455754 z^14수식을 사용하려고하는데 시간을 소비하지만 시퀀스를 생성하는 구성 요소를 작성할 수는 없습니다. z의 지수가 공식의 입력이고 결과가 곱셈 요소라는 것을 알면 놀랍습니다. 거기에서 수식을 추론 할 수있는 방법은 바이트 단위로 가장 짧은 답을 가진 방법 일 수 있습니다.
Christiaan Westerbeek

1
@ChristiaanWesterbeek : 시퀀스 생성 함수 라고합니다 . 시퀀스 자체보다 닫힌 형식이 더 좋은 생성 함수가있는 많은 시퀀스가 ​​있습니다. 멋진 것입니다!
Carmeister

답변:


6

MATL , 16 바이트

qtq:Y@0&Yc!d|qAs

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

초과 12하는 입력의 경우 메모리가 부족합니다.

설명

q      % Implicitly input n. Push n-1
tq     % Duplicate and subtract 1: pushes n-2
:      % Range [1 2 ... n-2]
Y@     % Matrix with all permutations, each in a row
0      % Push 0
&Yc    % Append n-1 and predend 0 to each row
!      % Tranpose
d      % Consecutive differences along each column
|      % Absolute value
q      % Subtract 1
A      % All: true if all values in each column are non-zero
s      % Sum. Implicitly display

1
잘 작동 :)
Philippe

1
이 문제에 대한 좋은 발전이 있었지만 여전히 솔루션이 가장 짧습니다. 젤리보다 빠릅니다. 축하합니다!
Philippe

19

수학, 58 바이트, 다항식 ( n ) 시간

Abs[Sum[(k-1)Hypergeometric2F1[k,k-#,2,2](#-k)!,{k,#}]-1]&

작동 원리

무차별 대입으로 순열을 반복하는 대신 포함-제외 원칙 을 사용하여 조합을 세어 계산합니다.

S를 σ 1 = 1, σ n = n 인 [1,…, n]의 모든 순열의 집합으로 하고, S i 를 | σ ii + 1 | = 1. 그럼 우리가 찾고있는 수는

| S | − | S 1 ∪ ⋯ ∪ S n − 1 | = ∑ 2 ≤ kn + 1; 1 ≤ i 2 <⋯ < i k -1 < n (−1) k − 2 | S i 2 ∩ ⋯ ∩ S i k -1 |.

이제 | S i 2 ∩ ⋯ ∩ S i k − 1 | [ i 1 , i 2 ,…, i k -1 , i k ]에서 연속 인덱스의 런 수 ( j)k 에만 의존한다. 편의상 i 1 = 0 및 i k = n을 고정한다 . 구체적으로 특별히,

| S i 2 ∩ ⋯ ∩ S i k − 1 | = 2 j − 2 ( nk ) !, 2 ≤ jkn 인 경우
| S i 2 ∩ ⋯ ∩ S i k − 1 | = 1, j = 1 인 경우 k = n + 1

j 런을 갖는 그러한 인덱스 세트 [ i 1 , i 2 ,…, i k -1 , i k ]의 수 는

( k -1 C j -1 ) ( n - k C j -2 ), 2 ≤ jkn ,
1, j = 1, k = n + 1

결과는

(−1) n − 1 + ∑ 2 ≤ kn2 ≤ jk (−1) k − 2 ( k − 1 C j − 1 ) ( nk C j − 2 ) 2 j − 2 ( n - k )!

j에 대한 내부 합계 는 hypergeometric 2 F 1 함수를 사용하여 작성할 수 있습니다 .

(−1) n − 1 + ∑ 2 ≤ kn (−1) k ( k − 1) 2 F 1 (2 − k , kn ; 2; 2) ( nk )!

여기에 절대 값을 사용하여 -1의 거듭 제곱을 퍼지게하는 Pfaff 변환을 적용합니다.

(−1) n − 1 + ∑ 2 ≤ kn (−1) n ( k -1) 2 F 1 ( k , k - n ; 2; 2) ( nk )!
= | −1 + ∑ 1 ≤ kn ( k -1) 2 F 1 ( k , k - n ; 2; 2) ( nk )! |.

데모

In[1]:= Table[Abs[Sum[(k-1)Hypergeometric2F1[k,k-#,2,2](#-k)!,{k,#}]-1]&[n],{n,50}]

Out[1]= {1, 0, 0, 0, 0, 2, 10, 68, 500, 4174, 38774, 397584, 4462848, 

>    54455754, 717909202, 10171232060, 154142811052, 2488421201446, 

>    42636471916622, 772807552752712, 14774586965277816, 297138592463202402, 

>    6271277634164008170, 138596853553771517492, 3200958202120445923684, 

>    77114612783976599209598, 1934583996316791634828454, 

>    50460687385591722097602304, 1366482059862153751146376304, 

>    38366771565392871446940748410, 1115482364570332601576605376898, 

>    33544252621178275692411892779180, 1042188051349139920383738392594332, 

>    33419576037745472521641814354312790, 

>    1105004411146009553865786545464526206, 

>    37639281863619947475378460886135133496, 

>    1319658179153254337635342434408766065896, 

>    47585390139805782930448514259179162696722, 

>    1763380871412273296449902785237054760438426, 

>    67106516021125545469475040472412706780911268, 

>    2620784212531087457316728120883870079549134420, 

>    104969402113244439880057492782663678669089779118, 

>    4309132147486627708154774750891684285077633835734, 

>    181199144276064794296827392186304334716629346180848, 

>    7800407552443042507640613928796820288452902805286368, 

>    343589595090843265591418718266306051705639884996218154, 

>    15477521503994968035062094274002250590013877419466108978, 

>    712669883315580566495978374316773450341097231239406211100, 

>    33527174671849317156037438120623503416356879769273672584588, 

>    1610762789255012501855846297689494046193178343355755998487686}

3
내 마음은 날아 갔고, 잘 했어
Philippe

6

젤리 , 17 16 바이트

ṖḊŒ!ð1;;⁹IỊṀðÐḟL

모나 딕 링크.

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

어떻게?

ṖḊŒ!ð1;;⁹IỊṀðÐḟL - Link: number n
Ṗ                - pop (implicit range build) -> [1,n-1]
 Ḋ               - dequeue -> [2,n-1]
  Œ!             - all permutations of [2,n-1]
    ð       ðÐḟ  - filter discard those entries for which this is truthy:
     1;          -   1 concatenated with the entry
       ;⁹        -   ...concatenated with right (n)
         I       -   incremental differences
          Ị      -   is insignificant (absolute value <=1)
           Ṁ     -   maximum
               L - length (the number of valid arrangements)

죄송하지만 테스트 사례를 충족하지 못합니다
Philippe

1
네, 당신은 Okx와 같은 실수를 저질렀습니다. 두 번째 숫자는 2가 될 수없고 두 번째 숫자는 n-1이 될 수 없다는 사실을 고려해야합니다.
ETHproductions

@Philippe가 고쳤습니다.
Jonathan Allan

사용 IỊṀ이 유효 하다고 생각하지 않습니다 . 구체적으로, -2예를 들어 델타 중 하나가 있다면 ? IAỊṀ+1로 고칠 수 있습니다 .
Outgolfer Erik

1
@JonathanAllan Ooh 나는 그것이 돌아 왔다고 생각했다 x <= 1.
Outgolfer Erik

5

Japt , 19 18 바이트

o2 á è_pU äÉ m²e>1

온라인으로 테스트하십시오! 보다 큰 테스트는 권장하지 않습니다 10.

설명

o2 á è_  pU äÉ  m²  e>1
o2 á èZ{ZpU ä-1 mp2 e>1}
                          : Implicit: U = input integer
o2                        : Create the range [2..U-1].
   á                      : Generate all permutations of this range.
     èZ{               }  : Check how many permutations Z return a truthy value:
        ZpU               :   Push U to the end of Z.
            ä-1           :   Push 1 to the beginning of Z, then take the difference
                          :   of each pair of items.
                m         :   Map each item X to
                 p2       :     X ** 2. This gives a number greater than 1 unless the
                          :     item is 1 or -1.
                    e>1   :   Return whether every item in this list is greater than 1.
                          :   This returns `true` iff the permutation contains no
                          :   consecutive pairs of numbers.
                          : Implicit: output result of last expression

잘 했어! 내 무차별 코드가 어떻게 n = 13을 넘지 못하는지 재미 있음
Philippe

@Philippe 너무 빨리 받아 들일 것을 권장하지 않습니다. 05AB1E 또는 Jelly에서 더 짧을 것이라고 확신합니다. ;-)
ETHproductions

테스트 케이스에서 실패합니다 1.
Okx

2
@Okx OP는 우리가 가정 할 수 있다고 명시했다 n > 1.
ETHproductions


5

하스켈, 76 65 바이트

@xnor 덕분에 11 바이트를 절약했습니다.

Q_rec@ ChristiaanWesterbeek 's find의 7 페이지에 대한 결과를 사용하여

f 1=1
f n|n<6=0
f n=sum$zipWith((*).f)[n-5..][n-4,1,10-2*n,4,n-2]

나는 그들의 다음 결과 ha가 이것과 어떻게 관련 되는지 이해하지 못하지만 속도를 낸 후에 (먼저 메모로, 이전 버전을 본 다음 아래와 같이) 숫자를 얻습니다.

위의 내용은 괜찮지 만 n=20재귀를하지 않는 방법의 예입니다. n>=6일정한 메모리 만 필요 로하는 더 빠른 버전 (전용 )-숫자 만 계속 증가하지 않으면 ...

f n=last$foldl(#)[1,0,0,0,0][6..n]
l#n=tail l++[sum$zipWith(*)l[n-4,1,10-2*n,4,n-2]]

그게

Prelude> f 50
1610762789255012501855846297689494046193178343355755998487686
Prelude> f 500
659178618863924802757920269977240274180092211041657762693634630044383805576666007245903670780603497370173231423527767109899936008034229541700392144282505597945561328426013937966521561345817045884498867592832897938083071843810602104434376305964577943025310184523643816782047883794585616331928324460394146825636085453532404319881264974005968087265587062691285454120911586459406436421191277596121471930913837355151842093002557978076653884610826296845041929616496533544124347765641367732716560025553179112645454078955409181466212732427071306363820080109636358537270466838558068527692374178581063316309789026101221004745226182671038004326069705775312654329754698423385241664984156235692539255677944294995403233446243315371404887473868003155621849544566385172835597260848972758443874423271017007843907015007416644383573987606586308556317833384896267539628278571497402655322562624217658332870157802254043614726316296058329670971054977099155788604175817828380564156329839201579006169173002756295957371639199917376529472990059986681882194726437566769717959443857298155265292535858523609764515938314672724480762724541633037484152303637096

얻는 데 문제는 f 5000없지만 결과를 붙여 넣고 싶지 않습니다 ...


BTW, 멋진 수학을 사용하지 않고 여전히 초강력을 사용하지 않을 수 있습니다. 먼저 모든 순열을 보지 말고 부분 순열을보고 아직 유효하지 않은 경우에만 확장하십시오. 로 시작하는 모든 순열을 보는 것은 아무 소용이 없습니다 1 6 5. 둘째, 같은 몇 가지 부분 순열 1 3 5 7과는 1 5 3 7너무 그들을 함께 처리, 정확히 같은 유효한 연속성을 수 있습니다. 이 아이디어를 사용하여 최대 n=16 0.3s 의 값을 계산할 수 있습니다.


계수를 추출하여 점처럼 짧은 재귀 표현식을 작성할 수 있습니다 f n=sum$zipWith((*).f)[n-5..][n-4,1,10-2*n,4,n-2].
xnor

@xnor 그래, 고마워!
Christian Sievers

이것은 좋은 일입니다.이 커뮤니티가 생각 해낸 결과에 놀랐습니다! 너무 나쁜 골프 ^^
Philippe

4

파이썬, 125 바이트

from itertools import*
lambda n:sum(p[-1]-p[0]==n-1and all(~-abs(x-y)for x,y in zip(p,p[1:]))for p in permutations(range(n)))

꽤 빠르다, 잘 했어!
Philippe


3

매스 매 티카, 66 바이트

Count[Permutations@Range@#,x:{1,__,#}/;FreeQ[Differences@x,1|-1]]&

설명

Function첫 번째 인수로 #.

Count[                                                             (* Count the number of *)
      Permutations@                                                (* permutations of *)
                   Range@#,                                        (* the list {1, ..., #} *)
                           x:{1,__,#}                              (* of the form {1, __, #} *)
                                     /;                            (* such that *)
                                             Differences@x,        (* the list of differences of consecutive elements *)
                                       FreeQ[                      (* is free of elements of the form *)
                                                           1|-1    (* 1 or -1 *)
                                                               ]]&

3

자바 스크립트 (ES6), 100 74 72 60 바이트

f=n=>n--<6?!n|0:f(n)*--n+4*f(n--)-2*f(n--)*--n+f(n)*++n+f(n)

아래는 @PeterTaylor의 골프 마스터리 이전 버전입니다

f=n=>n<6?n==1|0:(n-4)*f(n-5)+f(n-4)-2*(n-5)*f(n-3)+4*f(n-2)+(n-2)*f(n-1)

인터넷 검색 '0, 2, 10, 68, 500, 4174, 38774, 397584'후에 찾은 종이 에서 Haskell 솔루션을 작성하는 @ChristianSievers의 답변 덕분에 여기에도 순열이없는 Javascript 버전이 있습니다.

용법

for (i=1; i<=20; i++) {
  console.log(i, f(i))
}

1 1 
2 0 
3 0 
4 0 
5 0 
6 2 
7 10 
8 68 
9 500 
10 4174 
11 38774 
12 397584 
13 4462848 
14 54455754 
15 717909202 
16 10171232060 
17 154142811052 
18 2488421201446 
19 42636471916622 
20 772807552752712

1
작업 설명은 f(n)when 만 묻기 n>1때문에 무엇을 반환하는지는 중요하지 않습니다 n=1. 또한 나는 옳다고 생각 f(1)=1합니다.
Christian Sievers

n<6?n==1|0:추가 2 문자 절약 을 위해 특별한 경우를 결합 할 수 있습니다 .
피터 테일러

큰. 나는 그 두 의견에 맞게 조정했습니다.
Christiaan Westerbeek

1
그리고 용어를 재정렬하고 평가 순서에 의존함으로써 60으로 내려갈 수 있습니다.f=n=>n--<6?!n|0:f(n)*--n+4*f(n--)-2*f(n--)*--n+f(n)*++n+f(n)
Peter Taylor

1

Brachylog , 26 바이트

{⟦₁pLh1&~tLs₂ᶠ{-ȧ>1}ᵐ}ᶜ|∧0

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

설명

{                    }ᶜ       Output = count the number of outputs of:
 ⟦₁pL                           L is a permutation of [1, …, Input]
    Lh1                         The head of L is 1
       &~tL                     The tail of L is the Input
          Ls₂ᶠ                  Find all sublists of length 2 of L
              {    }ᵐ           Map on each sublist:
               -ȧ>1               The elements are separated by strictly more than 1
                       |      Else (no outputs to the count)
                        ∧0    Output = 0



0

수학, 134 바이트

(s=Permutations@Range[2,#-1];g=Table[Join[Prepend[s[[i]],1],{#}],{i,Length@s}];Length@Select[Union@*Abs@*Differences/@g,FreeQ[#,1]&])&


테스트 사례 n : 2 ~ 12

{0, 0, 0, 0, 2, 10, 68, 500, 4174, 38774, 397584}


0

파이썬 2 , 105 바이트

lambda n:reduce(lambda a,i:a+[i*a[-5]+a[-4]+2*(1-i)*a[-3]+4*a[-2]+(i+2)*a[-1]],range(2,n),[0,1]+4*[0])[n]

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

이것은 @Christiaan Westerbeek에 의해 발견 된 Philippe Flajolet의 논문을 기반으로 한다. 가능한 순열을 열거하는 Python 3 솔루션 보다 훨씬 빠르고 2 바이트 짧습니다 . (파이썬 3에서는 짜증나게로 옮겨졌습니다 .)reducefunctools

numpy의 내적 제품을 사용하는 버전이 훨씬 짧지 만 넘쳐 넘쳐서 numpy를 가져와야합니다. 그러나 가치가있는 것에 대해 :

lambda n:reduce(lambda a,i:a+[dot([i,1,2-2*i,4,i+2],a[-5:])],range(2,n),[0,1]+4*[0])[n]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.