A sequência Adicionar-Multiplicar-Adicionar

27

( Relacionado )

Dado um número inteiro n > 1,
1) Construa o intervalo de números n, n-1, n-2, ... 3, 2, 1e calcule a soma
2) Pegue os dígitos individuais desse número e calcule o produto
3) Pegue os dígitos individuais desse número e calcule a soma
4) Repita as etapas 2 e 3 até você atingir um único dígito. Esse dígito é o resultado.

Os primeiros vinte termos da sequência estão abaixo:

3, 6, 0, 5, 2, 7, 9, 2, 7, 9, 1, 9, 0, 0, 9, 6, 7, 0, 0, 6

Nota: Esta sequência NÃO está no OEIS.

E / S e regras

  • Os números ficarão muito grandes rapidamente, portanto, a solução deve ser capaz de lidar com números de entrada de até 100.000 sem falhas (tudo bem se o seu código aguentar além disso).
  • A entrada e saída podem ser fornecidas por qualquer método conveniente .
  • Um programa completo ou uma função são aceitáveis. Se uma função, você pode retornar a saída em vez de imprimi-la.
  • As brechas padrão são proibidas.
  • Isso é portanto todas as regras usuais de golfe se aplicam e o código mais curto (em bytes) vence.

Exemplos

n     output
1234   9
3005   3
5007   5
9854   8
75849  8
100000 0
AdmBorkBork
fonte
3
+1 para um desafio de sequência que não está no OEIS
JAD
2
Sempre que n ≤ 100000 , apenas duas iterações das etapas 2 e 3 são suficientes para obter o resultado. Podemos tirar proveito disso ou o algoritmo escolhido escolhe trabalhar com valores maiores de n ?
Dennis19
2
@ Dennis O algoritmo deve funcionar com qualquer valor de n. A solução postada apenas precisa funcionar até n = 100000.
AdmBorkBork
3
Numbers will get very large quicklynão, não
l4m2 05/05
3
@ l4m2 Não é a saída. Mas 100000 + 99999 + ... + 1 = 5000050000 é um número de 33 bits, que seu idioma preferido pode ou não ter problemas para representar.
Dennis

Respostas:

10

Python 2 , 77 72 71 62 60 bytes

lambda n:reduce(lambda x,c:eval(c.join(`x`)),'*+'*n,-n*~n/2)

Graças a @xnor por jogar fora 2 bytes!

Experimente online!

Dennis
fonte
Eu apenas mudou para um loop, mas eu vou ter que lembrar que truque para o futuro.
Dennis
Cadê o repeat until you reach a single digit?
Titus
2
@Titus I simplesmente executar n iterações das etapas 2 e 3, o que é sempre suficiente. De fato, desde n ≤ 100000 , três iterações seriam suficientes.
Dennis
Agora que você mencionou: na verdade, a menor entrada que exigiria três iterações é 236172; e esse é o único abaixo de 1 milhão.
Titus
Você pode reduzir
xnor
8

05AB1E , 7 bytes

LOΔSPSO

Experimente online!

Exlpanação

L         # push range [1 ... input]
 O        # sum range
  Δ       # loop until top of stack stops changing
   SP     # product of digits
     SO   # sum of digits
Emigna
fonte
Quase apenas ASCII! : D
AdmBorkBork
@AdmBorkBork: Sim, não é muito comum: P
Emigna
4

Gelatina , 8 bytes

RSDPDƲÐL

Experimente online!

Programa completo (retorna uma matriz singleton contendo o resultado, mas os colchetes não são visíveis no STDOUT).

Erik, o Outgolfer
fonte
Esta é a resposta Jelly mais "natural" que eu já vi. Existem apenas 2 caracteres não ASCII
RedClover
Por favor, não podemos discutir aqui, obrigado. : P TNB pode ser um local alternativo para discutir isso, se não houver ruído. ;)
Erik the Outgolfer
4

MATL , 15 13 bytes

Em homenagem ao idioma do mês :

:`sV!UpV!Utnq

Experimente online!

Eu não acho que exista uma maneira mais simples de obter os dígitos de um número do que converter o número em uma string V, transpor e transpor !esse vetor vertical de volta para um numérico U.

Economizou 2 bytes graças ao próprio Criador 1 ! Eu esqueci o fim implícito, o que significa que eu poderia remover ]e, em vez de comparar o número de elementos 1, eu poderia simplesmente diminuir esse valor e usá-lo como um booleano diretamente.

Então, a explicação é assim:

                 % Grab input n implicitly
:                % Range from 1 ... n inclusive
 `               % Do ... while
  s               % sum the vector
   V!U            % Convert the number to digits
      p           % Take the product of these digits
       V!U        % Convert the product into digits
          t       % Duplicate the result
           n      % Count the number of elements
            q     % Decrement the number of elements
                  % Loop until the number of elements is 1
                 % Implicit end

1 ... de MATL, Luis Mendo.

Stewie Griffin
fonte
3

JavaScript (ES6), 60 bytes

f=(n,k=n*++n/2)=>k>9?f(!n,eval([...k+''].join('*+'[+!n]))):k

Experimente online!

Comentado

f = (                     // f = recursive function taking:
  n,                      //   n = original input
  k = n * ++n / 2         //   k = current value, initialized to sum(i=1..n)(i)
) =>                      //
  k > 9 ?                 // if k has more than 1 digit:
    f(                    //   recursive call to f() with:
      !n,                 //     a logical NOT applied to n
      eval(               //     the result of the expression built by:
        [...k + '']       //       turning k into a list of digits
        .join('*+'[+!n])  //       joining with '*' on even iterations or '+' on odd ones
      )                   //     end of eval()
    )                     //   end of recursive call
  :                       // else:
    k                     //   stop recursion and return the last value

Versão alternativa, 59 bytes (não concorrente)

Uma versão não recursiva que funciona apenas para n <236172 . (Ele cobre o intervalo solicitado, mas não se qualifica como um algoritmo genérico válido.)

n=>[...'*+*+'].map(o=>n=eval([...n+''].join(o)),n*=++n/2)|n

Experimente online!

Arnauld
fonte
sua versão principal é interrompida quando N> = 77534568790. Funciona quando N = 7753456879; não tenho certeza exatamente onde está o ponto de interrupção. Claro, isso não importa, porque a exigência é apenas para lidar com até N = 100.000, então eu não sei por que eu escrevi isso ....
Ross Presser
1
@RossPresser Como uma estimativa aproximada, eu diria que sim Number.MAX_SAFE_INTEGER ** 0.5 ~= 94906265.
Arnauld
3

Haskell , 72 71 63 bytes

g=map(read.pure).show
f n=until(<10)(sum.g.product.g)$sum[1..n]

Graças a @BMO por um byte e @nimi por 8 bytes!

Experimente online!

Angs
fonte
2

Stax , 14 13 10 bytes

ñu┌↕a√äJ²┐

Execute e depure

Foi muito divertido de fazer. Gostaria de saber se existe uma maneira mais concisa de fazer a comparação no final.

Explicação

|+wE:*E|+c9>                 # Full Program Unpacked
|+                           # Create range and sum it
   wE:*                      # Start loop, digitize number, product of digits
       E|+                   # Digitize number, sum digits
          c9>                # Duplicate, check length is = 1
                             # Otherwise loop back to the 'w' character

-1 bytes graças a ovs

-3 bytes graças ao Scrooble

Multi
fonte
2

R , 152 130 109 bytes

function(w,x=w*(w+1)/2,y=prod(d(x)),z=sum(d(y)))"if"(z>9,f(,z),z)
d=function(x)x%/%10^(0:max(0,log10(x)))%%10

Experimente online!

A Giuseppe encontrou 21 42 bytes com várias coisas de R que eu ainda não estou acostumada, junto com uma maneira de obter os dígitos de um número sem forçar a string e voltar e com menos bytes!

# Old
d=function(x)strtoi(el(strsplit(paste(x),"")))
# New
d=function(x)x%/%10^(0:max(0,log10(x)))%%10

options(scipen=9) se foi necessário para o caso de 9854 para a função de idade, porque a primeira fase de produto acaba como 80000, o qual R gravuras como 8e + 05.

ngm
fonte
Ah entendo. Saída de notação científica. Boa pegada!
AdmBorkBork
1
Finalmente contornei o scipen: Experimente online ! note que max(0,log10(x))é porque se x=0, então log10(0)=-Infisso causa um erro.
Giuseppe
1

Pitão , 11 bytes

usj*FjGTTsS

Experimente aqui!

usj * FjGTTsS - Programa completo. N = a entrada.
          Gama S. Rendimento [1, N] ⋂ ℤ.
         s - soma.
u - Embora duas iterações consecutivas produzam o mesmo resultado, faça (var: G):
   * FjGT - produto digital.
 sj T - soma digital.
Mr. Xcoder
fonte
1

Carvão , 18 bytes

≔Σ…·¹NθW›θ⁹≔ΣΠθθIθ

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

≔Σ…·¹Nθ

Soma os números inteiros até a entrada.

 W›θ⁹≔ΣΠθθ

Enquanto o resultado for maior que 9, pegue a soma dos dígitos do produto dos dígitos.

Iθ

Transmitir o resultado para string e imprimi-lo implicitamente.

Neil
fonte
1

Gaia , 8 bytes

┅⟨Σ₸∨Π⟩°

Experimente online!

A explicação antiga (antes de corrigir um bug que é culpa de Gaia, IMO: P):

- ° - Programa completo. N = a entrada.
Range - Alcance. Pressione [1, N] ⋂ ℤ para a pilha.
 - ° - Embora não haja duas iterações consecutivas produzindo o mesmo resultado, faça:
  Sum - Soma (ou soma digital, quando aplicada a um número inteiro).
   Digital - Produto digital.

Guardado 1 byte graças a Dennis .

Mr. Xcoder
fonte
┅⟨ΣΠ⟩°salva um byte.
Dennis
Isso não funciona para valores eram a soma digital é 0, como4
Jo Rei
@JoKing Fixed, obrigado por descobrir isso. Infelizmente, em Gaia, obtendo os dígitos dos 0resultados []por algum motivo :(
Sr. Xcoder 04/04
1

F #, 175 bytes

let d n=seq{for i in(string n).ToCharArray() do yield string i|>uint64}
let c n=
 let mutable r=Seq.sum{1UL..n}
 while r>9UL do r<-d r|>Seq.reduce(fun a x->x*a)|>d|>Seq.sum
 r

Experimente online!

A única ressalva à função é que o valor de entrada deve ser do tipo uint64 .

Ungolfed é um pouco assim:

let d n=seq{for i in(string n).ToCharArray() do yield string i|>uint64}

let c n =
 let mutable r = Seq.sum {1UL..n}
 while r > 9UL do
  r<-d r
  |> Seq.reduce(fun a x->x*a)
  |> d
  |> Seq.sum
 r

A função d n converte o número nem seus dígitos do componente. Ele primeiro se converte em uma sequência e depois obtém cada caractere na sequência. Cada caractere deve ser convertido novamente em uma seqüência de caracteres, caso contrário, os caracteres serão convertidos em seus valores ASCII em vez de em seus valores "reais".

A c nfunção é a função principal, com no valor inicial. Nesta função ré o nosso valor atual. O whileloop faz o seguinte:

  • Converter r em seus dígitos componentes ( d r).
  • Obtenha o produto de todos esses dígitos. Isso usa Seq.reduceuma função com o valor acumulado (a ) e o próximo valor na sequência ( x) e, nesse caso, retorna o produto. O valor inicial é o primeiro elemento na sequência.
  • Converta esse valor do produto em seus dígitos do componente (d ).
  • Soma os dígitos anteriores e atribua-os a r.
Ciaran_McCarthy
fonte
1

Befunge, 136 bytes

101p&::*+2/>:82+%01g*01p82+/:#v_$01gv
X      v_v# #:/+82p10+g10%+82: <p100<
v:g10$ >#<#^                 #<^
>82+/#v_.@
      >101p^

Você pode tentar aqui .

Embora nem todos os intérpretes tenham um tamanho de célula grande o suficiente, ele funciona com números pequenos para praticamente qualquer pessoa. Para um número maior de nvocê pode precisar de um intérprete como o BefunExec .

Gegell
fonte
1

Gol> <> , 35 33 bytes

1AY:P*2,TYMR*YR+:a(?Bt
:a(qlBaSD$

Experimente online!

-2 bytes por Jo King.

Uso extensivo de funções e loops infinitos implícitos.

Exemplo de programa completo e como funciona

1AGIE;GN
2AY:P*2,YlMR*YlR+:a(?B8R!
:a(?BaSD$

<main program>
1AG       Register row 1 as function G
   IE;    Take number input; halt on EOF
      GN  Call G and print the result as number
          Repeat indefinitely

<function G>
2AY            Register row 2 as function Y
   :P*2,       Sum of 1 to n
        Y      Call Y (break into digits)
         lMR*  Product
Y              Call Y
 lR+           Sum (an implicit zero is used)
    :a(?B      Return if the result is less than 10
         8R!   Skip initial 8 commands
               Repeat indefinitely

<function Y>
:a(?B      Return if the top is less than 10
     aSD   Divmod by 10; [... n] => [... n/10 n%10]
        $  Swap top two, so the "div" goes to the top
Bubbler
fonte
33 bytes
Jo King
1

Japonês, 16 14 13 bytes

_ì ×ìx}gN®õ x

Tente


Explicação

                  :Implicit input of integer U
         ®        :Map
        N         :The array of inputs (which just contains U)
          õ       :  Range [1,U]
            x     :  Reduce by addition
_     }g          :Take the last element of N, run it through the following function and push the result to N
                  : Repeat U times and then return the last element of N
 ì                :  Split to an array of digits
   ×              :  Reduce by multiplication
    ìx            :  Split to an array of digits and reduce by addition
Shaggy
fonte
Puro, tentei resolver esse problema sozinho, mas não encontrei uma boa solução, por isso é interessante ver a sua.
Nit
Obrigado, @Nit. Deve haver uma maneira mais curta, no entanto.
Shaggy
@Nit, entendi! Ainda convencido de que deve haver uma maneira mais curta.
Shaggy
0

PHP 7, 89 bytes

for($a=$argn*-~+$argn/2;$a>9;)$a=array_sum(($s=str_split)(array_product($s($a))));echo$a;

Execute como pipe -rou experimente online .

  • O PHP sempre recebe entrada como string, então eu tenho que usar o +cast para int para ~funcionar como desejado.
  • O pré-incremento não funcionaria: não importa onde eu o colocasse, afetaria os dois operandos.
  • Mas: não importa se o dígito único ocorre antes ou depois da iteração (iterações adicionais não mudariam nada); para que eu possa usar em for()vez dedo ... while() .
  • O PHP 7 ou posterior é necessário para a atribuição embutida do nome da função.
    O PHP mais antigo requer mais um byte: for($s=str_split,$a=...;$a>9;)$a=array_sum($s(...));
    (Não atribuir str_splita uma variável de modo algum desperdiçaria outro byte.)
Titus
fonte
0

Perl 6 , 49 bytes

{($_*.succ/2,{[+] ([*] .comb).comb}...9>=*).tail}

Experimente online!

Sean
fonte
Você pode usar em [*](.comb).combvez de([*] .comb).comb
Brad Gilbert b2gills
0

Núcleo do PowerShell , 91 101 93 bytes

Function F($a){$o=$a*($a+1)/2;1,2|%{$o=[char[]]"$([char[]]"$o"-join'*'|iex)"-join'+'|iex};$o}

Experimente online!

Ungolfed um pouco ...

Function F ($a)
{
    $o=$a*($a+1)/2;
    1..2 | % {
        $o = [char[]]"$o"-join '*' | iex;
        $o = [char[]]"$o"-join '+' | iex;
    }
    $o | Write-Output
}

Os primeiros passos foram dividir os números inteiros em dígitos - fiz isso dividindo o número inteiro em uma matriz de caracteres de cadeias . Posteriormente, insira o operando e avalie a sequência como um comando. Então, é uma questão de fazer o ciclo de adição múltipla até que a entrada tenha um dígito.

iexé um alias para o Invoke-Commandqual avalia uma sequência passada na primeira posição de parâmetro.

Editar: conforme solicitado por @AdmBorkBork , adicionei um cabeçalho de função à contagem de bytes. Além disso, fiz um pouco de matemática e percebi que um limite superior para o número de iterações é < log log 10^6 < log 6 < 2, de modo a economizar outros seis bytes.

Edite x2: o @AdmBorkBork encontrou uma maneira mais concisa de converter o número inteiro em uma expressão matemática e, em seguida, sugeriu encaminhá-lo para iex. Isso economizou 8 bytes. Obrigado!

Jeff Freeman
fonte
É bom ver outro PowerSheller por perto! No entanto, acho que você precisa incluir a definição de função Function F($a){ }na sua contagem de bytes. No entanto, você deve conseguir economizar alguns usando, em [char[]]vez de -split''-ne'', eu acho.
AdmBorkBork
[char[]]1234=Ӓ, que é inválido; Talvez eu consiga fazê-lo funcionar, mas pode não ser óbvio agora. Obrigado pela sugestão!
Jeff Freeman
Desculpe, eu não estava claro - [char[]]"$o"e um |iexpouco do que iex( ).
AdmBorkBork
Essa dica raspou 8% do meu código. Impressionante. Obrigado!
Jeff Freeman
0

Ruby , 57 bytes

->n{("*+"*n).chars.reduce(-~n*n/2){|x,y|eval x.digits*y}}

Experimente online!

Kirill L.
fonte
0

Java 8, 129 bytes

n->{long r=1,i=n;for(;i>1;r+=i--);for(;r>9;r=(i+"").chars().map(p->p-48).sum(),i=1)for(int s:(r+"").getBytes())i*=s-48;return r;}

Experimente online.

Explicação:

n->{            // Method with integer parameter and long return-type
  long r=1,     //  Result-long, starting at 1
       i=n;     //  Temp integer, starting at the input `n`
  for(;i>1;     //  Loop as long as `i` is not 1 yet
      r+=i--);  //   And increase `r` by `i`
  for(;r>9      //  Loop as long as `r` is not a single digit yet
      ;         //    After every iteration:
       r=(i+"").chars().map(p->p-48).sum(),
                //     Set `r` to the sum of digits of `i`
       i=1)     //     And reset `i` to 1
    for(int s:(r+"").getBytes())i*=s-48;
                //    Set `i` to the product of the digits of `r`
  return r;}    //  Return `r` as result
Kevin Cruijssen
fonte
0

Julia 0.6 , 56 bytes

f(n,k=(n+1)n÷2)=k>9?f(0,sum(digits(prod(digits(k))))):k

Experimente online!

Bem simples: calcule (n+1)n÷2a soma de 1..n, verifique se é um número de um dígito ( >9); caso contrário, tente novamente com k definido como a soma dos dígitos do produto dos dígitos de k, caso contrário, retorne k.

sundar - Restabelecer Monica
fonte