Reorganizando la secuencia

23

Introducción

Observemos la siguiente secuencia (enteros no negativos):

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

Por ejemplo, tomemos los primeros tres números. Estos son 0, 1, 2. Los números utilizados en esta secuencia se pueden ordenar de seis maneras diferentes:

012   120
021   201
102   210

Entonces, digamos que F (3) = 6 . Otro ejemplo es F (12) . Este contiene los números:

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

O la versión concatenada:

01234567891011

Para encontrar la cantidad de formas de reorganizar esto, primero tenemos que mirar la longitud de esta cadena. La longitud de esta cadena es 14. ¡Entonces calculamos 14! . Sin embargo, por ejemplo, los que pueden intercambiar lugares sin interrumpir la cadena final. ¡Hay 2 ceros, entonces hay 2! maneras de exhalar los ceros sin interrumpir el orden. También hay 4 unos, ¡así que hay 4! maneras de cambiar las Dividimos el total por estos dos números:

Esto tiene 14! / (4! × 2!) = 1816214400 formas de organizar la cadena 01234567891011. Entonces podemos concluir que F (12) = 1816214400 .

La tarea

Dado N , salida F (N) . Para los que no necesitan la presentación. Para calcular F (N), primero concatenamos los primeros N enteros no negativos (por ejemplo, para N = 12, la cadena concatenada sería 01234567891011) y calculamos el número de formas de organizar esta cadena.

Casos de prueba

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

Nota

Calcular la respuesta debe calcularse dentro de un límite de tiempo de 10 segundos , no se permite la fuerza bruta .

Este es el , por lo que gana el envío con la menor cantidad de bytes.

Adnan
fuente
¿La salida es 10correcta? Parece que debería ser menos de 10 !, ya que ahí es donde comienzan los dígitos repetidos.
Geobits
@Geobits Los primeros 10dígitos son 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. Diez dígitos diferentes, por lo que el resultado es 10 !.
Adnan
Ah bien. Creo que el 0caso estaba descartando mi cuenta (estúpidas cadenas vacías).
Geobits
1
Ya no tienes que preocuparte por eso. La propuesta de escapatoria estaba en +4 cuando publiqué el comentario. Está en +9 ahora.
Dennis
1
Aquí hay una pregunta matemática interesante sobre este rompecabezas: ¿Cuál es el valor de F (N) en relación con N? Hay una serie de valores de N para los cuales F (N) / F (N-1) <N, pero generalmente es ligeramente mayor. Estoy bastante seguro de que F(N)no es O(N!)y que log F(N)es O(log N!), pero esos son sólo corazonadas ...
RICI

Respuestas:

5

Jalea, 17 15 bytes

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

Pruébalo en línea! o verificar todos los casos de prueba a la vez .

Cómo funciona

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
fuente
¿Es esto realmente Jelly? Veo muchos caracteres ASCII :-P
Luis Mendo
3
Siempre se las arreglan para colarse de alguna manera ...
Dennis
10

ES6, 118 81 78 bytes

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

Alguien tiene que decirme que hay una forma más corta de concatenar los números hasta n.

Ahorré 37 bytes geniales tomando la idea de @ edc65 y ejecutándola con esteroides. (Guarde un byte adicional usando '|' en lugar de &&pero eso limita el resultado a 31 bits).

Editar: Guardado 3 bytes más nuevamente gracias a @ edc65.

Neil
fuente
No encontré una manera de acortar la concatenación de dígitos. Pero todo lo demás puede ser más corto
edc65
Ahorre 2 bytes con reduce:n=>[...[...Array(n).keys()].join``].reduce((r,c,i)=>r*++i/(o[c]=-~o[c]),1,o=[])
user81655
1
¡Guauu! pero 78 es mejor:n=>[...[...Array(n).keys()].join``].map(c=>r/=(o[c]=-~o[c])/i++,o=[],i=r=1)&&r
edc65
1
@ edc65 r/=(...)/i++es más preciso que r*=i++/(...)? ¡Ese es el golf más ridículo que he visto!
Neil
2
Tuve que parar por un momento, porque pensé que tenías una expresión regular allí.
Mama Fun Roll
7

APL (Dyalog Extended) , 13 bytes

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

Pruébalo en línea!

Un programa completo Usos ⎕IO←0.

Cómo funciona

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

El cálculo multinomial proviene del siguiente hecho:

(un1+un2++unnorte)!un1!un2!unnorte!=(un1+un2)!un1!un2!×(un1+un2++unnorte)!(un1+un2)!un3!unnorte!

=(un1+un2)!un1!un2!×(un1+un2+un3)!(un1+un2)!un3!×(un1+un2++unnorte)!(un1+un2+un3)!unnorte!

==(un1+un2un1)(un1+un2+un3un1+un2)(un1++unnorteun1++unnorte-1)

Bubbler
fuente
1
Y es por eso que los programadores deben aprender matemáticas.
Anónimo
@ Anónimo ... y use un lenguaje de programación matemáticamente inclinado.
Adám
5

MATL , 21 bytes

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

Pruébalo en línea!

Explicación

: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
fuente
@Adnan Resuelto. Y con menos bytes :-)
Luis Mendo
Se ve muy bien! :)
Adnan
@Adnan Gracias! He agregado una explicación
Luis Mendo
5

Python 2, 142 137 101 97 bytes

(Gracias @adnan por la sugerencia sobre input)

(Aplica el cálculo incremental de la versión 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

Versión original usando 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)))

Realmente, el único juego de golf en lo anterior es llamar math.factorial Fy omitir algunos espacios, por lo que probablemente haya una solución de Python más corta.

Si se necesita vuna explicación, mantiene un recuento de la frecuencia de cada dígito; el recuento se actualiza para cada dígito en cada número en el rango indicado.

En la versión original, calculamos el número de permutaciones utilizando la fórmula estándar (Σf i )! / Π (f i !). Para la versión actual, este cálculo se realiza de forma incremental distribuyendo las multiplicaciones y las divisiones a medida que vemos los dígitos. Puede que no sea obvio que la división de enteros siempre será exacta, pero es fácil de probar en base a la observación de que cada división por kdebe seguir kmultiplicados de enteros consecutivos, por lo que una de esas multiplicaciones debe ser divisible por k. (Eso es una intuición, no una prueba).

La versión original es más rápida para argumentos grandes porque solo divide 10 bignum. Aunque dividir un bignum por un entero pequeño es más rápido que dividir un bignum por un bignum, cuando tienes miles de divisiones de bignum, se vuelve un poco lento.

rici
fuente
f = f * sum (v) / v [k] -> f * = sum (v) / v [k] guarda un byte
Mikko Virkkilä
@superflux: pero no tiene el mismo significado.
rici
5

Python 2, 197 Bytes (editar: guardado 4 bytes, ¡gracias 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

Sin golf:

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
fuente
1
¡Bienvenido a Programming Puzzles y Code Golf! Esta respuesta se marcó como VLQ (muy baja calidad), sospecho porque no contiene ninguna explicación o versión no protegida, que son la norma aquí. Asumiendo que su respuesta funciona, y la mejora de ser "solo código", ¡parece bastante buena!
gato
range(0,10)puede ser range(10).
lirtosiast
4

CJam, 21 19 bytes

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

Pruébalo aquí.

Explicación

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

Prueba

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
fuente
¿No es k[c]=~-k[c]sinónimo de --k[c]?
usandfriends
1
@usandfriends no, cuando k [c] no está definido --k [c] es NaN
edc65
Ooh, buena variedad de factoriales.
Neil
... aunque no lo necesites. Mira mi última actualización.
Neil
3

Pyth, 18 bytes

/F.!M+lJ.njRTQ/LJT

Pruébelo en línea: demostración

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

Ejemplo de uso: h 12-> 1816214400.

Cómo funciona

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
fuente
3

C, 236 174 138 121 bytes

Mucho crédito a rici, por la reducción masiva de 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);}

Sin golf

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

Probarlo aquí .

Cole Cameron
fuente
1
Podrías guardar 43 caracteres al no jugar con -lm. Solo cuente los dígitos a medida que los encuentre:#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
También podría contarlos en el bucle donde calcula d: for(;m<10;)s+=b[m],d*=f(b[m++])pero creo que son un par de bytes más.
rici
Eso es brillante. Me combinaré con mis esfuerzos de golf actuales y editaré.
Cole Cameron
Agradable: eche un vistazo al mío para ver cómo integrar el cálculo factorial en el bucle original, que tiene la ventaja de trabajar en un rango ligeramente mayor si no tiene una aritmética de precisión arbitraria. Creo que son otros 20 bytes para afeitarse.
rici
3

C / bc, 233 121 112 bytes (suponiendo 3 pena de byte para |bc)

  1. Inspirado por Cole Cameron, eliminó la manipulación de personajes extravagantes y solo hizo aritmética en el valor del argumento.

  2. Se cambió a scanf por usar el vector 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");}
    

Necesita bchacer el cálculo de precisión arbitrario.

Sin golf y sin advertencia:

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

Ilustrado (en el que confío muestra el algoritmo):

$ 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

Y, con la tubería a través de bc (y agregando el cálculo de 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

Esto calculó F (5000), un número de 18,592 dígitos, en menos de 10 segundos.

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

real    0m9.274s
user    0m9.273s
sys     0m0.005s
rici
fuente
3

Perl 6, 117 bytes

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

y en un fasion más legible

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

Muchas gracias a dev-null por guardarme 17 bytes, y a japhy por la idea factorial.

msh210
fuente
3

05AB1E , 13 12 11 bytes

ÝD¨SāPr¢!P÷

Pruébalo en línea!

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

Pruébalo en línea!

  1. Convierta el rangede la entrada en una sola cadena
  2. Verifique cuántas veces aparece cada uno de los números del 0 al 9 en la cadena y obtenga el factorial para cada uno, luego multiplíquelos
  3. Divida el factorial de la longitud de la cadena por el número calculado en el paso 2
ElPedro
fuente
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)

Toma información $args[0], resta 1, construye un rango de enteros a partir de 0..ese número, -joins que se unen en una cadena y lo guarda como $b. Tomamos el .Lengthde esa cadena, construimos otro rango a partir de 1..esa longitud, -joinesos enteros junto con *, luego lo canalizamos a Invoke-Expression(similar aeval ). En otras palabras, hemos construido el factorial de la longitud de la secuencia numérica en función de la entrada. Ese es nuestro numerador.

Dividimos eso /por ...

Nuestro denominador, que se construye tomando un rango 0..9y enviándolo a través de un ciclo for |%{...}. En cada iteración, establecemos una variable auxiliar $cigual al número de veces que $_aparece el dígito actual $bgracias a la llamada .NET[regex]::matches junto con el .countatributo. Luego construimos un nuevo rango desde 1..ese valor, siempre que no sea cero. Sí, en muchos casos, esto dará como resultado un rango 1..1, que se evalúa como justo 1. Tomamos todos esos y -joinellos juntos *, y luego lo canalizamos a Invoke-Expressionotra vez. En otras palabras, hemos construido el producto de los factoriales del número de ocurrencias de cada dígito.


nótese bien

Maneja la entrada hasta 90sin problemas y en significativamente menos de un segundo.

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

... más allá de eso resulta Infinitycomo salida, ya que la longitud de la cadena permutable resulta en 170!que cabe en el doubletipo de datos ( 7.25741561530799E+306), pero 171!no lo hace. PowerShell tiene una peculiaridad ... ... que automáticamente-elencos de [int]que [double]en el caso de desbordamiento (siempre que no convierta explícitamente la variable para empezar). No, no sé por qué no se utiliza [long]para valores enteros.

Si hiciéramos algo de conversión y manipulación explícitas (p. Ej., Usando [uint64], para enteros de 64 bits sin signo), podríamos hacerlo más alto, pero se hincharía significativamente el código ya que necesitaríamos un rango de hasta 170 de longitud con condicionales y luego refundir cada multiplicación a partir de ahí en adelante. Como el desafío no especifica un rango superior, supongo que esto es adecuado.

AdmBorkBork
fuente
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'

Más bien no golfista en este momento, necesito dormir ahora.

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

Mi humilde primera solución de Code Golf. Puedes probarlo aquí.

Y aquí hay una versión más legible:

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

Muy sencillo, pero hubo un par de puntos destacados para mí:

  • Realizar una inyección / reducción de una matriz de charsa Map<Character, Integer>. Esto todavía era un poco complicado por la falta de un valor predeterminado para los valores del mapa. Esta duda es posible, pero si el mapa predetermina todos los valores a 0, podría evitar el ternario que es necesario para evitar un NPE.

  • El operador Groovy spread (p }*.value. Ej. ) Siempre es divertido de usar

Sin embargo, una característica molesta era la necesidad de declarar la función factorial con el tipo de retorno BigInteger. Tenía la impresión de que Groovy incluía todos los números en BigIntegero BigDecimal, pero este podría no ser el caso cuando se trata de tipos de retorno. Tendré que experimentar más. Sin este tipo de retorno declarado explícitamente, obtenemos valores factoriales incorrectos muy rápidamente.

Lealand
fuente
2

J, 33 bytes

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

Convierte el rango en una cadena de dígitos, cuenta cada dígito y aplica el coeficiente multinomial para calcular el resultado.

Uso

   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
millas
fuente
2

R, 118 bytes

Aproximadamente 8 meses tarde a la fiesta, pero pensé en intentarlo porque parecía un desafío interesante.

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)

Pruébalo en R-Fiddle

Explicado

  1. Genera un vector 0 ... n-1y lo contrae en una cadena:paste(1:n-1,collapse="")
  2. Divida la cadena en sus dígitos y conviértala en numérica (almacenar como x):x=as.numeric(el(strsplit(...,"")))
  3. Para calcular el numerador simplemente hacemos lo factorial(sum(1|x))que es#digits!
  4. Para calcular el denominador usamos tablepara construir una tabla de contingencia que enumere las frecuencias. En el caso de F (12) la tabla generada es:

    0 1 2 3 4 5 6 7 8 9 
    2 4 1 1 1 1 1 1 1 1 
    
  5. Lo que significa que podemos tomar el uso factorial()(que por cierto está vectorizado) en el recuento y simplemente tomar el producto:prod(factorial(table(x)))

Nota: los pasos 4 y 5 solo se llevan a cabo si de lo n>0contrario regresan 1.

Billywob
fuente
1

Mathematica, 65 bytes

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

Probablemente podría jugar más golf.

LegionMammal978
fuente
1

Stax , 12 bytes

éÄ\↑≈g→FP○░→

¡Ejecútelo y depúrelo en staxlang.xyz!

Desempaquetado (14 bytes) y explicación:

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
fuente
1

Jalea , 11 bytes

Golfed Dennis '15 bytes Jelly respuesta ...

ḶDFµW;ĠẈ!:/

Un enlace monádico que acepta un número entero no negativo que produce un número entero positivo.

Pruébalo en línea! O vea el conjunto de pruebas .

¿Cómo?

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

Pruébalo en línea!

Alexey Burdin
fuente
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

Pruébalo en línea!

Un enfoque alternativo ...

Chas Brown
fuente