La séquence ajouter-multiplier-ajouter

27

( Connexes )

Étant donné un entier n > 1,
1) Construisez la plage de nombres n, n-1, n-2, ... 3, 2, 1et calculez la somme
2) Prenez les chiffres individuels de ce nombre et calculez le produit
3) Prenez les chiffres individuels de ce nombre et calculez la somme
4) Répétez les étapes 2 et 3 jusqu'à ce que vous atteindre un seul chiffre. Ce chiffre est le résultat.

Les vingt premiers termes de la séquence sont les suivants:

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

Remarque: cette séquence N'EST PAS dans OEIS.

E / S et règles

  • Les nombres deviendront très volumineux rapidement, donc la solution doit être capable de gérer des nombres d'entrée jusqu'à 100 000 sans échec (c'est bien si votre code peut gérer au-delà).
  • L'entrée et la sortie peuvent être fournies par n'importe quelle méthode pratique .
  • Un programme complet ou une fonction sont acceptables. S'il s'agit d'une fonction, vous pouvez renvoyer la sortie plutôt que de l'imprimer.
  • Les failles standard sont interdites.
  • Il s'agit de donc toutes les règles de golf habituelles s'appliquent et le code le plus court (en octets) l'emporte.

Exemples

n     output
1234   9
3005   3
5007   5
9854   8
75849  8
100000 0
AdmBorkBork
la source
3
+1 pour un défi de séquence qui n'est pas dans l'OEIS
JAD
2
Chaque fois que n ≤ 100 000 , seules deux itérations des étapes 2 et 3 sont suffisantes pour obtenir le résultat. Pouvons-nous en profiter ou l'algorithme que nous choisissons devrait-il fonctionner pour des valeurs plus grandes de n ?
Dennis
2
@Dennis L'algorithme devrait fonctionner pour n'importe quelle valeur de n. La solution publiée n'a qu'à fonctionner n = 100000.
AdmBorkBork
3
Numbers will get very large quicklynon, il ne fait pas
l4m2
3
@ l4m2 Pas la sortie. Mais 100000 + 99999 + ... + 1 = 5000050000 est un nombre de 33 bits, que votre langue de choix peut ou non avoir du mal à représenter.
Dennis

Réponses:

10

Python 2 , 77 72 71 62 60 octets

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

Merci à @xnor d'avoir joué au golf sur 2 octets!

Essayez-le en ligne!

Dennis
la source
Je viens de passer à une boucle for, mais je dois me souvenir de cette astuce pour l'avenir.
Dennis
Où est le repeat until you reach a single digit?
Titus
2
@Titus J'effectue simplement n itérations des étapes 2 et 3, ce qui est toujours suffisant. En effet, puisque n ≤ 100000 , trois itérations seraient suffisantes.
Dennis
Maintenant que vous le mentionnez: En fait, la plus petite entrée qui nécessiterait trois itérations est 236172; et c'est le seul en dessous de 1 million.
Titus
Vous pouvez réduire
xnor
8

05AB1E , 7 octets

LOΔSPSO

Essayez-le en ligne!

Exlpanation

L         # push range [1 ... input]
 O        # sum range
  Δ       # loop until top of stack stops changing
   SP     # product of digits
     SO   # sum of digits
Emigna
la source
Presque ASCII uniquement! : D
AdmBorkBork
@AdmBorkBork: Ouais, pas très courant: P
Emigna
4

Gelée , 8 octets

RSDPDƲÐL

Essayez-le en ligne!

Programme complet (il retourne un tableau singleton contenant le résultat, mais les crochets ne sont pas visibles dans STDOUT).

Erik le Outgolfer
la source
C'est la réponse Jelly la plus "naturelle" que j'ai jamais vue. Il n'y a que 2 caractères non ASCII
RedClover
Euh, pouvons-nous s'il vous plaît ne pas avoir la discussion ici, merci. : P TNB pourrait être un autre endroit pour en discuter, si aucun bruit n'est fait. ;)
Erik the Outgolfer
4

MATL , 15 13 octets

En hommage à la langue du mois :

:`sV!UpV!Utnq

Essayez-le en ligne!

Je ne pense pas qu'il existe un moyen plus simple d'obtenir les chiffres d'un nombre que de convertir le nombre en chaîne V, puis de le transposer !et de reconvertir ce vecteur vertical en un numérique U.

Enregistré 2 octets grâce au Créateur 1 lui-même! J'ai oublié la fin implicite, ce qui signifie que je pourrais supprimer ], et au lieu de comparer le nombre d'éléments avec 1, je pourrais simplement décrémenter cette valeur et l'utiliser directement comme booléen.

Donc, l'explication va comme ceci:

                 % 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
la source
3

JavaScript (ES6), 60 octets

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

Essayez-le en ligne!

Commenté

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

Version alternative, 59 octets (non concurrente)

Une version non récursive qui ne fonctionne que pour n <236172 . (Il couvre la plage demandée mais n'est pas considéré comme un algorithme générique valide.)

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

Essayez-le en ligne!

Arnauld
la source
votre version principale casse lorsque N> = 77534568790. Cela fonctionne lorsque N = 7753456879; Je ne sais pas exactement où se trouve le point d'arrêt. Bien sûr, cela n'a pas d'importance parce que l'exigence est de gérer jusqu'à N = 100 000, donc je ne sais pas pourquoi j'ai écrit cela ...
Ross Presser
1
@RossPresser Comme une estimation approximative, je dirais que cela fonctionne plutôt Number.MAX_SAFE_INTEGER ** 0.5 ~= 94906265.
Arnauld
3

Haskell , 72 71 63 octets

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

Merci à @BMO pour un octet et @nimi pour 8 octets!

Essayez-le en ligne!

Angs
la source
2

Stax , 14 13 10 octets

ñu┌↕a√äJ²┐

Exécuter et déboguer

C'était assez amusant à faire. Je me demande s'il y a une façon plus concise de faire la comparaison à la fin.

Explication

|+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 octets grâce aux ovs

-3 octets grâce à Scrooble

Multi
la source
2

R , 152 130 109 octets

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

Essayez-le en ligne!

@Giuseppe a trouvé 21 42 octets avec diverses choses R auxquelles je ne suis pas encore habitué, ainsi qu'un moyen d'obtenir les chiffres d'un nombre sans forcer la chaîne et le retour, et avec moins d'octets!

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

options(scipen=9) est a été nécessaire pour le cas de 9854 pour l'ancienne fonction, parce que la première étape du produit finit comme 80000, qui imprime R + 05 comme 8 E.

ngm
la source
Ah, je vois. Sortie de notation scientifique. Bonne prise!
AdmBorkBork
1
Enfin, contournez le scipen: Essayez-le en ligne ! notez que max(0,log10(x))c'est parce que si x=0, alors log10(0)=-Infce qui provoque une erreur.
Giuseppe
1

Pyth , 11 octets

usj*FjGTTsS

Essayez-le ici!

usj * FjGTTsS - Programme complet. N = l'entrée.
          S - Gamme. Rendement [1, N] ⋂ ℤ.
         s - Somme.
u - Bien que deux itérations consécutives ne donnent pas le même résultat, faites (var: G):
   * FjGT - Produit numérique.
 sj T - Somme numérique.
M. Xcoder
la source
1

Fusain , 18 octets

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

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication:

≔Σ…·¹Nθ

Additionnez les entiers jusqu'à l'entrée.

 W›θ⁹≔ΣΠθθ

Alors que le résultat est supérieur à 9, prenez la somme des chiffres du produit des chiffres.

Iθ

Convertissez le résultat en chaîne et imprimez-le implicitement.

Neil
la source
1

Gaia , 8 octets

┅⟨Σ₸∨Π⟩°

Essayez-le en ligne!

L'ancienne explication (avant de corriger un bug qui est la faute de Gaia IMO: P):

┅⟨ΣΠ⟩ ° - Programme complet. N = l'entrée.
┅ - Gamme. Poussez [1, N] ⋂ ℤ dans la pile.
 ⟨⟩ ° - Bien que deux itérations consécutives ne donnent pas le même résultat, faites:
  Σ - Somme (ou somme numérique, lorsqu'elle est appliquée à un entier).
   Π - Produit numérique.

Enregistré 1 octet grâce à Dennis .

M. Xcoder
la source
┅⟨ΣΠ⟩°enregistre un octet.
Dennis
Cela ne fonctionne pas pour les valeurs où la somme numérique est 0, comme4
Jo King
@JoKing Fixed, merci d'avoir repéré cela. Malheureusement, à Gaia, prendre les chiffres des 0résultats []pour une raison quelconque :(
M. Xcoder
1

F #, 175 octets

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

Essayez-le en ligne!

La seule mise en garde à la fonction est que la valeur d'entrée doit être de type uint64.

Ungolfed c'est un peu comme ça:

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 fonction d nconvertit le nombre nen ses chiffres composants. Il se convertit d'abord en chaîne, puis obtient chaque caractère de la chaîne. Chaque caractère doit ensuite être reconverti en chaîne, sinon les caractères seront convertis en leurs valeurs ASCII au lieu de leurs valeurs "réelles".

La c nfonction est la fonction principale, avec ncomme valeur initiale. Dans cette fonction rest notre valeur courante. La whileboucle fait ce qui suit:

  • Convertir ren ses chiffres composants ( d r).
  • Obtenez le produit de tous ces chiffres. Ceci utilise Seq.reducequi prend une fonction avec la valeur cumulée ( a) et la valeur suivante dans la séquence ( x) et dans ce cas retourne le produit. La valeur initiale est le premier élément de la séquence.
  • Convertissez cette valeur de produit en chiffres de ses composants ( d).
  • Additionnez les chiffres d'avant et affectez-le à r.
Ciaran_McCarthy
la source
1

Befunge, 136 octets

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

Vous pouvez l' essayer ici .

Bien que tous les interprètes n'aient pas une taille de cellule suffisamment grande, cela fonctionne avec de petits nombres pour à peu près n'importe qui. Pour un plus grand nombre d'entre nvous, vous pourriez avoir besoin d'un interprète comme BefunExec .

Gegell
la source
1

Gol> <> , 35 33 octets

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

Essayez-le en ligne!

-2 octets par Jo King.

Utilisation extensive des fonctions et boucles infinies implicites.

Exemple de programme complet et son fonctionnement

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
la source
33 octets
Jo King
1

Japt, 16 14 13 octets

_ì ×ìx}gN®õ x

Essayez-le


Explication

                  :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
Hirsute
la source
Bien, j'ai essayé de résoudre celui-ci moi-même mais je n'ai pas trouvé de bonne solution, donc c'est intéressant de voir la vôtre.
Nit
Merci, @Nit. Il doit y avoir un moyen plus court, cependant.
Shaggy
@Nit, j'ai compris! Toujours convaincu qu'il doit cependant y avoir un chemin plus court.
Shaggy
0

PHP 7, 89 octets

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

Exécuter en tant que pipe avec -rou l' essayer en ligne .

  • PHP prend toujours l'entrée sous forme de chaîne, donc je dois utiliser +pour convertir en int pour ~travailler comme souhaité.
  • Le pré-incrémentation ne fonctionnerait pas: peu importe où je l'ai mis, cela affecterait les deux opérandes.
  • Mais: Peu importe si le chiffre unique a lieu avant ou après l'itération (des itérations supplémentaires ne changeraient rien); donc je peux utiliser à la for()place de do ... while().
  • PHP 7 ou version ultérieure est requis pour l'attribution en ligne du nom de la fonction.
    PHP plus ancien nécessite un octet de plus: for($s=str_split,$a=...;$a>9;)$a=array_sum($s(...));
    (Ne pas attribuer str_splità une variable du tout gaspillerait un autre octet.)
Titus
la source
0

Perl 6 , 49 octets

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

Essayez-le en ligne!

Sean
la source
Vous pouvez utiliser à la [*](.comb).combplace de([*] .comb).comb
Brad Gilbert b2gills
0

PowerShell Core , 91 101 93 octets

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

Essayez-le en ligne!

Ungolfed un peu ...

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

Les premières étapes ont été de diviser les nombres entiers en chiffres - cela a été fait en divisant le nombre entier en un tableau de caractères de chaînes . Ensuite, insérez l'opérande, puis évaluez la chaîne en tant que commande. Ensuite, il s'agit de faire le cycle d'ajout multiple jusqu'à ce que l'entrée soit à un chiffre.

iexest un alias pour Invoke-Commandlequel évalue une chaîne passée dans la première position param.

Edit: comme demandé par @AdmBorkBork , j'ai ajouté un en-tête de fonction au nombre d'octets. De plus, j'ai fait un peu de calcul et j'ai réalisé que la limite supérieure du nombre d'itérations est < log log 10^6 < log 6 < 2, ce qui a permis d'économiser six autres octets.

Edit x2: @AdmBorkBork a trouvé un moyen plus concis de convertir l'entier en une expression mathématique, puis a suggéré de le canaliser iex. Cela a permis d'économiser 8 octets. Merci!

Jeff Freeman
la source
Ravi de voir un autre PowerSheller autour! Cependant, je pense que vous devez inclure la définition de la fonction Function F($a){ }dans votre nombre d'octets. Cependant, je pense que vous devriez pouvoir en sauvegarder certains en utilisant [char[]]au lieu de -split''-ne''.
AdmBorkBork
[char[]]1234=Ӓ, qui n'est pas valide; Je pourrais peut-être le faire fonctionner, mais ce n'est peut-être pas évident en ce moment. Merci pour la suggestion!
Jeff Freeman
Désolé, je n'ai pas été clair - [char[]]"$o"et |iexplutôt que iex( ).
AdmBorkBork
Cette astuce a rasé 8% de mon code. Impressionnant. Merci!
Jeff Freeman
0

Rubis , 57 octets

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

Essayez-le en ligne!

Kirill L.
la source
0

Java 8, 129 octets

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

Essayez-le en ligne.

Explication:

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
la source
0

Julia 0,6 , 56 octets

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

Essayez-le en ligne!

Assez simple: calculez la (n+1)n÷2somme de 1..n, vérifiez s'il s'agit d'un nombre à un seul chiffre ( >9), si ce n'est pas le cas, essayez à nouveau avec k réglé sur la somme des chiffres du produit des chiffres de k, sinon retournez k.

Sundar - Rétablir Monica
la source