シーケンスの並べ替え


23

前書き

次のシーケンス(非負の整数)を観察してみましょう。

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ...

たとえば、最初の3つの数字を見てみましょう。これらは0, 1, 2です。このシーケンスで使用される番号は、6つの異なる方法で注文できます。

012   120
021   201
102   210

それで、F(3)= 6としましょう。別の例はF(12)です。これには数字が含まれます。

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11

または、連結バージョン:

01234567891011

これを再配置する方法を見つけるには、まずこの文字列の長さを調べる必要があります。この文字列の長さは14です。14を計算します!。ただし、たとえば、最終的な文字列を中断することなく場所を交換できます。2つのゼロがあるため、2つあります!順序を乱すことなくゼロを変更する方法。4つもあるので、4つあります!切り替える方法。合計をこれらの2つの数値で除算します。

これは14個あります!/(4!×2!) = 1816214400文字列を配置する方法01234567891011。したがって、F(12)= 1816214400と結論付けることができます。

タスク

与えられたN、出力F(N) 。導入を必要としない人のために。F(N)を計算するには、最初に最初のN個の非負整数を連結し(たとえば、N = 12の場合、連結された文字列は01234567891011)、この文字列を配置する方法の数を計算します。

テストケース

Input:   Output:
0        1
1        1
2        2
3        6
4        24
5        120
6        720
7        5040
8        40320
9        362880
10       3628800
11       119750400
12       1816214400
13       43589145600
14       1111523212800
15       30169915776000

注意

回答の計算は10秒の制限時間内に計算する必要があり、総当たり攻撃許可されません

これはであるため、バイト数が最小の提出が勝ちです!


出力は10正しいですか?繰り返し桁が始まるのは10未満である必要があるように感じます。
ジオビット

@Geobits最初の10数字は0, 1, 2, 3, 4, 5, 6, 7, 8, 9です。10桁の数字なので、結果は10!です。
アドナン

ああ、そう。私の0場合、カウントがオフになったと思います(愚かな空の文字列)。
ジオビット

1
もう心配する必要はありません。コメントを投稿したとき、抜け穴の提案は+4でした。現在は+9です。
デニス

1
このパズルに関する興味深い数学の質問は次のとおりです。Nに対するF(N)の価値は何ですか?NにはF(N)/ F(N-1)<Nの値がいくつかありますが、通常はわずかに大きくなります。私はかなり確信しているよF(N)ではないO(N!)、それはlog F(N)あるO(log N!)が、それらはただ...勘です
RICI

回答:


5

ゼリー、17 15バイト

R’DFµ=€QS;@L!:/

オンラインでお試しください!または、すべてのテストケースを一度に検証します

使い方

R’DFµ=€QS;@L!:/    Main link. Input: n

R                  Yield [1, ..., n] for n > 0 or [0] for n = 0.
 ’                 Decrement. Yields [0, ..., n - 1] or [-1].
  D                Convert each integer into the list of its decimal digits.
   F               Flatten the resulting list of lists.
    µ              Begin a new, monadic chain. Argument: A (list of digits)
       Q           Obtain the unique elements of A.
     =€            Compare each element of A with the result of Q.
                   For example, 1,2,1 =€ Q -> 1,2,1 =€ 1,2
                                           -> [[1, 0], [0, 1], [1, 0]]
        S          Sum across columns.
                   This yields the occurrences of each unique digit.
         ;@L       Prepend the length of A.
            !      Apply factorial to each.
             :/    Reduce by divison.
                   This divides the first factorial by all remaining ones.

これは本当にゼリーですか?多くのASCII文字が表示されます。
ルイスメンドー

3
彼らはいつもなんとかしてこっそりこっそり
デニス

10

ES6、118の 81 78バイト

n=>[...[...Array(n).keys()].join``].map(c=>r/=(o[c]=-~o[c])/i++,o=[],i=r=1)&&r

数字を連結する短い方法があることを教えてくれる人がいnます。

@ edc65のアイデアを取り入れてステロイドで実行することで、37バイトの節約になりました。(代わりに「|」を使用して余分なバイトを保存&&しますが、結果は31ビットに制限されます。)

編集:@ edc65のおかげで、さらに3バイトを保存しました。


数字の連結を短縮する方法が見つかりませんでした。ただし、残りはすべて短くすることができます
-edc65

2バイトの保存reducen=>[...[...Array(n).keys()].join``].reduce((r,c,i)=>r*++i/(o[c]=-~o[c]),1,o=[])
user81655

1
うわー!ただし、78の方が優れていますn=>[...[...Array(n).keys()].join``].map(c=>r/=(o[c]=-~o[c])/i++,o=[],i=r=1)&&r
。– edc65

1
@ edc65 r/=(...)/i++r*=i++/(...)?それは私が今まで見た中で最も滑dicなゴルフです!
ニール

2
私はあなたがそこに正規表現を持っていると思ったので、私はしばらく止めなければなりませんでした。
ママファンロール

7

APL(Dyalog Extended)、13バイト

×/2!/+\⎕D⍧⍕⍳⎕

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

完全なプログラム。用途⎕IO←0ます。

使い方

×/2!/+\⎕D⍧⍕⍳⎕
               Take input from stdin (N)
               Generate range 0..N-1
               Stringify the entire array (S)
                (The result has spaces between items)
       D       The character array '0123456789'
               Count occurrences of each digit in S
×/2!/+\         Calculate multinomial:
     +\           Cumulative sum
  2!/             Binomial of consecutive pairs
×/                Product

多項計算は、次の事実に基づいています。

(a1+a2++an)!a1!a2!an!=(a1+a2)!a1!a2!×(a1+a2++an)!(a1+a2)!a3!an!

=(a1+a2)!a1!a2!×(a1+a2+a3)!(a1+a2)!a3!×(a1+a2++an)!(a1+a2+a3)!an!

==(a1+a2a1)(a1+a2+a3a1+a2)(a1++ana1++an1)


1
そして、これがプログラマが数学を学ぶべき理由です。
匿名

@Anonymous…数学的に傾斜したプログラミング言語を使用します。
アダム

5

MATL、21バイト

:qV0h!4Y2=sts:pw"@:p/

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

説明

:q     % implicitly input N, and generate vector [0, 1, ..., N-1]
V      % convert to string representation of numbers. Contains spaces,
       % but no matter. Only characters '0', ..., '9' will be counted
0h     % append 0 character (not '0'), so that string is never empty
!      % convert string to column char array
4Y2    % string '0123456789' (row char array)
=      % test all pairs for equality
s      % sum each column. For N = 12 this gives [2, 4, 1, 1, ..., 1]
t      % duplicate
s      % compute sum. For N = 12 this gives 14
:p     % factorial
w      % swap. Now vector [2, 4, 1, 1, ..., 1] is on top
"      % for each number in that vector
  @:p  %   factorial
  /    %   divide
       % implicitly end loop
       % implicitly display

@Adnan解決しました。そして、より少ないバイトで:-)
ルイスメンドー

とてもいいですね!:)
アドナン

@Adnanありがとう!説明を追加しました
ルイスメンドー

5

Python 2、142 137 101 97バイト

(についての提案を@adnanに感謝しますinput

Cバージョンからの増分計算を適用)

f=1;v=10*[0]
for i in range(input()):
 for h in str(i):k=int(h);v[k]+=1;f=f*sum(v)/v[k]
print f

階乗を使用した元のバージョン

import math
F=math.factorial
v=10*[0]
for i in range(input()):
 for h in str(i):v[int(h)]+=1
print reduce(lambda a,x:a/F(x),v,F(sum(v)))

実際、上記の唯一のゴルフは math.factorial Fいくつかのスペースをて除外することなので、おそらくより短いPythonソリューションがあります。

説明が必要な場合、 v、各桁の頻度のカウントを維持します。カウントは、指定された範囲内の各数字の各桁ごとに更新されます。

元のバージョンでは、標準式を使用して順列の数(のΣf計算I)!/π(F Iを!)。現在のバージョンでは、この計算は数字が見えるように乗算と除算を分配することにより増分的に行われます。整数除算が常に正確であることは明らかではないかもしれませんが、各除算は連続する整数の乗算kに従う必要があるという観察に基づいて証明するのは簡単ですk。したがって、これらの乗算の1つはkです。(それは直観であり、証拠ではありません。)

元のバージョンは、10個のbignum除算しか行わないため、大きな引数の場合は高速です。bignumを小さな整数で除算することは、bignumをbignumで除算するよりも高速ですが、数千個のbignum除算がある場合は、少し遅くなります。


f = f * sum(v)/ v [k]-> f * = sum(v)/ v [k]は1バイトを節約します
ミッコヴィルッキラ

@superflux:しかし、それは同じ意味ではありません。
リチ

5

Python 2、197バイト(編集:4バイト保存、Thomas Kwaに感謝!)

import math
l,g,f,p,r,s=[],[],math.factorial,1,range,str
for x in r(int(input())):l.append(s(x))
l="".join(l)
for y in r(10):b=s(l).count(s(y));g.append(f(b));
for c in g:p*=y
print f(int(len(l)))/p

ゴルフをしていない:

import math

l=[] #list of the numbers from 0 to n
exchange_list=[] #numbers that can be exchanged with each other, ie      repeats

multiplied = 1 #for multiplying the digits by each other
n = int(input())

for x in range(n): #put all the numbers from 0-n into the list
    l.append(str(x))

l = "".join(l) #put all the digits in a string to remove repeats

for x in range(10): #look at all the digits and check how many are in the     list/string
    count = str(l).count(str(x))
    if count > 1: #if there is more than 1 of the digit, put the factorial of the amount of - 
        exchange_list.append(math.factorial(count)) # - appearances into the exchange list.

for x in exchange_list: #multiply all the values in the list by each other
    multiplied*=x

print math.factorial(int(len(l)))/multiplied #print the factorial of the  length of the string 
#divided by the exchanges multiplied

1
プログラミングパズルとコードゴルフへようこそ!この回答にはVLQ(非常に低品質)のフラグが付けられていますが、これには説明が含まれていないか、ここでは通常のバージョンではありません。あなたの答えが機能し、「コードのみ」であることからそれを改善すると仮定すると、それは非常に良いようです!

range(0,10)することができますrange(10)
-lirtosiast

4

CJam、21 19バイト

ri,s_,A,s@fe=+:m!:/

ここでテストしてください。

説明

ri   e# Read input and convert to integer N.
,    e# Get a range [0 1 ... N-1].
s    e# Convert to string, flattening the range.
_,   e# Duplicate and get its length.
A,s  e# Push "012345789".
@fe= e# Pull up the other copy of the string and count the occurrences of each digit.
+    e# Prepend the string length.
:m!  e# Compute the factorial of each of them.
:/   e# Fold division over the list, dividing the factorial of the length by all the other
     e# factorials.

3

JavaScript(ES6)、100

n=>(f=[...[...Array(n).keys()].join``].map(c=>(k[c]=~-k[c],p*=i++),i=p=1,k=[]),k.map(v=>p/=f[~v]),p)

テスト

F=n=>(f=[...[...Array(n).keys()].join``].map(c=>(k[c]=~-k[c],p*=i++),i=p=1,k=[]),k.map((v,i)=>p/=f[~v]),p)

// Less golfed
U=n=>( // STEP 1, count digits, compute factorials
      f= // will contain the value of factorials 1 to len of digits string
      [...[...Array(n).keys()].join``] // array of cancatenated digits
      .map(c=> // execute the following for each digit
           (
            k[c]=~-k[c], // put in k[c] the repeat count for digit c, negated 
            p*=i++       // evaluate factorial, will be stored in f
           ),i=p=1,k=[]),// initialisations
       // at the end of step 1 we have all factorials if f and max factorial in p
       // STEP 2, divide the result taking into account the repeated digits
      k.map(v=>p/=f[~v]), // for each digit, divide p by the right factorial (~v === -v-1)
  p // return result in p
) 

// Test
console.log=x=>O.textContent+=x+'\n'

for(j=0;j<=15;j++) console.log(j+' '+F(j))
<pre id=O></pre>


k[c]=~-k[c]と同義ではありません--k[c]か?
-usandfriends

1
@usandfriendsいいえ、k [c]が未定義の場合--k [c]はNaN
edc65

おお、素晴らしく階乗の配列。
ニール

...必要ありませんが。最新のアップデートをご覧ください。
ニール

3

Pyth、18バイト

/F.!M+lJ.njRTQ/LJT

オンラインで試す:デモンストレーション

/F.!M+lJ.njRTQ/LJT   implicit: Q = input number
          jRTQ       convert each number in [0, ..., Q-1] to their digits
        .n           flatten to a single list
       J             store this list in J
              /LJT   for each digit count the number of appearances in J
     +lJ             prepend the length of J
  .!M                compute the factorial for each number
/F                   fold by division

3

Haskell、92バイト

import Data.List
h n|l<-sort$show=<<[0..n-1]=foldl1 div$product.map fst.zip[1..]<$>l:group l

使用例: h 12 -> 1816214400

使い方

l<-sort$show=<<[0..n-1]       -- bind l to the sorted concatenated string
                              -- representations of the numbers from 0 to n-1
                              -- e.g. n=12 -> "00111123456789"

               l: group l     -- group the chars in l and put l itself in front
                              -- e.g. ["00111123456789","00","1111","2",..."9"]
            <$>               -- map over this list
    product.map fst.zip[1..]  -- the faculty the length of the sublist (see below)  
                              -- e.g. [87178291200,2,24,1,1,1,..,1]
foldl1 div                    -- fold integer division from the left into this list
                              -- e.g. 87178291200 / 2 / 24 / 1

                              -- Faculty of the length of a list:
                  zip[1..]    -- make pairs with the natural numbers
                              -- e.g. "1111" -> [(1,'1'),(2,'1'),(3,'1'),(4,'1')]
          map fst             -- drop 2nd element form the pairs
                              -- e.g. [1,2,3,4]
  product                     -- calculate product of the list

3

C、236の 174 138 121バイト

バイトの大幅な削減に対するriciの功績です。

long long d,f=1;j,s=1,n,b[10]={1};main(d){for(scanf("%d",&n);n--;)for(j=n;j;j/=10,f*=++s)d*=++b[j%10];printf("%Ld",f/d);}

非ゴルフ

long long d,f=1;
j,s=1,n,b[10]={1};

main(d)
{
    scanf("%d",&n); /* get input */
    for(;n--;) /* iterate through numbers... */
        for(j=n;j;j/=10,f*=++s) /* iterate through digits, sum up and factorial */
            d*=++b[j%10]; /* count and factorial duplicates */
    printf("%Ld",f/d); /* print out result */
}

ここで試してみてください


1
-lmをいじらないことで43文字を節約できます。見つかったら数字を数えるだけです#define L long long L d;i,j,k,m,n,s=1,b[10]={1};L f(n){return n?n*f(n-1):1;}main(d){for(scanf("%d",&n);i<n;)for(j=i++;j;j/=10)++b[j%10],++s;for(;m<10;)d*=f(b[m++]);printf("%Ld",f(s)/d);}
。– rici

d:を計算するループでカウントすることもできますがfor(;m<10;)s+=b[m],d*=f(b[m++])、それはさらに2バイトだと思います。
リチ

そりゃ素晴らしい。私は現在のゴルフの取り組みと組み合わせて編集します。
コールキャメロン

ニース:鉱山を見て、階乗計算を元のループに統合する方法を見てみましょう。これには、任意精度の計算がない場合、少し広い範囲で作業するという利点があります。私はそれがさらに20バイトを剃ると思います。
リチ

3

C / bc、233 121 112バイト(3バイトのペナルティを想定|bc

  1. Cole Cameronに触発されて、ハッキーキャラクターの操作を削除し、引数値の算術演算を行います。

  2. argベクトルの使用からscanfに変更されました。

    C[10]={1},n=1,k,t;main(){for(scanf("%d",&k);k--;)for(t=k;t;t/=10)printf("%d/%d*",++n,++C[t%10]);puts("1");}
    

ニーズ bc実際に任意精度の計算を行うがあります。

ゴルフをしないで警告なし:

#include <stdio.h>
int main() {
  int C[10]={1},n=1,k,t;    /* 0 is special-cased */
  for(scanf("%d",&k);k--;)  /* For each integer less than k */
    for(int t=k;t;t/=10)    /* For each digit in t */
      printf("%d/%d*",++n,++C[t%10]);  /* Incremental choice computation */
  puts("1");                /* Finish the expression */
}

図解(私が信頼するアルゴリズムを示しています):

$ for i in {0..15} 100 ; do printf %4d\  $i;./cg70892g<<<$i;done
   0 1
   1 1
   2 2/1*1
   3 2/1*3/1*1
   4 2/1*3/1*4/1*1
   5 2/1*3/1*4/1*5/1*1
   6 2/1*3/1*4/1*5/1*6/1*1
   7 2/1*3/1*4/1*5/1*6/1*7/1*1
   8 2/1*3/1*4/1*5/1*6/1*7/1*8/1*1
   9 2/1*3/1*4/1*5/1*6/1*7/1*8/1*9/1*1
  10 2/1*3/1*4/1*5/1*6/1*7/1*8/1*9/1*10/1*1
  11 2/1*3/2*4/1*5/1*6/1*7/1*8/1*9/1*10/1*11/1*12/2*1
  12 2/1*3/2*4/3*5/2*6/1*7/1*8/1*9/1*10/1*11/1*12/1*13/1*14/4*1
  13 2/1*3/1*4/2*5/3*6/4*7/2*8/1*9/1*10/1*11/1*12/1*13/1*14/1*15/2*16/5*1
  14 2/1*3/1*4/2*5/1*6/3*7/4*8/5*9/2*10/1*11/1*12/1*13/1*14/1*15/1*16/2*17/2*18/6*1
  15 2/1*3/1*4/2*5/1*6/3*7/1*8/4*9/5*10/6*11/2*12/1*13/1*14/1*15/1*16/1*17/2*18/2*19/2*20/7*1
 100 2/1*3/2*4/3*5/1*6/4*7/1*8/5*9/1*10/6*11/1*12/7*13/1*14/8*15/1*16/9*17/1*18/10*19/1*20/11*21/2*22/2*23/12*24/3*25/4*26/5*27/2*28/6*29/2*30/7*31/2*32/8*33/2*34/9*35/2*36/10*37/2*38/11*39/2*40/12*41/3*42/3*43/13*44/4*45/13*46/5*47/6*48/7*49/3*50/8*51/3*52/9*53/3*54/10*55/3*56/11*57/3*58/12*59/3*60/13*61/4*62/4*63/14*64/5*65/14*66/6*67/14*68/7*69/8*70/9*71/4*72/10*73/4*74/11*75/4*76/12*77/4*78/13*79/4*80/14*81/5*82/5*83/15*84/6*85/15*86/7*87/15*88/8*89/15*90/9*91/10*92/11*93/5*94/12*95/5*96/13*97/5*98/14*99/5*100/15*101/6*102/6*103/16*104/7*105/16*106/8*107/16*108/9*109/16*110/10*111/16*112/11*113/12*114/13*115/6*116/14*117/6*118/15*119/6*120/16*121/7*122/7*123/17*124/8*125/17*126/9*127/17*128/10*129/17*130/11*131/17*132/12*133/17*134/13*135/14*136/15*137/7*138/16*139/7*140/17*141/8*142/8*143/18*144/9*145/18*146/10*147/18*148/11*149/18*150/12*151/18*152/13*153/18*154/14*155/18*156/15*157/16*158/17*159/8*160/18*161/9*162/9*163/19*164/10*165/19*166/11*167/19*168/12*169/19*170/13*171/19*172/14*173/19*174/15*175/19*176/16*177/19*178/17*179/18*180/19*181/10*182/20*183/20*184/20*185/20*186/20*187/20*188/20*189/20*190/20*1

そして、bcを通るパイプで(そしてF(1000)の計算を追加します:

$ time for i in {0..15} 100 1000; do printf "%4d " $i;./cg70892g<<<$i|bc;done
   0 1
   1 1
   2 2
   3 6
   4 24
   5 120
   6 720
   7 5040
   8 40320
   9 362880
  10 3628800
  11 119750400
  12 1816214400
  13 43589145600
  14 1111523212800
  15 30169915776000
 100 89331628085599251432057142025907698637261121628839475101631496666431\
15835656928284205265561741805657733401084399630568002336920697364324\
98970890135552420133438596044287494400000000
1000 45200893173828954313462564749564394748293201305047605660842814405721\
30092686078003307269244907986874394907789568742409099103180981532605\
76231293886961761709984429587680151617686667512237878219659252822955\
55855915137324368886659115209005785474446635212359968384367827713791\
69355041534558858979596889046036904489098979549000982849236697235269\
84664448178907805505235469406005706911668121136625035542732996808166\
71752374116504390483133390439301402722573240794966940354106575288336\
39766175522867371509169655132556575711715087379432371430586196966835\
43089966265752333684689143889508566769950374797319794056104571082582\
53644590587856607528082987941397113655371589938050447115717559753757\
79446152023767716192400610266474748572681254153493484293955143895453\
81280908664541776100187003079567924365036116757255349569574010994259\
42252682660514007543791061446917037576087844330206560326832409035999\
90672829766080114799705907407587600120545365651997858351981479835689\
62520355320273524791310387643586826781881487448984068291616884371091\
27306575532308329716263827084514072165421099632713760304738427510918\
71188533274405854336233290053390700237606793599783757546507331350892\
88552594944038125624374807070741486495868374775574664206439929587630\
93667017165594552704187212379733964347029984154761167646334095514093\
41014074159155080290000223139198934433986437329522583470244030479680\
80866686589020270883335109556978058400711868633837851169536982150682\
22082858700246313728903459417761162785473029666917398283159071647546\
25844593629926674983035063831472139097788160483618679674924756797415\
01543820568689780263752397467403353950193326283322603869951030951143\
12095550653333416019778941123095611302340896001090093514839997456409\
66516109033654275890898159131736630979339211437991724524614375616264\
98121300206207564613016310794402755159986115141240217861695468584757\
07607748055900145922743960221362021598547253896628914921068009536934\
53398462709898222067305585598129104976359039062330308062337203828230\
98091897165418693363718603034176658552809115848560316073473467386230\
73804128409097707239681863089355678037027073808304307450440838875460\
15170489461680451649825579772944318869172793737462142676823872348291\
29912605105826175323042543434860948610529385778083808434502476018689\
05150440954486767102167489188484011917026321182516566110873814183716\
30563399848922002627453188732598763510259863554716922484424965400444\
85477201353937599094224594031100637903407963255597853004241634993708\
88946719656130076918366596377038503741692563720593324564994191848547\
42253991635763101712362557282161765775758580627861922528934708371322\
38741942406807912441719473787691540334781785897367428903185049347013\
44010772740694376407991152539070804262207515449370191345071234566501\
33117923283207435702471401696679650483057129117719401161591349048379\
16542686360084412816741479754504459158308795445295721744444794851033\
08800000000

real    0m0.246s
user    0m0.213s
sys     0m0.055s

これは、F(5000)-18,592桁の数字-を10秒以内に計算しました。

$ time ./cg70892g3<<<5000|BC_LINE_LENGTH=0 bc|wc -c
18593

real    0m9.274s
user    0m9.273s
sys     0m0.005s

3

Perl 6、117バイト

say $_ <2??1!!permutations(+[(my@n=^$_ .join.comb)]).elems÷[*] ([*] 2..$_ for @n.classify(&unique).values)for lines

そして、より読みやすいファッションで

for (lines) -> $number {
    say 1 and next if $number < 2;
    my @digits = (^$number).join.comb;
    my @duplicates = @digits.classify(&unique).values;
    my $unique_permutations = permutations(+@digits).elems ÷ [*] ([*] 2..$_ for @duplicates);
    say $unique_permutations;
}

3

Perl 5、108バイト

sub f{eval join"*",@_,1}push@a,/./g for 0..<>-1;for$i(0..9){$b[$i]=grep/$i/,@a}say f(1..@a)/f map{f 1..$_}@b

感謝DEV-nullを私に17のバイトを保存するための、およびへjaphy階乗アイデア。


3

05AB1E13 12 11バイト

ÝD¨SāPr¢!P÷

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

Ý             # range [0..input]
 D            # duplicate
  ¨           # drop the last element
   S          # split into digits
    ā         # length range: [1..number of digits]
     P        # product (effectively a factorial)
      r       # reverse the stack
       ¢      # count occurences of each number in the list of digits
        !     # factorial of each count
         P    # product of those
          ÷   # divide the initial factorial by this product

3

Python 2、123バイト

import math
i,b,F="".join(map(str,range(input()))),1,math.factorial
for x in range(10):b*=F(i.count(`x`))
print F(len(i))/b

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

  1. range入力のを単一の文字列に変換します
  2. 文字列に0から9までの各数値が何回現れるかを確認し、それぞれの階乗を取得してから、それらを乗算します
  3. 文字列の長さの階乗をステップ2で計算された数で除算します

2

PowerShell、125バイト

(1..(($b=0..($args[0]-1)-join'').Length)-join'*'|iex)/((0..9|%{$c=[regex]::Matches($b,$_).count;1..($c,1)[!$c]})-join'*'|iex)

入力を受け取り$args[0]、減算し10..その数値から整数の範囲を構築します。-joinこれを文字列にまとめ、として保存します$b.Lengthその文字列を取得し、1..その長さから別の範囲を構築し、-joinそれらの整数とを一緒に*パイプしますInvoke-Expression(同様にeval)。つまり、入力に基づいて数値シーケンスの長さの階乗を構築しました。それが分子です。

それを分ける /を...

分母。範囲0..9を取得してfor-loopを介して送信することで構築されます|%{...}。各反復では、属性結合された.NET 呼び出しのおかげで$c、現在の数字$_が表示される回数に等しいヘルパー変数を設定します。次に、ゼロ以外である限り、その値までの新しい範囲を作成します。はい、多くの場合、これはrangeになり、これはjustと評価されます。それらすべてを一緒に取り、それを再びパイプします。つまり、各桁の出現回数の階乗の積を作成しました。$b[regex]::matches.count1..1..11-join*Invoke-Expression


NB

最大901秒で問題なく入力を処理します。

PS C:\Tools\Scripts\golfing> .\rearranging-the-sequence.ps1 90
1.14947348910454E+159

PS C:\Tools\Scripts\golfing> Measure-Command {.\rearranging-the-sequence.ps1 90} | FL TotalMilliseconds
TotalMilliseconds : 282.587

... Infinity置換可能な文字列の長さはデータ型()に170!適合しますが、適合しないため、出力を超える結果になります。PowerShellは自動的にアップキャストからのことを... ...癖を持っていると、オーバーフローの場合(明示的に開始するための変数をキャストしなかった場合)。いいえ、なぜ整数値にならないのかわかりません。double7.25741561530799E+306171![int][double][long]

明示的なキャストと操作を行うと(たとえば、[uint64]符号なし64ビット整数にを使用して)、それ以上の値を得ることができますが、条件付きで最大170の長さの範囲を設定してからリキャストする必要があるため、コードが大幅に膨張しますそこから先の各乗算。課題では上限を指定していないため、これが適切であると考えています。


2

Perl6

perl6 -e 'sub p ($a) { my $x = $a.join.comb.classify(+*).values.map(*.elems).classify(+*).values.flatmap(*.list).flatmap((2..+*).list); my $y = 2..$a[*-1]; [/] $x.list * [*] $y.list }; p([1..11]).say'

現時点では、どちらかといえば手に負えない-今眠る必要があります。


2

Groovy、156バイト

def f(n){def s=(0..n-1).join('')
0==n?1:g(s.size())/s.inject([:]){a,i->a[i]=a[i]?a[i]+1:1;a}*.value.inject(1){a,i->a*g(i)}}
BigInteger g(n){n<=1?1:n*g(n-1)}

謙虚な最初のCode Golfソリューション。 ここでテストできます。

そして、より読みやすいバージョンがあります:

def f(n) {
  def s = (0..n - 1).join('')                       // Store our concatented range, s
  0 == n ? 1 :                                      // Handle annoying case where n = 0
    fact(s.size()) / s.inject([:]) {                // Divide s.size()! by the product of the values we calculate by...
      a, i ->                                       // ...reducing into a map...
        a[i] = a[i] ? a[i] + 1 : 1                  // ...the frequency of each digit
        a                                           // Our Groovy return statement
    }*.value.inject(1) { a, i -> a * fact(i) }      // Finally, take the product of the factorial of each frequency value
}

BigInteger fact(n) { n <= 1 ? 1 : n * fact(n - 1) } // No built-in factorial function...

かなり簡単ですが、私にとっていくつかのハイライトがありました。

  • の配列からcharsへのインジェクト/リデュースの実行Map<Character, Integer>ます。マップ値のデフォルト値がないため、これはまだ少し複雑でした。これは疑わしいことですが、マップのデフォルト値がすべて0の場合、NPEを回避するために必要な3項を回避できます。

  • Groovyスプレッド演算子(例 }*.valueは常に使用するのが楽しい

しかし、迷惑な機能については、階乗関数を戻り値の型で宣言する必要がありましたBigInteger。私は、Groovyがすべての数値をBigIntegerまたはBigDecimalでラップしているという印象を受けていましたが、型を返すことになるとは限りません。もっと実験する必要があります。この戻り値の型が明示的に指定されていないと、誤った階乗値が非常に迅速に取得されます。


2

J、33バイト

(#(%*/)&:!&x:#/.~)@([:;<@":"0)@i.

範囲を数字列に変換し、各数字をカウントし、多項係数を適用して結果を計算します。

使用法

   f =: (#(%*/)&:!&x:#/.~)@([:;<@":"0)@i.
   (,.f"0) i. 16
 0              1
 1              1
 2              2
 3              6
 4             24
 5            120
 6            720
 7           5040
 8          40320
 9         362880
10        3628800
11      119750400
12     1816214400
13    43589145600
14  1111523212800
15 30169915776000

2

R、118バイト

パーティーに約8か月遅れましたが、面白い挑戦のように見えたので、試してみようと思いました。

function(n,x=as.numeric(el(strsplit(paste(1:n-1,collapse=""),""))),F=factorial)`if`(n,F(sum(1|x))/prod(F(table(x))),1)

Rフィドルで試してみてください

説明した

  1. ベクトルを生成 0 ... n-1をし、文字列に折りたたみます:paste(1:n-1,collapse="")
  2. 文字列を数字に分割し、数値に変換します x):x=as.numeric(el(strsplit(...,"")))
  3. 我々は単にやる分子計算するfactorial(sum(1|x))だけです#digits!
  4. 分母を計算するためにtable、周波数をリストする分割表を作成するために利用します。F(12)の場合、生成されるテーブルは次のとおりです。

    0 1 2 3 4 5 6 7 8 9 
    2 4 1 1 1 1 1 1 1 1 
    
  5. つまりfactorial()、カウントを使用して(これはベクトル化されます)、単純に製品を取得できます。prod(factorial(table(x)))

注:ステップ4と5は、n>0そうでない場合に戻る場合のみ実行され1ます。


1

Mathematica、65バイト

(Tr@IntegerLength[a=Range@#-1]+1)!/Times@@(Total[DigitCount@a]!)&

おそらくさらにゴルフをすることができます。




1

ゼリー、11バイト

Golfed Dennisの15バイトのゼリーの回答 ...

ḶDFµW;ĠẈ!:/

正の整数を生成する非負の整数を受け入れる単項リンク。

オンラインでお試しください!または、テストスイートを参照してください。

どうやって?

ḶDFµW;ĠẈ!:/ - Link: non-negative integer, N   e.g. 12
Ḷ           - lowered range            [0,1,2,3,4,5,6,7,8,9,10,11]
 D          - to decimal (vectorises)  [[0],[1],[2],[3],[4],[5],[6],[7],[8],[9],[1,0],[1,1]]
  F         - flatten                  [0,1,2,3,4,5,6,7,8,9,1,0,1,1]
   µ        - start a new monadic chain - i.e. f(that)
    W       - wrap in a list           [[0,1,2,3,4,5,6,7,8,9,1,0,1,1]]
      Ġ     - group indices by values  [[1,12],[2,11,13,14],3,4,5,6,7,8,9,10]
     ;      - concatenate              [[0,1,2,3,4,5,6,7,8,9,1,0,1,1],[1,12],[2,11,13,14],3,4,5,6,7,8,9,10]
       Ẉ    - length of each           [14,2,4,1,1,1,1,1,1,1,1]
        !   - factorial (vectorises)   [87178291200,2,24,1,1,1,1,1,1,1,1]
          / - reduce by:
         :  -   integer division       1816214400


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