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

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!


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


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

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


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.


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!


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


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


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.


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.

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.


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 .


┅⟨ΣΠ⟩°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.

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 .


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


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

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



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!


É 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

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

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.

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.