Sekansı yeniden düzenleme


23

Giriş

Aşağıdaki sırayı izleyelim (negatif olmayan tamsayılar):

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

Örneğin, ilk üç sayıyı ele alalım . Bunlar 0, 1, 2. Bu sırada kullanılan numaralar altı farklı şekilde sipariş edilebilir :

012   120
021   201
102   210

Diyelim ki F (3) = 6 . Başka bir örnek F (12) . Bu sayıları içerir:

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

Veya birleştirilmiş sürüm:

01234567891011

Bunu yeniden düzenlemenin yollarını bulmak için, önce bu dizenin uzunluğuna bakmamız gerekir. Bu dizenin uzunluğu 14. 14 hesaplıyoruz ! . Ancak, örneğin son dizeyi bozmadan yer değiştirebilirler. 2 sıfır var, bu yüzden 2 var! sırayı bozmadan sıfırları değiştirmenin yolları . Ayrıca 4 tane var, bu yüzden 4 tane var! olanları değiştirmenin yolları. Toplamı şu iki sayıya böleriz:

Bu 14 tane var! / (4! × 2!) = 1816214400 dizeyi düzenlemenin yolları 01234567891011. Böylece F (12) = 1816214400 olduğu sonucuna varabiliriz .

Görev

N verildiğinde , çıkış F (N) . Girişe ihtiyaç duymayanlar için. F (N) 01234567891011değerini hesaplamak için , önce ilk N negatif olmayan tamsayıları birleştiririz (örneğin, N = 12 için, birleştirilmiş dize olur ) ve bu dizeyi düzenleme yollarının sayısını hesaplarız.

Test senaryoları

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

Not

Cevabı hesaplanması bir dahilinde hesaplanmalıdır 10 saniyelik süre , zorlaması olduğunu izin .

Bu , yani en az bayt ile gönderme kazanır!


Çıktı 10doğru mu? Tekrar eden rakamların başladığı yer 10'dan az olması gerektiği gibi geliyor.
Geobits

@Geobits İlk 10rakamlar 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. On farklı basamak, bu yüzden sonuç 10 !.
Adnan

Ah doğru. Sanırım 0dava sayımı attı (aptal boş teller).
Geobits

1
Artık bunun için endişelenmenize gerek yok. Yorum gönderdiğimde kaçamak teklifi +4 idi . Bu yer almaktadır +9 şimdi.
Dennis

1
İşte bu bulmaca hakkında ilginç bir matematik sorusu: F (N) 'nin N! N (F (N) / F (N-1) <N olan bir dizi N değeri vardır, ancak genellikle biraz daha büyüktür. Oldukça emin değilim F(N)değildir O(N!)ve bu log F(N)olduğunu O(log N!)ancak bu sadece ... eğilir vardır
Rici

Yanıtlar:


5

Jöle, 17 15 bayt

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

Çevrimiçi deneyin! veya tüm test senaryolarını bir kerede doğrulayın .

Nasıl çalışır

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.

Bu gerçekten Jelly mi? Birçok ASCII karakteri görüyorum :-P
Luis Mendo

3
Her zaman bir şekilde gizlice
Dennis

10

ES6, 118 81 78 bayt

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

Birisi bana sayıları birleştirmenin daha kısa bir yolu olduğunu söylemek zorunda n.

@ Edc65'in fikrini alarak ve steroidler üzerinde çalıştırarak serin bir 37 bayt kurtardı. (Bunun yerine '|' kullanarak fazladan bir bayt kaydedin &&ancak sonucu 31 bit ile sınırlandırın.)

Düzenleme: @ edc65 sayesinde 3 bayt daha kaydetti.


Basamak birleştirmeyi kısaltmanın bir yolunu bulamadık. Ama geri kalan her şey daha kısa olabilir
edc65

reducen=>[...[...Array(n).keys()].join``].reduce((r,c,i)=>r*++i/(o[c]=-~o[c]),1,o=[])
Şununla

1
Vaov! ama 78 daha iyi:n=>[...[...Array(n).keys()].join``].map(c=>r/=(o[c]=-~o[c])/i++,o=[],i=r=1)&&r
edc65

1
@ edc65 r/=(...)/i++daha doğru r*=i++/(...)mu? Bu şimdiye kadar gördüğüm en gülünç golf!
Neil

2
Bir an durmalıydım, çünkü orada bir regex olduğunu düşündüm.
Mama Fun Roll

7

APL (Genişletilmiş Dyalog) , 13 bayt

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

Çevrimiçi deneyin!

Tam bir program. Kullanır ⎕IO←0.

Nasıl çalışır

×/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

Çok terimli hesaplama aşağıdaki gerçeğe dayanır:

(bir1+bir2++birn)!bir1!bir2!birn!=(bir1+bir2)!bir1!bir2!x(bir1+bir2++birn)!(bir1+bir2)!bir3!birn!

=(bir1+bir2)!bir1!bir2!x(bir1+bir2+bir3)!(bir1+bir2)!bir3!x(bir1+bir2++birn)!(bir1+bir2+bir3)!birn!

==(bir1+bir2bir1)(bir1+bir2+bir3bir1+bir2)(bir1++birnbir1++birn-1)


1
İşte bu yüzden programcılar matematik öğrenmelidir.
İsimsiz

@Anonymous… ve matematiksel olarak eğimli bir programlama dili kullanın.
Adám

5

MATL , 21 bayt

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

Çevrimiçi deneyin!

açıklama

: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 Çözüldü. Ve daha az bayt ile :-)
Luis Mendo

Çok hoş görünüyor! :)
Adnan

@Adnan Teşekkürler! Bir açıklama ekledim
Luis Mendo

5

Python 2, 142 137 101 97 bayt

(Öneri için teşekkürler @adnan input)

( C versiyonundan artımlı hesaplama uygulandı )

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

Faktöriyel kullanarak orijinal sürüm

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

Gerçekten, yukarıdaki tek golf math.factorial Fbazı alanları çağırıyor ve bırakıyor, bu yüzden muhtemelen daha kısa bir python çözümü var.

Açıklama gerekiyorsa, vher bir basamağın sıklığını tutar; sayı, belirtilen aralıktaki her sayıdaki her basamak için güncellenir.

Orijinal versiyonda, standart formül (Σf i )! / Π (f i !) Kullanarak permütasyon sayısını hesaplıyoruz . Mevcut sürüm için, bu hesaplama basamakları gördüğümüzde çarpanları ve bölmeleri dağıtarak kademeli olarak yapılır. Tamsayı bölmesinin her zaman kesin olacağı açık olmayabilir, ancak her bölmenin ardışık tamsayıların katlarını ktakip etmesi gerektiği gözlemine dayanarak kanıtlanması kolaydır k, bu nedenle bu çarpılardan birinin bölünebilmesi gerekir k. (Bu bir sezgi, kanıt değil.)

Orijinal sürüm büyük argümanlar için daha hızlıdır, çünkü sadece 10 bignum ayrımı yapar. Bir bignumu küçük bir tamsayıya bölmek, bignumu bir bignum'a bölmekten daha hızlı olsa da, binlerce bignum bölünmesi olduğunda, biraz durgunlaşır.


f = f * toplam (v) / v [k] -> f * = toplam (v) / v [k] bir bayt kaydeder
Mikko Virkkilä

@superflux: ama aynı anlama gelmiyor.
rici

5

Python 2, 197 Bayt (değiştir: 4 bayt kaydedildi, teşekkürler 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

Ungolfed:

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
Programlama Bulmacaları ve Kod Golf hoş geldiniz! Bu cevap VLQ (çok düşük kalite) olarak işaretlendi, şüpheliyim çünkü burada norm olan herhangi bir açıklama veya ungolfed versiyonu içermiyor. Cevabınızın işe yaradığını ve bunu "yalnızca kod" olarak geliştirdiğinizi varsayarsak, oldukça iyi görünüyor!
kedi

range(0,10)olabilir range(10).
lirtosiast

4

CJam, 21 19 bayt

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

Burada test edin.

açıklama

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)

Ölçek

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>


İle k[c]=~-k[c]eşanlamlı değil --k[c]mi?
usandfriends

1
@usandfriends no, k [c] undefined olduğunda --k [c] NaN
edc65

Ooh, faktöriyel güzel dizi.
Neil

... ihtiyacın olmasa da. En son güncellememe bakın.
Neil

3

Pyth, 18 bayt

/F.!M+lJ.njRTQ/LJT

Çevrimiçi deneyin: Gösteri

/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 bayt

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

Kullanım örneği: h 12-> 1816214400.

Nasıl çalışır

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 bayt

Baytların büyük ölçüde azaltılması için rici'ye çok fazla kredi.

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);}

Ungolfed

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 */
}

Burada deneyin .


1
-Lm ile uğraşmadan 43 karakter kaydedebilirsiniz. Rakamları bulduğunuz gibi #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);}
saymanız yeterlidir

Onları d: hesapladığınız döngüde de sayabilirsiniz, for(;m<10;)s+=b[m],d*=f(b[m++])ancak bence bu birkaç bayt daha.
rici

Bu harika. Şu anki golf çabalarımla birleştirip düzenleyeceğim.
Cole Cameron

Güzel: Faktöriyel hesaplamanın orijinal döngüye nasıl entegre edileceğini görmek için bana bir göz atın, bu da keyfi hassas aritmetiğiniz yoksa biraz daha geniş bir aralıkta çalışma avantajına sahiptir. Sanırım bu tıraş için 20 bayt daha.
rici

3

Cı / BC, 233 121 112 bayt (3 bayt cezası varsayılarak |bc)

  1. Cole Cameron'dan esinlenerek, hacky karakter manipülasyonunu kaldırdı ve sadece argüman değeri üzerinde aritmetik yapın.

  2. Arg vektörü kullanılarak scanf olarak değiştirildi.

    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");}
    

İhtiyaçlar bcaslında keyfi hassas hesaplama yapmak.

Kurtulmamış ve ücretsiz uyarı:

#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 */
}

Resimli (güvendiğim algoritma gösterir):

$ 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

Ve bc aracılığıyla boru ile (ve F (1000) hesaplamasını ekleyerek:

$ 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

Bu, 10 saniyenin altında 18.592 haneli bir sayı olan F (5000) 'i hesapladı.

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

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

3

Perl 6, 117 bayt

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

ve daha okunabilir bir fasyonda

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 bayt

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

Beni 17 bayt kurtardığı için dev- null'a ve faktöriyel fikir için Japonlara çok teşekkürler .


3

05AB1E , 13 12 11 bayt

ÝD¨SāPr¢!P÷

Çevrimiçi deneyin!

Ý             # 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 bayt

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

Çevrimiçi deneyin!

  1. Dönüştür range tek dizeye giriş
  2. Dizede 0'dan 9'a kadar olan sayıların her birinin kaç kez göründüğünü kontrol edin ve her biri için faktöriyeli alın, sonra bunları çarpın
  3. Dizenin uzunluğunun faktöryelini 2. adımda hesaplanan sayıya bölün

2

PowerShell, 125 bayt

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

Girdi alır $args[0], çıkarır 1, 0..bu sayıdan bir dizi tamsayı oluşturur , -joins birlikte bir dizgiye kaydeder ve olarak kaydeder $b. Bu .Lengthdizgiyi alıyoruz, 1..bu uzunluktan başka bir aralık oluşturuyoruz , -joinbu tamsayılarla birlikte *, sonra Invoke-Expressionbuna (benzer eval) boru yapıyoruz . Başka bir deyişle, girdiye dayalı olarak sayı dizisinin uzunluğunun faktöriyelini oluşturduk. Bu bizim payımız.

Bunu bölüyoruz /...

Bir aralık alarak 0..9ve bir for-loop yoluyla göndererek inşa edilen paydamız |%{...}. Her bir yinelemede, öznitelikle birleştirilmiş .NET çağrısı sayesinde $cgeçerli rakamın kaç kez $_göründüğüne eşit bir yardımcı değişken ayarladık . Daha sonra sıfır olmadığı sürece bu değere kadar yeni bir aralık oluştururuz. Evet, birçok durumda, bu sadece değerlendirilen bir aralık ile sonuçlanacaktır . Tüm bunları ve bunları birlikte alıyoruz , sonra tekrar boruya geçiriyoruz. Diğer bir deyişle, her bir basamağın gerçekleşme sayısının faktöriyelerinin ürününü oluşturduk.$b[regex]::matches.count1..1..11-join*Invoke-Expression


NB

Girişi 90sorunsuz bir şekilde ve bir saniyeden daha kısa sürede işler.

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

... bunun ötesinde Infinityçıktı olarak sonuçlanır , çünkü izin verilen dizginin uzunluğu veri tipine ( ) 170!sığar , fakat girmez. PowerShell olan bir ... cilvesi ... bu otomatik yukarı atmalarını için taşma durumunda (açıkça başlamak değişkeni döküm vermedi şartıyla). Hayır, neden gitmediğini bilmiyorumdouble7.25741561530799E+306171![int][double][long] tamsayı değerlere .

Bazı açık döküm ve manipülasyonlar yapsaydık (örneğin, [uint64]imzasız 64 bit tamsayılar için), bunu daha yükseğe çıkarabilirdik, ancak koşullara göre 170 uzunluğa kadar aralamaya ve yeniden biçimlendirmeye ihtiyaç duyacağımız için kodu önemli ölçüde şişirirdik. oradan her çarpma. Zorluk bir üst menzil belirtmediğinden, bunun yeterli olduğunu düşünüyorum.


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'

Şu anda ungolfed - şimdi uykuya ihtiyacım var.


2

Groovy, 156 bayt

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)}

Benim mütevazı ilk Code Golf çözümü. Burada test edebilirsiniz.

Ve burada daha okunabilir bir sürüm:

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...

Oldukça açık, ama benim için birkaç önemli nokta vardı:

  • Bir diziden charsa enjekte etme / azaltma gerçekleştirme Map<Character, Integer>. Bu, harita değerleri için varsayılan bir değer bulunmaması nedeniyle biraz karmaşıktı. Bu şüphe bu mümkün, ancak harita varsayılan olarak tüm değerleri 0 olarak ayarladıysa, bir NPE'den kaçınmak için gerekli olan üçlüden kaçınabilirim.

  • Groovy forma operatörünün (örn. }*.value) Kullanımı her zaman eğlencelidir

Bununla birlikte, can sıkıcı bir özellikte, faktöriyel fonksiyonu dönüş tipiyle bildirme zorunluluğu vardı BigInteger. Groovy'nin tüm sayısalları BigIntegerveya içine sardığı izlenimindeydim BigDecimal, ancak dönüş türleri söz konusu olduğunda durum böyle olmayabilir. Daha fazla deneme yapmak zorunda kalacağım. Bu dönüş türü açıkça belirtilmedikçe, çok faktörlü değerleri çok hızlı bir şekilde alırız.


2

J, 33 bayt

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

Aralığı bir basamak dizisine dönüştürür, her basamağı sayar ve sonucu hesaplamak için çok terimli katsayıyı uygular.

kullanım

   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 bayt

Partiye yaklaşık 8 ay geç kaldım ama ilginç bir meydan okumaya benzediğinden bir şans vereceğimi düşündüm.

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-fiddle'da deneyin

Açıklaması

  1. Vektör oluştur 0 ... n-1 ve dizeye daraltma:paste(1:n-1,collapse="")
  2. Dizeyi rakamlarına bölün ve sayıya dönüştürün ( x ):x=as.numeric(el(strsplit(...,"")))
  3. Payı hesaplamak için factorial(sum(1|x))sadece#digits!
  4. Paydayı hesaplamak tableiçin frekansları listeleyen bir olasılık tablosu oluşturmak için kullanırız . F (12) durumunda, oluşturulan tablo:

    0 1 2 3 4 5 6 7 8 9 
    2 4 1 1 1 1 1 1 1 1 
    
  5. Bu, kullanımı factorial()(bu arada vektörize edilir) sayıya göre alabilir ve ürünü alabiliriz:prod(factorial(table(x)))

Not: Adım 4 ve 5 sadece n>0aksi takdirde geri dönerse gerçekleştirilir 1.


1

Mathematica, 65 bayt

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

Muhtemelen daha fazla golf olabilir.




1

Jöle , 11 bayt

Golf Dennis '15 bayt Jelly cevap ...

ḶDFµW;ĠẈ!:/

Pozitif bir tamsayı veren negatif olmayan bir tamsayıyı kabul eden monadik bir Bağlantı.

Çevrimiçi deneyin! Veya test takımına bakın .

Nasıl?

Ḷ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 , 190 bayt

from collections import*
g,n=range,int(input())
p=lambda r:reduce(lambda x,y:x*y,r,1)
f=lambda n:p(g(1,n+1))
s=''.join(str(i)for i in g(n))
c=Counter(s)
print(f(len(s))/p(f(c[i])for i in c))

Çevrimiçi deneyin!


0

Python 2 , 134 bayt

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

Çevrimiçi deneyin!

Alternatif bir yaklaşım ...

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.