Перестановка послідовності


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 Перші 10цифри є 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. Десять різних цифр, тому результат 10 !.
Аднан

Ага, правильно. Я думаю, що 0справа кинула мій рахунок (дурні порожні рядки).
Геобіт

1
Про це більше не потрібно хвилюватися. Пропозиція щодо лазівки становила +4, коли я опублікував коментар. Зараз це +9 .
Денніс

1
Ось цікаве математичне запитання щодо цієї головоломки: Яке значення F (N) щодо N !? Існує ряд значень N, для яких F (N) / F (N-1) <N, але зазвичай це трохи більше. Я майже впевнений, що F(N)це не так O(N!), але log F(N)це, O(log N!)але це просто
вигони

Відповіді:


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
Луїс Мендо

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.

Зберегли круті 37 байт, взявши ідею @ edc65 і запустивши її на стероїди. (Збережіть додатковий байт, використовуючи "|" замість, &&але це обмежує результат на 31 біт.)

Редагувати: Збережено ще 3 байти знову завдяки @ edc65.


Не знайшли способу скоротити конкатенацію цифр. Але все інше може бути коротшим
edc65

Збережіть 2 байти за допомогою reduce:n=>[...[...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++/(...)? Це найсмішніший гольф, який я коли-небудь бачив!
Ніл

2
Мені довелося зупинитися на мить, тому що я думав, що у вас тут є виразка.
Mama Fun Roll

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

Багаточленний розрахунок випливає з наступного факту:

(а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… і використовувати математичну мову програмування.
Adám

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

Пітон 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та залишення місця, тому, мабуть, існує коротше рішення пітона.

Якщо потрібне пояснення, vпідтримує підрахунок частоти кожної цифри; кількість оновлюється для кожної цифри кожного номера у вказаному діапазоні.

У початковій версії ми обчислюємо кількість перестановок, використовуючи стандартну формулу (Σf i )! / Π (f i !). Для поточної версії це обчислення проводиться поступово, розподіляючи множення та ділення, як ми бачимо цифри. Можливо, не очевидно, що ціле ділення завжди буде точним, але легко довести на основі спостереження, що кожне ділення на kповинне слідувати kмноженням послідовних цілих чисел, тому одне з цих множень повинно бути діленим на k. (Це інтуїція, а не доказ.)

Оригінальна версія швидша для великих аргументів, оскільки вона робить лише 10 діючих бігумів. Хоча ділення бігуму на мале ціле число швидше, ніж ділення бігуму на бінгум, коли у вас є тисячі ділення бінтуму, воно стає дещо млявим.


f = f * sum (v) / v [k] -> f * = sum (v) / v [k] зберігає байт
Mikko Virkkilä

@superflux: але це не те саме значення.
rici

5

Python 2, 197 байт (редагувати: збережено 4 байти, дякую Томасу Ква!)

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

Піт, 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

Хаскелл, 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
Ви можете зберегти 43 символи, не спілкуючись з -lm. Просто порахуйте цифри, як їх знайдете:#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. Натхненний Коулом Кемероном, видалив маніпуляцію з хитким персонажем і просто зробив арифметику за значенням аргументу.

  2. Змінено на scanf з використанням arg вектор.

    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

05AB1E , 13 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. Ви можете протестувати його тут.

І ось більш читана версія:

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) завжди цікавий у використанні

Однак прикрою особливістю була необхідність оголосити факторіальну функцію з типом повернення 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

Математика, 65 байт

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

Можливо, можна було б пограти в гольф далі.




1

Желе , 11 байт

Відповідь 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


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.