Rearranging the sequence

23

Introduction

Let's observe the following sequence (non-negative integers):

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

For example, let's take the first three numbers. These are 0, 1, 2. The numbers used in this sequence can be ordered in six different ways:

012   120
021   201
102   210

So, let's say that F(3) = 6. Another example is F(12). This contains the numbers:

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

Or the concatenated version:

01234567891011

To find the number of ways to rearrange this, we first need to look at the length of this string. The length of this string is 14. So we compute 14!. However, for example the ones can exchange places without disrupting the final string. There are 2 zeroes, so there are 2! ways to exhange the zeroes without disrupting the order. There are also 4 ones, so there are 4! ways to switch the ones. We divide the total by these two numbers:

This has 14! / (4! × 2!) = 1816214400 ways to arrange the string 01234567891011. So we can conclude that F(12) = 1816214400.

The task

Given N, output F(N). For the ones who don't need the introduction. To compute F(N), we first concatenate the first N non-negative integers (e.g. for N = 12, the concatenated string would be 01234567891011) and calculate the number of ways to arrange this string.

Test cases

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

Note

Computing the answer must be computed within a time limit of 10 seconds, brute-forcing is disallowed.

This is , so the submission with the least amount of bytes wins!

Adnan

Posted 2016-02-03T21:49:26.677

Reputation: 41 965

Is the output for 10 correct? It feels like it should be less than 10!, since that's where the repeating digits start. – Geobits – 2016-02-03T22:02:05.707

@Geobits The first 10 digits are 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. Ten different digits, so the result is 10!. – Adnan – 2016-02-03T22:03:41.323

Ah, right. I think the 0 case was throwing my count off (stupid empty strings). – Geobits – 2016-02-03T22:05:20.987

You only need to support the test cases that your language can handle. Natively? This needs one more upvote to count as standard loophole... – Dennis – 2016-02-04T00:37:53.437

@Dennis Hmmm, good point. I have deleted the rule in the post. – Adnan – 2016-02-04T08:05:31.953

1No need to worry about that anymore. The loophole proposal was at +4 when I posted the comment. It is at +9 now. – Dennis – 2016-02-04T16:09:06.470

1Here's an interesting math question about this puzzle: What is the value of F(N) relative to N!? There are a number of values of N for which F(N)/F(N-1) < N, but it is usually slightly greater. I'm pretty sure that F(N) is not O(N!) and that log F(N) is O(log N!) but those are just hunches... – rici – 2016-02-05T03:10:48.543

Answers

5

Jelly, 17 15 bytes

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

Try it online! or verify all test cases at once.

How it works

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.

Dennis

Posted 2016-02-03T21:49:26.677

Reputation: 196 637

Is this really Jelly? I see to many ASCII characters :-P – Luis Mendo – 2016-02-03T22:36:56.797

3They always manage to sneak in somehow... – Dennis – 2016-02-04T00:03:59.430

10

ES6, 118 81 78 bytes

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

Someone's bound to tell me there's a shorter way of concatenating the numbers up to n.

Saved a cool 37 bytes by taking @edc65's idea and running it on steroids. (Save an extra byte by using '|' instead of && but that limits the result to 31 bits.)

Edit: Saved 3 further bytes again thanks to @edc65.

Neil

Posted 2016-02-03T21:49:26.677

Reputation: 95 035

Did not find a way to shorten the digits concatenation. But all the rest can be shorter – edc65 – 2016-02-03T23:54:56.787

Save 2 bytes with reduce: n=>[...[...Array(n).keys()].join\`].reduce((r,c,i)=>r*++i/(o[c]=-~o[c]),1,o=[])` – user81655 – 2016-02-04T11:43:59.687

1Wow! but 78 is better: n=>[...[...Array(n).keys()].join``].map(c=>r/=(o[c]=-~o[c])/i++,o=[],i=r=1)&&r – edc65 – 2016-02-04T11:52:13.620

@user81655 Huh, I was sure someone told me that map would always work out cheaper. – Neil – 2016-02-04T13:30:04.070

1@edc65 r/=(...)/i++ is more accurate than r*=i++/(...)? That's the most ludicrous golf I've ever seen! – Neil – 2016-02-04T13:31:28.417

2I had to stop for a moment, because I thought you had a regex in there. – Mama Fun Roll – 2016-02-06T05:10:55.863

7

APL (Dyalog Extended), 13 bytes

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

Try it online!

A full program. Uses ⎕IO←0.

How it works

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

The multinomial calculation comes from the following fact:

$$ \frac{(a_1 + a_2 + \cdots + a_n)!}{a_1! a_2! \cdots a_n!} = \frac{(a_1 + a_2)!}{a_1! a_2!} \times \frac{(a_1 + a_2 + \cdots + a_n)!}{(a_1 + a_2)! a_3! \cdots a_n!} $$

$$ = \frac{(a_1 + a_2)!}{a_1! a_2!} \times \frac{(a_1 + a_2 + a_3)!}{(a_1 + a_2)! a_3!} \times \frac{(a_1 + a_2 + \cdots + a_n)!}{(a_1 + a_2 + a_3)! \cdots a_n!} $$

$$ = \cdots = \binom{a_1 + a_2}{a_1} \binom{a_1 + a_2 + a_3}{a_1 + a_2} \cdots \binom{a_1 + \cdots + a_n}{a_1 + \cdots + a_{n-1}} $$

Bubbler

Posted 2016-02-03T21:49:26.677

Reputation: 16 616

1And this is why programmers should learn mathematics. – Anonymous – 2019-11-28T17:16:32.400

@Anonymous … and use a mathematically inclined programming language. – Adám – 2019-12-01T23:04:39.187

5

MATL, 21 bytes

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

Try it online!

Explanation

: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

Luis Mendo

Posted 2016-02-03T21:49:26.677

Reputation: 87 464

@Adnan Solved. And with fewer bytes :-) – Luis Mendo – 2016-02-03T22:19:31.267

Looks very nice! :) – Adnan – 2016-02-03T22:20:41.427

@Adnan Thanks! I've added an explanation – Luis Mendo – 2016-02-03T22:27:40.493

5

Python 2, 197 Bytes (edit: saved 4 bytes, thanks 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

Dave Lin

Posted 2016-02-03T21:49:26.677

Reputation: 71

1Welcome to Programming Puzzles and Code Golf! This answer was flagged as VLQ (very low quality), I suspect because it does not contain any explanation or ungolfed version, which are the norm here. Assuming your answer works, and you improve it from being "code only", it seems quite good! – cat – 2016-02-04T02:53:52.950

range(0,10) can be range(10). – lirtosiast – 2016-02-04T03:09:57.600

5

Python 2, 142 137 101 97 bytes

(Thanks @adnan for the suggestion about input)

(Applied the incremental calculation from the C version)

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

Original version using factorial

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

Really, the only golfing in the above is calling math.factorial F and leaving out some spaces, so there is probably a shorter python solution.

If explanation is needed, v maintains a count of the frequency of each digit; the count is updated for each digit in each number in the indicated range.

In the original version, we compute the number of permutations using the standard formula (Σfi)!/π(fi!). For the current version, this computation is done incrementally by distributing the multiplies and divides as we see the digits. It might not be obvious that the integer divide will always be exact, but it is easy to prove based on the observation that each division by k must follow k multiplies of consecutive integers, so one of those multiplies must be divisible by k. (That's an intuition, not a proof.)

The original version is faster for large arguments because it does only 10 bignum divides. Although dividing a bignum by a small integer is faster than dividing a bignum by a bignum, when you have thousands of bignum divides, it gets a bit sluggish.

rici

Posted 2016-02-03T21:49:26.677

Reputation: 601

f=fsum(v)/v[k] --> f=sum(v)/v[k] saves a byte – Mikko Virkkilä – 2016-02-06T08:30:47.930

@superflux: but it is not the same meaning. – rici – 2016-02-06T11:15:32.483

4

CJam, 21 19 bytes

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

Test it here.

Explanation

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.

Martin Ender

Posted 2016-02-03T21:49:26.677

Reputation: 184 808

3

05AB1E, 13 12 11 bytes

ÝD¨SāPr¢!P÷

Try it online!

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

Grimmy

Posted 2016-02-03T21:49:26.677

Reputation: 12 521

3

Python 2, 123 bytes

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

Try it online!

  1. Convert the range of the input to a single string
  2. Check how many times each of the numbers from 0 to 9 appears in the string and get the factorial for each then multiply them together
  3. Divide the factorial of the length of the string by the number calculated in step 2

ElPedro

Posted 2016-02-03T21:49:26.677

Reputation: 5 301

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)

Test

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>

edc65

Posted 2016-02-03T21:49:26.677

Reputation: 31 086

Isn't k[c]=~-k[c] synonymous with --k[c]? – usandfriends – 2016-02-04T00:09:42.003

1@usandfriends no, when k[c] is undefined --k[c] is NaN – edc65 – 2016-02-04T00:16:44.343

Ooh, nice array of factorials. – Neil – 2016-02-04T00:23:39.630

... although you don't need it. See my latest update. – Neil – 2016-02-04T08:52:20.427

3

Pyth, 18 bytes

/F.!M+lJ.njRTQ/LJT

Try it online: Demonstration

/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

Jakube

Posted 2016-02-03T21:49:26.677

Reputation: 21 462

3

Haskell, 92 bytes

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

Usage example: h 12 -> 1816214400.

How it works

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

nimi

Posted 2016-02-03T21:49:26.677

Reputation: 34 639

3

Perl 6, 117 bytes

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

and in a more readable fasion

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

Joshua

Posted 2016-02-03T21:49:26.677

Reputation: 261

3

C, 236 174 138 121 bytes

Much credit to rici, for massive reduction of bytes.

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

Try it here.

Cole Cameron

Posted 2016-02-03T21:49:26.677

Reputation: 1 013

1You could save 43 characters by not mucking around with -lm. Just count the digits as you find them: #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 – 2016-02-05T15:33:19.347

You could also count them in the loop where you compute d: for(;m<10;)s+=b[m],d*=f(b[m++]) but I think that's a couple more bytes. – rici – 2016-02-05T15:38:00.967

That's brilliant. I'll combine with my current golfing efforts and edit. – Cole Cameron – 2016-02-05T15:38:47.760

Nice: take a look at mine to see how to integrate the factorial computation into the original loop, which has the advantage of working on a slightly larger range if you don't have arbitrary-precision arithmetic. I think that's another 20 bytes to shave. – rici – 2016-02-05T16:11:43.107

3

C/bc, 233 121 112 bytes (assuming 3 byte penalty for |bc)

  1. Inspired by Cole Cameron, removed the hacky character manipulation and just do arithmetic on the argument value.

  2. Changed to scanf from using arg vector.

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

Needs bc to actually do the arbitrary precision computation.

Ungolfed and warning free:

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

Illustrated (which I trust shows the algorithm):

$ 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

And, with the pipe through bc (and adding the computation of 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

This computed F(5000) -- an 18,592-digit number -- in under 10 seconds.

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

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

rici

Posted 2016-02-03T21:49:26.677

Reputation: 601

3

Perl 5, 108 bytes

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

Many thanks to dev-null for saving me 17 bytes, and to japhy for the factorial idea.

msh210

Posted 2016-02-03T21:49:26.677

Reputation: 3 094

2

PowerShell, 125 bytes

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

Takes input $args[0], subtracts 1, builds a range of integers from 0.. that number, -joins that together into a string, and saves it as $b. We take the .Length of that string, build another range from 1.. that length, -join those integers together with *, then pipe that to Invoke-Expression (similar to eval). In other words, we've constructed the factorial of the length of the number sequence based on the input. That's our numerator.

We divide that / by ...

Our denominator, which is constructed by taking a range 0..9 and sending it through a for-loop |%{...}. Each iteration, we set a helper variable $c equal to the number of times the current digit $_ appears within $b thanks to the .NET [regex]::matches call coupled with the .count attribute. We then construct a new range from 1.. up to that value, so long as it's non-zero. Yes, in many instances, this will result in a range 1..1, which evaluates to just 1. We take all of those and -join them together with *, then pipe that to Invoke-Expression again. In other words, we've constructed the product of the factorials of the number of occurrences of each digit.


NB

Handles input up to 90 without issue and in significantly less than a second.

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

... beyond that results in Infinity as output, since the length of the permutable string results in 170! which fits in the double datatype (7.25741561530799E+306), but 171! doesn't. PowerShell has a ... quirk ... that automatically up-casts from [int] to [double] in the case of overflow (provided you didn't explicitly cast the variable to start with). No, I don't know why it doesn't go to [long] for integer values.

If we did some explicit casting and manipulation (e.g., using [uint64], for unsigned 64-bit integers), we could get that higher, but it would significantly bloat the code as we would need to range up to 170-length with conditionals and then recast each multiplication from there onward. As the challenge doesn't specify an upper range, I'm presuming this to be adequate.

AdmBorkBork

Posted 2016-02-03T21:49:26.677

Reputation: 41 581

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'

Rather ungolfed at the moment - need sleep now.

user52889

Posted 2016-02-03T21:49:26.677

Reputation: 211

2

Groovy, 156 bytes

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

My humble first Code Golf solution. You can test it here.

And here's a more readable version:

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

Quite straightforward, but there were a couple highlights for me:

  • Performing an inject/reduce from an array of chars to a Map<Character, Integer>. This was still a little complicated by the lack of a default value for the map values. This doubt this is possible, but if the map defaulted all values to 0, I could avoid the ternary which is necessary to avoid an NPE.

  • The Groovy spread operator (e.g. }*.value) is always fun to use

On annoying feature, however, was the necessity to declare the factorial function with the return type BigInteger. I was under the impression that Groovy wrapped all numerics in BigInteger or BigDecimal, but this might not be the case when it comes to return types. I'll have to experiment more. Without this return type explicitly stated, we get incorrect factorial values very quickly.

lealand

Posted 2016-02-03T21:49:26.677

Reputation: 131

2

J, 33 bytes

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

Converts the range into a string of digits, counts each digits, and applies the multinomial coefficient to compute the result.

Usage

   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

miles

Posted 2016-02-03T21:49:26.677

Reputation: 15 654

2

R, 118 bytes

About 8 months late to the party but thought I'd give it a go because it looked like an interesting challenge.

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)

Try it on R-fiddle

Explained

  1. Generate vector 0 ... n-1 and collapse it to a string: paste(1:n-1,collapse="")
  2. Split string into its digits and convert to numeric(store as x): x=as.numeric(el(strsplit(...,"")))
  3. To calculate the numerator we simply do factorial(sum(1|x)) which is just #digits!
  4. To calculate the denominator we make use of table to construct a contingency table that list the frequencies. In the case of F(12) the table generated is:

    0 1 2 3 4 5 6 7 8 9 
    2 4 1 1 1 1 1 1 1 1 
    
  5. Which means we can take the use factorial() (which by the way is vectorized) on the count and simply take the product: prod(factorial(table(x)))

Note: step 4 and 5 are only carried through if n>0 otherwise return 1.

Billywob

Posted 2016-02-03T21:49:26.677

Reputation: 3 363

1

Ruby, 64 bytes

->n,*w{a=1;[*0...n].join.chars{|d|a=a*(w<<d).size/w.count(d)};a}

Try it online!

G B

Posted 2016-02-03T21:49:26.677

Reputation: 11 099

1

Stax, 12 bytes

éÄ\↑≈g→FP○░→

Run and debug it at staxlang.xyz!

Unpacked (14 bytes) and explanation:

r$c%|Fso:GF|F/
r                 Range [0..input)
 $                Stringify each and concat
  c               Copy atop the stack
   %|F            Factorial of length
      s           Swap original back to top
       o          Sort
        :G        Run lengths
          F       For each:
           |F       Factorial
             /      Divide running quotient by this factorial
                  Implicit print

Khuldraeseth na'Barya

Posted 2016-02-03T21:49:26.677

Reputation: 2 608

1

Jelly, 11 bytes

Golfed Dennis' 15 byte Jelly answer...

ḶDFµW;ĠẈ!:/

A monadic Link accepting a non-negative integer which yields a positive integer.

Try it online! Or see the test suite.

How?

Ḷ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

Jonathan Allan

Posted 2016-02-03T21:49:26.677

Reputation: 67 804

1

Mathematica, 65 bytes

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

Could probably be golfed further.

LegionMammal978

Posted 2016-02-03T21:49:26.677

Reputation: 15 731

0

Python 2, 190 bytes

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

Try it online!

Alexey Burdin

Posted 2016-02-03T21:49:26.677

Reputation: 844

0

Python 2, 134 bytes

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

Try it online!

An alternate approach...

Chas Brown

Posted 2016-02-03T21:49:26.677

Reputation: 8 959