La sequenza Aggiungi-Moltiplica-Aggiungi


27

( Correlato )

Dato un numero intero n > 1,
1) Costruisci l'intervallo di numeri n, n-1, n-2, ... 3, 2, 1e calcola la somma
2) Prendi le singole cifre di quel numero e calcola il prodotto
3) Prendi le singole cifre di quel numero e calcola la somma
4) Ripeti i passaggi 2 e 3 fino a raggiungere una singola cifra. Quella cifra è il risultato.

I primi venti termini della sequenza sono di seguito:

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

Nota: questa sequenza NON è in OEIS.

I / O e regole

  • I numeri diventeranno molto grandi rapidamente, quindi la soluzione deve essere in grado di gestire numeri di input fino a 100.000 senza errori (va bene se il tuo codice è in grado di superarlo).
  • L'input e l'output possono essere forniti con qualsiasi metodo conveniente .
  • È accettabile un programma completo o una funzione. Se una funzione, è possibile restituire l'output anziché stamparlo.
  • Sono vietate le scappatoie standard .
  • Si tratta di quindi si applicano tutte le normali regole del golf e vince il codice più breve (in byte).

Esempi

n     output
1234   9
3005   3
5007   5
9854   8
75849  8
100000 0

3
+1 per una sfida di sequenza che non è nell'OEIS
JAD

2
Ogni volta che n ≤ 100000 , solo due iterazioni dei passaggi 2 e 3 sono sufficienti per ottenere il risultato. Possiamo trarne vantaggio o l'algoritmo che scegliamo dovrebbe funzionare per valori maggiori di n ?
Dennis,

2
@Dennis L'algoritmo dovrebbe funzionare per qualsiasi valore di n. La soluzione pubblicata deve funzionare solo fino a n = 100000.
AdmBorkBork,

3
Numbers will get very large quicklyno non lo fa
l4m2

3
@ l4m2 Non l'output. Ma 100000 + 99999 + ... + 1 = 5000050000 è un numero a 33 bit, che la tua lingua preferita potrebbe avere o meno problemi a rappresentare.
Dennis,

Risposte:


10

Python 2 , 77 72 71 62 60 byte

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

Grazie a @xnor per giocare a golf con 2 byte!

Provalo online!


Sono appena passato a un ciclo for, ma dovrò ricordare quel trucco per il futuro.
Dennis,

Dov'è il repeat until you reach a single digit?
Tito,

2
@Titus Eseguo semplicemente n iterazioni dei passaggi 2 e 3, il che è sempre sufficiente. Infatti, poiché n ≤ 100000 , sarebbero sufficienti tre iterazioni.
Dennis,

Ora che lo dici: in realtà, il più piccolo input che richiederebbe tre iterazioni è 236172; e quello è l'unico sotto 1 milione.
Tito

Puoi ridurre
xnor

8

05AB1E , 7 byte

LOΔSPSO

Provalo online!

Exlpanation

L         # push range [1 ... input]
 O        # sum range
  Δ       # loop until top of stack stops changing
   SP     # product of digits
     SO   # sum of digits

Quasi solo ASCII! : D
AdmBorkBork

@AdmBorkBork: Sì, non terribilmente comune: P
Emigna

4

Gelatina , 8 byte

RSDPDƲÐL

Provalo online!

Programma completo (restituisce un array singleton contenente il risultato, ma le parentesi non sono visibili in STDOUT).


Questa è la risposta Jelly più "naturale" che abbia mai visto. Ci sono solo 2 caratteri non ASCII
RedClover


Per favore, non possiamo discutere qui, grazie. : P TNB potrebbe essere un luogo alternativo per discuterne, se non si fa rumore. ;)
Erik the Outgolfer

4

MATL , 15 13 byte

In omaggio alla lingua del mese :

:`sV!UpV!Utnq

Provalo online!

Non penso che ci sia un modo più semplice per ottenere le cifre di un numero piuttosto che convertirlo in una stringa V, quindi trasporlo !e riconvertire questo vettore verticale in uno numerico U.

Hai salvato 2 byte grazie al Creatore 1 stesso! Ho dimenticato il fine implicito, il che significa che potrei rimuovere ], e invece di confrontare il numero di elementi con 1, potrei semplicemente decrementare quel valore e usarlo direttamente come booleano.

Quindi, la spiegazione è questa:

                 % 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 ... di MATL, Luis Mendo.


3

JavaScript (ES6), 60 byte

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

Provalo online!

Commentate

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

Versione alternativa, 59 byte (non competitiva)

Una versione non ricorsiva che funziona solo per n <236172 . (Copre l'intervallo richiesto ma non si qualifica come un algoritmo generico valido.)

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

Provalo online!


la tua versione principale si interrompe quando N> = 77534568790. Funziona quando N = 7753456879; non sono sicuro di dove sia esattamente il punto di interruzione. Certo, questo non importa perché il requisito è solo di gestire fino a N = 100.000, quindi non sono sicuro del motivo per cui ho scritto questo ...
Ross Presser

1
@RossPresser Come stima approssimativa, direi che funziona piuttosto Number.MAX_SAFE_INTEGER ** 0.5 ~= 94906265.
Arnauld

3

Haskell , 72 71 63 byte

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

Grazie a @BMO per un byte e @nimi per 8 byte!

Provalo online!


2

Stax , 14 13 10 byte

ñu┌↕a√äJ²┐

Esegui ed esegui il debug

È stato abbastanza divertente da fare. Mi chiedo se alla fine ci sia un modo più conciso di fare il confronto.

Spiegazione

|+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 byte grazie a ovs

-3 byte grazie a Scrooble


2

R , 152 130 109 byte

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

Provalo online!

@Giuseppe ha trovato 21 42 byte con varie cose R a cui non sono ancora abituato, insieme a un modo per ottenere le cifre di un numero senza forzare su stringa e ritorno, e con meno byte!

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

options(scipen=9) è stato richiesto per il caso 9854 per la vecchia funzione, perché il primo stadio del prodotto finisce con 80000, che R stampa come 8e + 05.


Ah, capisco. Uscita di notazione scientifica. Buona pesca!
AdmBorkBork

1
Finalmente sono riuscito a scipen: Provalo online ! si noti che max(0,log10(x))is if x=0, log10(0)=-Infche causa un errore.
Giuseppe,

1

Pyth , 11 byte

usj*FjGTTsS

Provalo qui!

usj * FjGTTsS - Programma completo. N = L'ingresso.
          S - Range. Resa [1, N] ⋂ ℤ.
         s - Somma.
u - Anche se non esistono due iterazioni consecutive che producono lo stesso risultato, fai (var: G):
   * FjGT - Prodotto digitale.
 sj T - Somma digitale.

1

Carbone , 18 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

≔Σ…·¹Nθ

Somma gli interi fino all'input.

 W›θ⁹≔ΣΠθθ

Mentre il risultato è maggiore di 9, prendi la somma delle cifre del prodotto delle cifre.

Iθ

Trasmetti il ​​risultato in stringa e stampalo implicitamente.


1

Gaia , 8 byte

┅⟨Σ₸∨Π⟩°

Provalo online!

La vecchia spiegazione (prima di correggere un bug che è colpa di Gaia IMO: P):

┅⟨ΣΠ⟩ ° - Programma completo. N = L'ingresso.
┅ - Gamma. Spingi [1, N] ⋂ ℤ sullo stack.
 ⟨⟩ ° - Sebbene non vi siano due iterazioni consecutive che producono lo stesso risultato, fai:
  Σ - Somma (o somma digitale, quando applicata a un numero intero).
   Π - Prodotto digitale.

Salvato 1 byte grazie a Dennis .


┅⟨ΣΠ⟩°salva un byte.
Dennis,

Questo non funziona per i valori dove la somma digitale è 0, come4
Jo King,

@JoKing Risolto, grazie per averlo individuato. Sfortunatamente, a Gaia, prendere le cifre dei 0risultati []per qualche motivo :(
Mr. Xcoder

1

F #, 175 byte

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

Provalo online!

L'unica avvertenza alla funzione è che il valore di input deve essere di tipo uint64.

Ungolfed è un po 'così:

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

La funzione d nconverte il numero nnelle cifre dei suoi componenti. Prima si converte in una stringa, quindi ottiene ogni carattere nella stringa. Ogni carattere deve quindi essere riconvertito in una stringa, altrimenti i caratteri verranno convertiti nei loro valori ASCII anziché nei loro valori "reali".

La c nfunzione è la funzione principale, con ncome valore iniziale. In questa funzione rè il nostro valore corrente. Il whileciclo procede come segue:

  • Converti rnelle sue cifre componenti ( d r).
  • Ottieni il prodotto di tutte quelle cifre. Questo utilizza Seq.reducequale prende una funzione con il valore accumulato ( a) e il valore successivo nella sequenza ( x) e in questo caso restituisce il prodotto. Il valore iniziale è il primo elemento della sequenza.
  • Converti il ​​valore di questo prodotto nelle cifre dei suoi componenti ( d).
  • Somma le cifre di prima e assegnale a r.

1

Befunge, 136 byte

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

Puoi provarlo qui .

Sebbene non tutti gli interpreti abbiano una dimensione cellulare abbastanza grande, funziona con numeri piccoli praticamente per chiunque. Per un numero maggiore di nte potrebbe essere necessario un interprete come BefunExec .


1

Gol> <> , 35 33 byte

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

Provalo online!

-2 byte di Jo King.

Ampio uso di funzioni e cicli infiniti impliciti.

Esempio di programma completo e come funziona

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

Japt, 16 14 13 byte

_ì ×ìx}gN®õ x

Provalo


Spiegazione

                  :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

Bene, ho provato a risolverlo da solo, ma non ho trovato una buona soluzione, quindi è interessante vedere il tuo.
Nit

Grazie, @Nit. Tuttavia, deve esserci un modo più breve.
Shaggy

@Nit, capito! Tuttavia, sono ancora convinto che ci debba essere un modo più breve.
Shaggy,


0

PHP 7, 89 byte

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

Esegui come pipe -ro provalo online .

  • PHP accetta sempre l'input come stringa, quindi devo usare +cast per int per ~funzionare come desiderato.
  • Il pre-incremento non funzionerebbe: indipendentemente da dove lo inserissi, avrebbe effetto su entrambi gli operandi.
  • Ma: non importa se la singola cifra ha luogo prima o dopo l'iterazione (iterazioni aggiuntive non cambierebbero nulla); così posso usare for()invece di do ... while().
  • PHP 7 o successivo è necessario per l'assegnazione in linea del nome della funzione.
    PHP precedente richiede un altro byte: for($s=str_split,$a=...;$a>9;)$a=array_sum($s(...));
    (La mancata assegnazione str_splita una variabile sprecherebbe un altro byte).



0

PowerShell Core , 91 101 93 byte

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

Provalo online!

Ungolfed un po '...

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

I primi passi sono stati quelli di dividere i numeri interi in cifre, facendo questo dividendo l'intero in una matrice di caratteri di stringhe . Successivamente, inserire l'operando e quindi valutare la stringa come comando. Quindi, si tratta di eseguire il ciclo di aggiunta multipla fino a quando l'input è di una cifra.

iexè un alias per il Invoke-Commandquale valuta una stringa passata nella prima posizione param.

Modifica: come richiesto da @AdmBorkBork , ho aggiunto un'intestazione di funzione al conteggio dei byte. Inoltre, ho fatto un po 'di matematica e mi sono reso conto che esiste un limite superiore al numero di iterazioni < log log 10^6 < log 6 < 2, in modo da risparmiare altri sei byte.

Modifica x2: @AdmBorkBork ha trovato un modo più conciso di convertire l'intero in un'espressione matematica, e quindi ha suggerito di eseguirne il piping in iex. Ciò ha salvato 8 byte. Grazie!


Bello vedere un altro PowerSheller in giro! Tuttavia, penso che sia necessario includere la definizione della funzione Function F($a){ }nel conteggio dei byte. Tuttavia, dovresti essere in grado di salvare alcuni usando [char[]]invece di -split''-ne'', credo.
AdmBorkBork

[char[]]1234=Ӓ, che non è valido; Potrei essere in grado di farlo funzionare, ma potrebbe non essere ovvio proprio ora. Grazie per il suggerimento!
Jeff Freeman,

Mi dispiace non essere stato chiaro - [char[]]"$o"e |iexpiuttosto che iex( ).
AdmBorkBork

Questo suggerimento mi ha permesso di cancellare l'8% del mio codice. Eccezionale. Grazie!
Jeff Freeman,



0

Java 8, 129 byte

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;}

Provalo online.

Spiegazione:

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 byte

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

Provalo online!

Abbastanza semplice: calcola (n+1)n÷2per la somma da 1..n, controlla se si tratta di un numero a una cifra ( >9), in caso contrario, riprova con k impostato sulla somma delle cifre del prodotto delle cifre di k, altrimenti restituisci k.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.