9erilous 9ermutations

8

Nota: Esta é uma tentativa de reciclar a (s) pergunta (s) de permutação de guest271314

Existe um padrão interessante que se forma quando você encontra as diferenças entre permutações lexograficamente classificadas dos números da base 10 com dígitos únicos ascendentes. Por exemplo, 123tem permutações:

123 132 213 231 312 321

Quando você encontra as diferenças entre elas, obtém a sequência

9 81 18 81 9

Quais são todos divisíveis por nove (por causa da soma dos dígitos dos números da base 10), além de palindrômicos.

Notavelmente, se usarmos o próximo número 1234, obtemos a sequência

9 81 18 81 9 702 9 171 27 72 18 693 18 72 27 171 9 702 9 81 18 81 9

O que estende a sequência anterior e permanece palindrômico em torno de 693 . Esse padrão sempre é válido, mesmo quando você começa a usar mais 10números, embora o comprimento da sequência seja n!-1 para n números. Observe que, para usar os números acima 0 to 9, não mudamos para uma base diferente, apenas multiplicamos o número por 10x , por exemplo, [1,12,11]10=1102+12101+11100 0=231 .

Seu objetivo é implementar essa sequência, retornando cada elemento como um múltiplo de nove. Por exemplo, os 23 primeiros elementos dessa sequência são:

1 9 2 9 1 78 1 19 3 8 2 77 2 8 3 19 1 78 1 9 2 9 1

Alguns outros casos de teste (0 indexados):

23     => 657
119    => 5336
719    => 41015
5039   => 286694
40319  => 1632373
362879 => 3978052
100    => 1
1000   => 4
10000  => 3
100000 => 3

Regras:

  • O envio pode ser:
    • Um programa / função que pega um número e retorna o número nesse índice, 0 ou 1 indexado.
    • Uma função de programa / que tem um número n e retorna-se para a n th índice, 0 ou 1 indexado.
    • Um programa / função que gera / retorna a sequência infinitamente.
  • O programa deve ser capaz de lidar teoricamente com os 11!-1 elemento e além, embora eu entenda se as restrições de tempo / memória fazem com que isso falhe. Em particular, isso significa que você não pode concatenar os dígitos e avaliar como base 10, pois algo como 012345678910 estaria errado.
  • Isso é , então a implementação mais curta para cada idioma vence!

Notas:

  • Este é o OEIS A217626
  • Ofereço uma recompensa de 500 por uma solução que elabore os elementos diretamente, sem calcular as permutações reais.
  • A sequência funciona para qualquer dígito contíguo. Por exemplo, as diferenças entre as permutações de [1,2,3,4]10 são as mesmas que para [-4,-3,-2,-1]10 .
Brincadeira
fonte
Qual é o desempate para a recompensa?
Nwellnhof 11/1118
2
Há pouco sentido em "elaborar os elementos diretamente", pois o cálculo da permutação em si leva tempo linear (no tamanho da entrada) (certo?), O que já é muito bom. Você só quer ver métodos legais?
user202729
1
10!-13628799 => -83676269
@ user202729 Talvez o OP queira algum algoritmo de tempo de log ou tempo constante? Como essa é uma sequência OEIS, esse algoritmo pode ajudar na pesquisa.
Shieru Asakoto 13/11
1
O(Γ-1(n))

Respostas:

5

Geléia , 9 bytes

,‘œ?ŻḌI÷9

Experimente online! (imprima o n-ésimo elemento)

Experimente online! (20 primeiros elementos)

Explicação:

      I÷9      Compute the difference divided by 9 between
 ‘             the (n+1)th
  œ?           permutation
,              and
               the (n)th
  œ?           permutation
    Ż          of [0,1,2,...n]
     Ḍ         converted to decimal.

(A Jelly possui o built-in œ?que calcula a npermutação de uma lista em tempo aproximadamente linear. Bastante útil.)

user202729
fonte
4

Carvão , 71 bytes

≔⟦N⊕θ⟧ηW⌈η≧÷L⊞OυEη﹪κ⊕Lυη≔⁰δF²«≔Eυλζ≔⟦⟧ηF⮌Eυ§κι«⊞η§ζκ≔Φζ⁻μκζ»≦⁻↨ηχδ»I÷δ⁹

Experimente online! Link é a versão detalhada do código. Explicação:

≔⟦N⊕θ⟧η

Obtenha uma lista contendo a entrada e mais uma que a entrada.

W⌈η

Repita até que ambos os valores sejam zero.

≧÷L⊞OυEη﹪κ⊕Lυη

Realize a conversão da base fatorial em ambos os valores. Esta é a primeira vez que eu realmente usei em uma lista!

≔⁰δ

Limpe o resultado.

F²«

Faça um loop sobre cada número base fatorial.

≔Eυλζ

Faça uma lista dos dígitos de 0 a comprimento - 1.

≔⟦⟧η

Inicialize o resultado em uma lista vazia.

F⮌Eυ§κι«

Faça um loop sobre os dígitos do número base fatorial.

⊞η§ζκ

Adicione o próximo dígito de permutação ao resultado.

≔Φζ⁻μκζ»

Remova esse dígito da lista.

≦⁻↨ηχδ»

Converta a permutação como um número base 10 e subtraia o resultado até agora.

I÷δ⁹

Divida o resultado final por 9 e faça a sequência.

Neil
fonte
3

Perl 6 , 82 bytes

-2 bytes graças a Jo King

->\n{([-] map {$/=[^n];:10[map {|splice $/,$_,1},[R,] .polymod(1..n-2)]},n+1,n)/9}

Experimente online!

Indexado a 0. Não enumera todas as permutações. Teoricamente, deve funcionar para todos os n, mas é compatível com n> 65536 com "Muitos argumentos na matriz de nivelamento".

A seguinte versão de 80 bytes funciona para n até 98! -2 e é muito mais rápida:

{([-] map {$/=[^99];:10[map {|splice $/,$_,1},[R,] .polymod(1..97)]},$_+1,$_)/9}

Experimente online!

A versão de 53 bytes a seguir deve, teoricamente, funcionar para todos os n, mas é defasada para n> = 20 com "recusando-se a permutar mais de 20 elementos".

{[-](map {:10[$_]},permutations(1..$_+1)[$_,$_-1])/9}

Experimente online!

Nwellnhof
fonte
2

JavaScript (Node.js) , 134 bytes

n=>(F=_=>f>n?((G=(n,z=0,x=f,y=l,b=[...a])=>y?G(n%(x/=y),+b.splice(n/x,1)+z*10,x,y-1,b):z)(n--)-G(n))/9:F(a.push(++l),f*=l))(a=[l=f=1])

Experimente online!

1 indexado.

A opinião de @ guest271314 está certa. O cálculo da permutação direta é mais curto ...

Explicação

n=>(                           // Function -
 F=_=>                         //  Helper func to calculate length needed
 f>n?                          //   If f > n (meaning the length is enough) -
  (
   (
    G=(                        //    Helper func to calculate permutation value -
     n,
     z=0,                      //     Initial values
     x=f,                      //     Made as copies because we need to alter
     y=l,                      //     these values and the function will be
     b=[...a]                  //     called twice
    )=>
    y?                         //     If still elements remaining -
     G(
      n%(x/=y),                //      Get next element
      +b.splice(n/x,1)+z*10,   //      And add to the temporary result
      x,
      y-1,                     //      Reduce length
      b                        //      Remaining elements
     )
    :z                         //     Otherwise return the permutation value
   )(n--)-G(n)                 //    Calculate G(n) - G(n - 1)
  )/9                          //    ... the whole divided by 9 
 :F(
  a.push(++l),                 //   Otherwise l = l + 1, push l into the array
  f*=l                         //   ... and calculate l!
 )
)(
 a=[l=f=1]                     //  Initial values
)

Solução original (159 bytes)

n=>(x=l=t=0n,P=(a,b=[])=>n?""+a?a.map(z=>P(a.filter(y=>y-z),[...b,z])):(v=b.reduce((u,y)=>u=u*10n+y),x?--n?0:t=v-x:0,x=v):0)([...Array(n+1))].map(_=>++l))&&t/9n

Experimente online!

O link é para uma versão mais longa feita para desempenho. Array(n+1)torna-se Array(Math.min(n+1,15))para fazer o trabalho de demonstração. Teoricamente, funciona até o infinito (na prática, até o limite de empilhamento).

Explicação

Quero dizer, há muito para explicar.

n=>(                             // Function
 x=l=t=0n,                       // Initialization
 P=(                             // Function to determine the permutation -
  a,                             //  remaining items
  b=[]                           //  storage
 )=>
 n?                              //  if we haven't reached the required permutation yet - 
  ""+a?                          //   if we haven't the last layer of loop - 
   a.map(                        //    loop over the entries -
    z=>      
    P(                           //     recurse -
     a.filter(y=>y-z),           //      pick out the selected number
     [...b,z]                    //      append to next 
    )
   )
  :(                             //   if we are at the last layer -
   v=b.reduce((u,y)=>u=u*10n+y), //    calculate the value of the permutation
   x?                            //    if not the first number -
    --n?                         //     if not the last -
     0                           //      do nothing
    :t=v-x                       //     else calculate difference
   :0,                           //    else do nothing
   x=v                           //    record ot anyway
  )
 :0                              //   else do nothing
)
(
 [...Array(n+1)].map(_=>++l)     // the list of numbers to permute
)&&t/9n                          // last difference divided by 9
Shieru Asakoto
fonte
FWIW, uma vez que essa implementação não retornar todas as diferenças até n, esta solução stackoverflow.com/a/34238979 fornece um meio para obter dois permutações adjacentes, ou representações número de permutações diretamente por índice, que quando golfed, deve reduzir o código necessário para produzir a saída (f(n) - f(n-1))/9para esse tipo de resposta selecionado consistente com a regra "Um programa / função que pega um número e retorna o número nesse índice, 0 ou 1 indexado". .
guest271314
2

Pyth, 15 14 bytes

.+m/i.PdSQT9,h

Retorna o enésimo termo. Experimente aqui .

.+                     Find the differences between adjacent elements of
   m                   mapping lambda d:
      .PdSQ                the dth permutation of input,
     i     T               converted to base 10
    /       9              divided by 9
             ,         over [Q+1,Q]
               h Q
               Q
lirtosiast
fonte
2

J , 44 , 41 bytes

(9%~[:(2-~/\])i.(10#.1+A.)[:i.@>.!inv)@>:

Experimente online!

Nota: funciona mesmo para 10! caso de teste, mas perde alguma precisão lá ...

explicação original

(9 %~ [: (2 -~&(10&#.)/\ ]) 1 + i. A. i.@>.@(!inv))@>:
(                                                 )@>: NB. add one to input
                                                       NB. since n-1 deltas
                                                       NB. gives n results
                                                       NB. call that "n"
(                               i.                )    NB. take the first n
(                                  A.             )    NB. lexicographically
                                                       NB. sorted items of
(                                     i.@         )    NB. 0 up to...
(                                        >.@      )    NB. the ceil of...
(                                           (!inv))    NB. the inverse of 
                                                       NB. the factorial
(                           1 +                   )    NB. add 1 so our
                                                       NB. lists start at 1
                                                       NB. instead of 0
(     [: (                )                       )    NB. apply what's in 
                                                       NB. parens to that
                                                       NB. list of lists
(        (2 -~        /\ ])                       )    NB. take successive
                                                       NB. differences BUT
(        (    &(10&#.)    )                       )    NB. convert each list
                                                       NB. to a base 10
                                                       NB. number first
(9 %~                                             )    NB. and divide every
                                                       NB. items of the
                                                       NB. result by 9
Jonah
fonte