Persistência multiplicativa


46

Persistência Multiplicativa

  1. Multiplique todos os dígitos em um número
  2. Repita até que você tenha um único dígito restante

Conforme explicado por Numberphile :

Exemplo

  1. 277777788888899 → 2x7x7x7x7x7x7x8x8x8x8x8x8x9x9 = 4996238671872
  2. 4996238671872 → 4x9x9x6x2x3x8x6x7x1x8x7x2 = 438939648
  3. 438939648 → 4x3x8x9x3x9x6x4x8 = 4478976
  4. 4478976 → 4x4x7x8x9x7x6 = 338688
  5. 338688 → 3x3x8x6x8x8 = 27648
  6. 27648 → 2x7x6x4x8 = 2688
  7. 2688 → 2x6x8x8 = 768
  8. 768 → 7x6x8 = 336
  9. 336 → 3x3x6 = 54
  10. 54 → 5x4 = 20
  11. 20 → 2x0 = 0

A propósito, este é o registro atual: o menor número com o maior número de etapas.

Golfe

Um programa que pega qualquer número inteiro como entrada e, em seguida, gera o resultado de cada etapa, começando com a própria entrada, até atingirmos um único dígito. Para 277777788888899, a saída deve ser

277777788888899
4996238671872
438939648
4478976
338688
27648
2688
768
336
54
20
0

(Contar o número de etapas é deixado como um exercício para o usuário).

Mais exemplos

De A003001 :

25
10
0

A partir de A003001 também:

68889
27648
2688
768
336
54
20
0

Do Numberphile vídeo:

327
42
8

Portanto, houve uma pergunta sobre a persistência aditiva , mas essa é a persistência multiplicativa. Além disso, essa pergunta pede o número de etapas como saída, enquanto estou interessado em ver os resultados intermediários.


Bônus: encontre um novo registro: o menor número com o maior número de etapas. Advertência: conjectura diz que 11 é o maior possível.
SQB 21/03

7
Você provavelmente deve incluir mais alguns casos de teste que não terminam com . 0 0
Arnauld

Veio para fazer este post, encontrei-o já existente, gg
cat

é uma entrada válida de um dígito?
dzaima 21/03

1
No vídeo da Numberphile, Matt Parker afirma que foram feitas pesquisas com várias centenas de dígitos.
HardScale 21/03

Respostas:


7

Gelatina , 4 bytes

DP$Ƭ

Experimente online!

Explicação

D    | convert to decimal digits
 P   | take the product
  $  | previous two links as a monad
   Ƭ | loop until no change, collecting all intermediate results

Como bônus, aqui está um TIO que encontrará os números com o maior número de etapas para um determinado intervalo de números de dígitos. Escala bem mesmo no TIO.


15

TI-BASIC (TI-84), 30 32 31 bytes

-1 byte graças a @SolomonUcko!

While Ans>9:Disp Ans:prod(int(10fPart(Ans10^(seq(-X-1,X,0,log(Ans:End:Ans

A entrada é no Ans.
A saída é exibida como as solicitações de desafio. O final Ansé necessário para imprimir a última etapa.

Admito que não pensei nessa fórmula, mas a encontrei aqui e a modifiquei para melhor atender ao desafio.

EDIT: Ao reler o desafio, percebi que o programa deve terminar se o produto tiver um dígito. Portanto, 2 bytes deveriam ser adicionados para explicar isso.

Exemplo:

24456756
        24456756
prgmCDGF8
        24456756
          201600
               0
11112
           11112
prgmCDGF8
           11112
               2

Explicação:

While Ans>9               ;loop until the product is one digit
Disp Ans                  ;display the current product
prod(                     ;get the product of...
 int(                     ; the integer part of...
  10fPart(                ; ten times the fractional part of...
  Ans                     ; each element in the following list times the
                          ;  current product
  10^(                    ; multiplied by the list generated by using each
                          ;  element of the following list as an exponent
                          ;  for 10^n
   seq(-X-1),X,0,log(Ans  ; generate a list of exponents from -1 to -L where
                          ;  L = the length of the current product
End
Ans                       ;leave the final product in "Ans" and implicitly
                          ; print it

Modelo Visual:
Ans começa como 125673.
Este modelo cobre apenas a lógica por trás da multiplicação dos dígitos; tudo o resto é mais fácil de entender.

seq(-X-1,X,0,log(Ans  =>  seq(-X-1,X,0,5.0992
   {-1 -2 -3 -4 -5 -6}
10^(...
   {.1 .01 .001 1E-4 1E-5 1E-6}
Ans...
   {12567.3 1256.73 125.673 12.5673 1.25673 .125673}
fPart(...
   {.3 .73 .673 .5673 .25673 .125673}
10...
   {3 7.3 6.73 5.673 2.5673 1.25673}
int(...
   {3 7 6 5 2 1}
   (the digits of the number, reversed)
prod(...
   1260
   (process is repeated again)

seq(-X-1,X,0,log(Ans  =>  seq(-X-1,X,0,3.1004
   {-1 -2 -3 -4}
10^(...
   {.1 .01 .001 1E-4}
Ans...
   {126 12.6 1.26 .126}
fPart(...
   {0 .6 .26 .126}
10...
   {0 6 2.6 1.26}
int(...
   {0 6 2 1}
prod(...
   0
   (product is less than 10.  loop ends)

Notas:

TI-BASIC é uma linguagem tokenizada. Contagem de caracteres não é igual à contagem de bytes.

10^(é esse token de um byte .

Este programa não fornecerá a sequência correta de produtos com números inteiros maiores que 14 dígitos, devido às limitações da precisão decimal nas calculadoras de TI.


Você pode salvar um byte movendo-se para 10^(fora seq(e omitindo o parêntese de fechamento?
Solomon Ucko

Sim, acredito que sim!
Tau

11

K (ngn / k) , 9 bytes

{*/.'$x}\

Experimente online!

{ }\ continue aplicando a função entre chaves até a sequência convergir

$x formate o argumento como uma sequência (lista de caracteres)

.'avaliar cada um (outros dialetos de k requerem dois pontos .:')

*/ vezes, ou seja, produto



8

R , 59 bytes

n=scan();while(print(n)>9)n=prod(n%/%10^(nchar(n):1-1)%%10)

Experimente online!

Como print invisiblyretorna sua entrada, podemos usar print(n)dentro do whileloop para simular um do-whileloop. Isto é inspirado por uma das minhas dicas para golfe em R .

O cabeçalho ajuda a impedir que grandes números sejam impressos em notação científica.







5

PowerShell , 54 bytes

for($a=$args;$a-gt9){$a;$a=("$a"|% t*y)-join"*"|iex}$a

Experimente online!


Método iterativo que primeiro grava o argumento de entrada, depois o converte em uma string e o canaliza em uma matriz de caracteres. Essa matriz é unida por um único asterisco e é executada como um comando com o alias da expressão de chamada. Como isso escreve o número inicial até o último número maior que 0, (20, no cenário de teste fornecido), adiciono uma final $aao final na saída.



5

PHP , 63 bytes

<?=$n=$argn;while($n>9)echo"
",$n=array_product(str_split($n));

Versão iterativa, ligue com php -nF entrada deSTDIN .

Experimente online!

PHP ,72 71 bytes

function h($n){echo"$n
",($n=array_product(str_split($n)))>9?h($n):$n;}

Experimente online!

Versão recursiva, como função.

Entrada: 277777788888899

277777788888899
4996238671872
438939648
4478976
338688
27648
2688
768
336
54
20
0

Entrada: 23

23
6

5

Python 2 , 61 62 59 bytes

def f(n):print n;n>9and f(reduce(int.__mul__,map(int,`n`)))

Experimente online!

-3 bytes, graças a Jonathan Allan


Não funciona para entradas que não terminam com 0 na última iteração, por exemplo 23
Modalidade de ignorância

int.__mul__é três bytes menor quelambda a,b:a*b
Jonathan Allan

@JonathanAllan Thanks! Eu sabia que tinha que haver algo assim
TFeld 21/03

Mude f(reduce(int.__mul__,map(int,`n`)))para f(eval('*'.join(`n`)))para salvar 13 bytes.
mypetlion 21/03

@ypetlion ... Eu já fiz isso em outro post.
Jonathan Allan


5

MathGolf , 9 10 bytes

h(ôo▒ε*h(→

Experimente online!

Agora, ele manipula corretamente entradas com um dígito. Não é perfeito, mas pelo menos está correto.

Explicação

h(            check length of input number and decrease by 1
  ö       →   while true with pop using the next 6 operators
   p          print with newline
    ▒         split to list of chars/digits
     ε*       reduce list by multiplication
       h(     length of TOS without popping, subtracted by 1 (exits when len(TOS) == 1)

A saída para uma entrada de um dígito deve ser uma cópia do número - esclarecido nos comentários
dzaima

@dzaima Vou dar uma olhada e atualizar a resposta quando ela for resolvida
maxb 22/03




4

APL (NARS), 19 caracteres, 38 bytes

{⍵≤9:⍵⋄∇×/⍎¨⍕⍵⊣⎕←⍵}

teste:

   f←{⍵≤9:⍵⋄∇×/⍎¨⍕⍵⊣⎕←⍵}
   f 23     
23
6
   f 27648     
27648
2688
768
336
54
20
0




4

Japt -R , 9 bytes

Horrivelmente ineficiente - nem tente executar o primeiro caso de teste!

_ì ×}hN â

Tente

_ì ×}hN â     :Implicit input of integer U
      N       :Starting with the array of inputs (i.e., [U])
     h        :Do the following U times, pushing the result to N each time
_             :Take the last element in N and pass it through the following function
 ì            :  Convert to digit array
   ×          :  Reduce by multiplication
    }         :End function
        â     :Deduplicate N
              :Implicitly join with newlines and output

3

Braquilog , 7 bytes

ẉ?Ḋ|ẹ×↰

Experimente online!

Explicação

ẉ          Write the input followed by a linebreak
 ?Ḋ        If the input is a single digit, then it's over
   |       Otherwise
    ẹ      Split the input into a list of digits
     ×     Multiply them together
      ↰    Recursive call with the result of the multiplication as input

Eu mesmo tentei. Esqueceu sobre o Ḋ. O resto eu tive o mesmo.
Kroppeb 21/03


3

PowerShell , 64 59 bytes

for($a="$args";9-lt$a){$a;$a="$(($a|% t*y)-join'*'|iex)"}$a

Experimente online!

Método iterativo. Pega a entrada e a armazena $a, depois entra em um forloop desde que o comprimento de $aseja dois ou mais (ou seja, é maior que 9). Dentro do loop, produzimos $ae depois o recalculamos, convertendo-o em tCharArra y, joinjuntando-o com *, e depois iex(abreviação de Invoke-Expressione semelhante a eval). Uma vez que estamos fora do circuito, temos um único dígito para imprimir, então colocamos $ano pipeline novamente.

-5 bytes graças ao KGlasier.


Você pode usar a comparação em 9-lt$avez de $a.length-1salvar 5 bytes. E se você não seguisse o tempo todo, poderia cortar um pedaço decente. Confira minha tentativa de PowerShell, se quiser!
KGlasier 21/03

3

Carvão vegetal , 13 bytes

θW⊖Lθ«≔IΠθθ⸿θ

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

θ

Imprima a entrada pela primeira vez.

W⊖Lθ«

Repita enquanto o comprimento da entrada não for 1.

≔IΠθθ

Substitua a entrada pelo seu produto digital convertido em string.

⸿θ

Imprima a entrada em uma nova linha.


3

Retina , 24 bytes

.+~(\`

.
$&$*
^
.+¶$$.(

Experimente online! Explicação:

.+~(\`

Imprima o valor atual em sua própria linha no início de cada loop até que ele pare de mudar e não imprima o valor inalterado duas vezes. Avalie o valor atual no final de cada loop.

.
$&$*

Adicione um *após cada dígito.

^
.+¶$$.(

Termine de transformar a entrada em uma expressão que seja avaliada para o produto digital.

Apenas para o registro, o Retina pode fazer isso em uma linha (25 bytes):

.+"¶"<~[".+¶$.("|'*]'*L`.

3

C (gcc) , 58 bytes

f(n,t){for(;n=printf("%d\n",t=n)>2;)for(;n*=t%10,t/=10;);}

Experimente online!

A abordagem iterativa acaba sendo 1 byte menor.

f(n,t){
    for(;n=printf("%d\n",t=n)   //print and update current number
            >2;)                //until only one digit is printed
        for(;n*=t%10,t/=10;);   //n*= product of digits of t (step)
}

C (gcc) , 61 59 bytes (recursivo)

f(n){printf("%d\n",n)>2&&f(p(n));}p(n){n=n?n%10*p(n/10):1;}

Experimente online!

A recursão parece ser mais curta que a iteração para impressão e etapa ...

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.