連続番号なしで1からnまでカウントする


19

ゴール

整数nn > 1)が与えられます。あなたは、出力がどのように多くの整数の順列必要1nそこから開始され1、最後にn、そして1によって異なる2つの連続した整数を持っていません。

あなたが完全グラフを取る場合は別の方法として、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、2つのソリューションしかありません(1-4-2-5-3-6もう1つです)。

したがって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-12n-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の指数が式の入力であり、結果が乗算係数であることがわかります。そこから式を推定する方法を1バイト単位で最短の答えを有するものであってもよい
クリスチャンはWesterbeek

1
シーケンスの生成関数と呼ばれる@ChristiaanWesterbeek 。シーケンス自体よりも閉じた形の生成関数を備えた多くのシーケンスが存在します。
カーマイスター

回答:


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
うまく動作し、よくやった:)
フィリップ

1
この問題には本当に素晴らしい進歩がありましたが、解決策はまだ最短です。また、ゼリーよりも高速です。おめでとうございます!
フィリップ

19

Mathematica、58バイト、polynomial(n)time

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

使い方

順列をブルートフォースで反復するのではなく、包含-除外の原則を使用して組み合わせでカウントします。

Sはすべての順列の集合とする[1、...、n]はσと1 = 1、σ N = N、およびSは聞かせて、私は順列の集合σ∈Sように|σ I - σ I + 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 | kと[ i 1i 2、…、i k − 1i k ] の連続したインデックスの実行回数jのみに依存します。便宜上、i 1 = 0とi k = nを修正します。具体的には、

| S I 2 ∩⋯∩S I K - 1 | = 2 J - 2N - K)] 2≤ JKN
| S iは2 ∩⋯∩S I K - 1 | = 1、j = 1、k = n + 1。

このようなインデックスセットの数[ i 1i 2、…、i k − 1i k ]はj回実行されます

K - 1 C J - 1)(N - k個の CのJ - 2)、2≤用JKN
1、のためにJ = 1、K = N + 1。

結果は

(-1)のn - 12≤ KN Σ 2≤ JK (-1)K - 2K 1 - C J - 1)(N - K C J - 2)2 J - 2nk)!

jの内部合計は、超幾何2 F 1関数を使用して記述できます。

(-1)のn - 12≤ KN(-1)KK - 1)2 F 1(2 - KK - N ; 2; 2)(N - K)!

絶対値を使用して-1のべき乗をゴルフで解くPfaff変換を適用します。

(-1)のn - 12≤ KN(-1)NK - 1)2 F 1KK - N ; 2; 2)(N - K)!
= | -1 +Σ 1≤ KNK - 1)2 F 1KK - N ; 2; 2)(N - K!)|。

デモ

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
私の心は吹き飛ばされて、良い仕事
フィリップ

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)

申し訳ありませんが、テストケースを満たしていません
フィリップ

1
ええ、あなたはOkxと同じ間違いをしました。私は最初に犯しました。2番目の数値を2にすることはできず、最後から2番目の数値をn-1にすることはできないという事実を考慮する必要があります
-ETHproductions

@Philippeが修正しました。
ジョナサンアラン

を使用することIỊṀは有効ではないと思います。具体的には、-2たとえばそこにデルタの1つがある場合はどうなりますか?IAỊṀ+1で修正できます。
エリックアウトゴルファー

1
@JonathanAllan Ooh戻ってきたと思ったx <= 1
エリックアウトゴルファー

5

Japt19 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もahahを超えることができない
フィリップ

@Philippe私はそれほど速く受け入れることをお勧めしません、これは05AB1EまたはJellyでもっと短くなると確信しています;-)
ETHproductions

テストケースで失敗します1
Okx

2
@Okx OPは、想定できることを指定していますn > 1
-ETHproductions


5

Haskell、76 65バイト

@xnorのおかげで11バイト節約されました。

@ChristiaanWesterbeek Q_recの検索結果の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ありませんが、結果を貼り付けたくありません...


ちなみに、派手な数学を使用せずに、(超)ブルートフォースを使用しないことは可能です。まず、すべての順列を見る代わりに、部分的な順列を見て、それらがまだ無効でない場合にのみ拡張します。で始まるすべての順列を見るのは無駄1 6 5です。第二に、一部の順列は1 3 5 71 5 3 7有効な継続とまったく同じであるため、一緒に処理します。これらのアイデアを使用してn=16 、最大0.3秒で値を計算できました。


係数を抽出することにより、ドットのように短い再帰式を記述できますf n=sum$zipWith((*).f)[n-5..][n-4,1,10-2*n,4,n-2]
-xnor

@xnorそう、ありがとう!
クリスチャンシーバーズ

これは良い仕事ですが、このコミュニティが思いついた結果に驚いています!残念、ゴルフです^^
フィリップ

4

Python、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)))

かなり速く、良い仕事に見えます!
フィリップ


3

Mathematica、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

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

から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)いつを要求するだけなn>1ので、何を返すかは関係ありませんn=1。また、私f(1)=1は正しいと思います。
クリスチャンシーバーズ

特別なケースを組み合わせてn<6?n==1|0:、さらに2文字の保存を行うことができます。
ピーターテイラー

すばらしいです。これらの2つのコメントを調整しました。
クリスティアアンウェスターベーク

1
そして、用語を並べ替えると評価の順序に依存することによって、それは60まで取得することが可能です:f=n=>n--<6?!n|0:f(n)*--n+4*f(n--)-2*f(n--)*--n+f(n)*++n+f(n)
ピーター・テイラー

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

Mathematica、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

Python 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バイト短くなっています。(Python 3では、reduceいらいらすることに移動しましたfunctools。)

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.