重新排列顺序


23

介绍

让我们观察以下序列(非负整数):

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

例如,让我们采用前三个数字。这些是0, 1, 2。此序列中使用的数字可以以六种不同的方式排序:

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个!切换方式。我们将总数除以这两个数字:

这个有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 '16

@Geobits的10前两位数字是0, 1, 2, 3, 4, 5, 6, 7, 8, 9。十个不同的数字,因此结果是10!。
阿德南

嗯对 我认为0此案使我的计票失败(愚蠢的空字符串)。
Geobits '16

1
无需再担心了。当我发表评论时,漏洞建议为+4。现在是+9
丹尼斯

1
这是关于这个难题的一个有趣的数学问题:F(N)相对于N!的值是多少?有许多N值,其中F(N)/ F(N-1)<N,但通常略大一些。我敢肯定,F(N)是不是O(N!)log F(N)O(log N!),但这些都只是预感......
罗杰斯国际商品指数

Answers:


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字符:-P
Luis Mendo

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 '16

使用以下方法保存2个字节reducen=>[...[...Array(n).keys()].join``].reduce((r,c,i)=>r*++i/(o[c]=-~o[c]),1,o=[])
user81655 '02

1
哇!但是78更好:n=>[...[...Array(n).keys()].join``].map(c=>r/=(o[c]=-~o[c])/i++,o=[],i=r=1)&&r
edc65 '16

1
@ edc65 r/=(...)/i++r*=i++/(...)?那是我见过的最荒唐的高尔夫!
尼尔

2
我不得不停了一会儿,因为我以为你那里有一个正则表达式。
Mama Fun Roll

7

APL(Dyalog扩展),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

多项式计算来自以下事实:

一种1个+一种2++一种ñ一种1个一种2一种ñ=一种1个+一种2一种1个一种2×一种1个+一种2++一种ñ一种1个+一种2一种3一种ñ

=一种1个+一种2一种1个一种2×一种1个+一种2+一种3一种1个+一种2一种3×一种1个+一种2++一种ñ一种1个+一种2+一种3一种ñ

==一种1个+一种2一种1个一种1个+一种2+一种3一种1个+一种2一种1个++一种ñ一种1个++一种ñ-1个


1
这就是为什么程序员应该学习数学的原因。
匿名

@Anonymous…,并使用数学上倾向于编程的语言。
2:43

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解决了。且字节数少:-)
Luis Mendo

看起来很不错!:)
Adnan

@Adnan谢谢!我添加了一个解释
Luis Mendo

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数)!/π(F !)。对于当前版本,此计算是通过分布乘法和除法来逐步完成的,就像我们看到的数字一样。整数除法将始终是精确的可能并不明显,但是基于以下观察很容易证明:除法k必须遵循k连续整数的倍数,因此这些乘法之一必须可以被整除k。(这是一种直觉,而不是证明。)

对于大参数,原始版本速度更快,因为它只进行10个bignum除法。尽管将bignum除以小整数要比将bignum除以bignum快,但是当您有成千上万的bignum除法时,它会变慢。


f = f * sum(v)/ v [k]-> f * = sum(v)/ v [k]保存一个字节
MikkoVirkkilä16年

@superflux:但是含义不一样。
rici

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
欢迎来到编程难题和Code Golf!我怀疑这个答案被标记为VLQ(质量很低),因为它不包含任何解释或非高尔夫版本,这是这里的规范。假设您的答案有效,并且您将其从“仅代码化”的角度加以改善,那么看起来还不错!

range(0,10)可以range(10)
lirtosiast'2

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's

1
@usandfriends否,当未定义k [c]时--k [c]为NaN
edc65 '16

哦,很好的析因数组。
尼尔

...尽管您不需要它。查看我的最新更新。
尼尔

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++])但是我认为这要多几个字节。
rici

那太好了。我将结合我目前的高尔夫运动并进行编辑。
科尔·卡梅隆

不错:看看我的方法,看看如何将阶乘计算集成到原始循环中,如果没有任意精度算术,这样做的好处是可以在更大的范围内工作。我认为还需要刮掉20个字节。
rici

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

这将在10秒内计算出F(5000)-一个18,592位数字。

$ 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],减去1,然后从0..该数字中构建一个整数范围,将-joins组合成一个字符串,然后将其另存为$b。我们采用该.Length字符串的,从1..该长度构建另一个范围,-join这些整数与一起*,然后将其通过管道传递给Invoke-Expression(类似于eval)。换句话说,我们已经根据输入构造了数字序列长度的阶乘。那就是我们的分子。

我们将其分开 /除以...

我们的分母是通过获取范围0..9并将其通过for循环发送而构造的|%{...}。每次迭代,我们都将一个辅助变量设置为$c等于当前数字$_出现的次数,$b这要归功于.NET [regex]::matches调用与该.count属性。然后1..,只要不为零,就可以构造一个新的范围,直到该值为止。是的,在很多情况下,这将导致一个范围1..1,其值等于1。我们将所有这些以及-join它们与一起使用*,然后Invoke-Expression再次将其传送到。换句话说,我们已经构造了每个数字出现次数的阶乘乘积。


NB

最多可90在不到一秒钟的时间内处理输入,而不会出现问题。

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!适合double数据类型(7.25741561530799E+306),但171!不适合。PowerShell有一个... ...怪癖自动从向上类型转换[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。

  • Groovy点差运算符(例如 }*.value)总是很有趣

然而,令人讨厌的功能是必须使用return type声明阶乘函数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)))

注意:仅在n>0返回否则执行步骤4和5 1


1

Mathematica,65个字节

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

可能会打得更远。




1

果冻,11 字节

打高尔夫球的丹尼斯(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


0

Python 2,134字节

s="".join(map(str,range(input())))
n=d=1
for i in range(1,len(s)+1):n*=i;d*=i**len([c for c in range(10)if s.count(`c`)>=i])
print n/d

在线尝试!

另一种方法...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.