9erilous 9ermutations


8

注:これは、guest271314の順列の質問をリサイクルする試みです。

ユニークな数字が昇順の10進数の辞書式に並べ替えられた順列の違いを見つけると、興味深いパターンが形成されます。たとえば、123順列があります:

123 132 213 231 312 321

これらの違いを見つけると、シーケンスが得られます

9 81 18 81 9

これらはすべて9で割り切れる(10進数の数字の合計のため)、また回文構造です。

特に、次の番号を使用すると1234、シーケンスが得られます

9 81 18 81 9 702 9 171 27 72 18 693 18 72 27 171 9 702 9 81 18 81 9

693あたりの回文構造を維持しながら、前のシーケンスを拡張します。10シーケンスの長さは1が、それ以上の数を使い始めても、このパターンは常に成り立ちます- 1のための数。メモは、上記使用の数字は、その0 to 9によって、我々は異なった塩基に変化しない、我々は、単に多重数10バツ、たとえば[11211]10=1102+12101+11100=231

あなたの目標は、各要素を9の倍数として返すことにより、このシーケンスを実装することです。たとえば、このシーケンスの最初の23要素は次のとおりです。

1 9 2 9 1 78 1 19 3 8 2 77 2 8 3 19 1 78 1 9 2 9 1

他のいくつかのテストケース(0インデックス付き):

23     => 657
119    => 5336
719    => 41015
5039   => 286694
40319  => 1632373
362879 => 3978052
100    => 1
1000   => 4
10000  => 3
100000 => 3

ルール:

  • 提出物は次のいずれかです。
    • 数値を受け取り、そのインデックスで、0または1のインデックスが付けられた数値を返すプログラム/関数。
    • 数値を取り、0番目または1番目のインデックス付きの番目のインデックスまでを返すプログラム/関数。
    • シーケンスを無限に出力/返すプログラム/関数。
  • 111012345678910
  • これはので、各言語の最短の実装が優先されます!

ノート:

  • これはOEIS A217626です
  • 私は、実際の順列を計算せずに要素を直接計算するソリューションに500の報奨金を提供しています。
  • [124]10[421]10

賞金のタイブレーカーは何ですか?
nwellnhof

2
順列自体の計算には(入力のサイズで)線形時間がかかるので(正しいですか)、「要素を直接計算する」ことにはほとんど意味がありません。あなただけのクールな方法を見たいですか?
user202729 2018

1
1013628799 => -83676269

@ user202729おそらく、OPはログ時間または一定時間のアルゴリズムを必要としていますか?これはOEISシーケンスであるため、このようなアルゴリズムは調査に役立つ場合があります。
Shieru Asakoto

1
OΓ1

回答:


5

ゼリー、9バイト

,‘œ?ŻḌI÷9

オンラインでお試しください!(n番目の要素を出力)

オンラインでお試しください!(最初の20の要素)

説明:

      I÷9      Compute the difference divided by 9 between
 ‘             the (n+1)th
  œ?           permutation
,              and
               the (n)th
  œ?           permutation
    Ż          of [0,1,2,...n]
     Ḍ         converted to decimal.

(ジェリーには、ほぼ線形の時間でリストのth番目の順列œ?を計算する組み込み関数がありnます。非常に便利です。)


4

チャコール、71バイト

≔⟦N⊕θ⟧ηW⌈η≧÷L⊞OυEη﹪κ⊕Lυη≔⁰δF²«≔Eυλζ≔⟦⟧ηF⮌Eυ§κι«⊞η§ζκ≔Φζ⁻μκζ»≦⁻↨ηχδ»I÷δ⁹

オンラインでお試しください!リンクはコードの詳細バージョンです。説明:

≔⟦N⊕θ⟧η

入力と入力より1つ多いリストを取得します。

W⌈η

両方の値がゼロになるまで繰り返します。

≧÷L⊞OυEη﹪κ⊕Lυη

両方の値で階乗ベース変換を実行します。これは私が実際にリストで使用したのは初めてです!

≔⁰δ

結果をクリアします。

F²«

各階乗の基数をループします。

≔Eυλζ

0から長さ-1までの数字のリストを作成します。

≔⟦⟧η

結果を空のリストに初期化します。

F⮌Eυ§κι«

階乗の基数の桁をループします。

⊞η§ζκ

結果に次の置換桁を追加します。

≔Φζ⁻μκζ»

リストからその数字を削除します。

≦⁻↨ηχδ»

順列を10を底とする数として変換し、それまでの結果を引きます。

I÷δ⁹

最終結果を9で割り、文字列にキャストします。


3

Perl 6、82バイト

-Jo Kingのおかげで2バイト

->\n{([-] map {$/=[^n];:10[map {|splice $/,$_,1},[R,] .polymod(1..n-2)]},n+1,n)/9}

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

0インデックス。すべての順列を列挙するわけではありません。理論的にはすべてのnで機能するはずですが、n> 65536の場合、「配列のフラット化で引数が多すぎます」と表示されます。

次の80バイトバージョンは、nが最大98!-2で機能し、はるかに高速です。

{([-] map {$/=[^99];:10[map {|splice $/,$_,1},[R,] .polymod(1..97)]},$_+1,$_)/9}

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

次の53バイトバージョンは、理論的にはすべてのnで機能しますが、n> = 20の場合、「20を超える要素の順列を拒否する」ことで回避されます。

{[-](map {:10[$_]},permutations(1..$_+1)[$_,$_-1])/9}

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


2

JavaScript(Node.js)、134バイト

n=>(F=_=>f>n?((G=(n,z=0,x=f,y=l,b=[...a])=>y?G(n%(x/=y),+b.splice(n/x,1)+z*10,x,y-1,b):z)(n--)-G(n))/9:F(a.push(++l),f*=l))(a=[l=f=1])

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

1インデックス付き。

@ guest271314の意見は正しい。直接置換計算はより短いです...

説明

n=>(                           // Function -
 F=_=>                         //  Helper func to calculate length needed
 f>n?                          //   If f > n (meaning the length is enough) -
  (
   (
    G=(                        //    Helper func to calculate permutation value -
     n,
     z=0,                      //     Initial values
     x=f,                      //     Made as copies because we need to alter
     y=l,                      //     these values and the function will be
     b=[...a]                  //     called twice
    )=>
    y?                         //     If still elements remaining -
     G(
      n%(x/=y),                //      Get next element
      +b.splice(n/x,1)+z*10,   //      And add to the temporary result
      x,
      y-1,                     //      Reduce length
      b                        //      Remaining elements
     )
    :z                         //     Otherwise return the permutation value
   )(n--)-G(n)                 //    Calculate G(n) - G(n - 1)
  )/9                          //    ... the whole divided by 9 
 :F(
  a.push(++l),                 //   Otherwise l = l + 1, push l into the array
  f*=l                         //   ... and calculate l!
 )
)(
 a=[l=f=1]                     //  Initial values
)

元のソリューション(159バイト)

n=>(x=l=t=0n,P=(a,b=[])=>n?""+a?a.map(z=>P(a.filter(y=>y-z),[...b,z])):(v=b.reduce((u,y)=>u=u*10n+y),x?--n?0:t=v-x:0,x=v):0)([...Array(n+1))].map(_=>++l))&&t/9n

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

リンクはパフォーマンスのために作られた長いバージョンへのリンクです。デモを動作させるためにArray(n+1)なりArray(Math.min(n+1,15))ます。理論的には、無限まで(実際にはスタック制限まで)機能します。

説明

説明しきれないほどたくさんあります。

n=>(                             // Function
 x=l=t=0n,                       // Initialization
 P=(                             // Function to determine the permutation -
  a,                             //  remaining items
  b=[]                           //  storage
 )=>
 n?                              //  if we haven't reached the required permutation yet - 
  ""+a?                          //   if we haven't the last layer of loop - 
   a.map(                        //    loop over the entries -
    z=>      
    P(                           //     recurse -
     a.filter(y=>y-z),           //      pick out the selected number
     [...b,z]                    //      append to next 
    )
   )
  :(                             //   if we are at the last layer -
   v=b.reduce((u,y)=>u=u*10n+y), //    calculate the value of the permutation
   x?                            //    if not the first number -
    --n?                         //     if not the last -
     0                           //      do nothing
    :t=v-x                       //     else calculate difference
   :0,                           //    else do nothing
   x=v                           //    record ot anyway
  )
 :0                              //   else do nothing
)
(
 [...Array(n+1)].map(_=>++l)     // the list of numbers to permute
)&&t/9n                          // last difference divided by 9

FWIW、この実装がまでのすべての違いを返さない場合n、このソリューションstackoverflow.com/a/34238979は、隣接する2つの順列、またはインデックスによって直接置換の数表現を取得する手段を提供します。(f(n) - f(n-1))/9この選択された回答タイプの出力を生成するには、「数値を受け取り、そのインデックスで、0または1のインデックスが付けられた数値を返すプログラム/関数」というルールと一致します。
guest271314

2

Pyth、15 14バイト

.+m/i.PdSQT9,h

n番目の項を返します。こちらでお試しください。

.+                     Find the differences between adjacent elements of
   m                   mapping lambda d:
      .PdSQ                the dth permutation of input,
     i     T               converted to base 10
    /       9              divided by 9
             ,         over [Q+1,Q]
               h Q
               Q

2

J44、41バイト

(9%~[:(2-~/\])i.(10#.1+A.)[:i.@>.!inv)@>:

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

注:10でも機能します!テストケースですが、そこで精度が失われます...

元の説明

(9 %~ [: (2 -~&(10&#.)/\ ]) 1 + i. A. i.@>.@(!inv))@>:
(                                                 )@>: NB. add one to input
                                                       NB. since n-1 deltas
                                                       NB. gives n results
                                                       NB. call that "n"
(                               i.                )    NB. take the first n
(                                  A.             )    NB. lexicographically
                                                       NB. sorted items of
(                                     i.@         )    NB. 0 up to...
(                                        >.@      )    NB. the ceil of...
(                                           (!inv))    NB. the inverse of 
                                                       NB. the factorial
(                           1 +                   )    NB. add 1 so our
                                                       NB. lists start at 1
                                                       NB. instead of 0
(     [: (                )                       )    NB. apply what's in 
                                                       NB. parens to that
                                                       NB. list of lists
(        (2 -~        /\ ])                       )    NB. take successive
                                                       NB. differences BUT
(        (    &(10&#.)    )                       )    NB. convert each list
                                                       NB. to a base 10
                                                       NB. number first
(9 %~                                             )    NB. and divide every
                                                       NB. items of the
                                                       NB. result by 9

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.