Die Add-Multiply-Add-Sequenz

27

( Verwandte )

Gegeben eine ganze Zahl n > 1,
1) Konstruieren Sie den Bereich von Zahlen n, n-1, n-2, ... 3, 2, 1und berechnen Sie die Summe
2) Nehmen Sie die einzelnen Ziffern dieser Zahl und berechnen das Produkt
3) Nehmen Sie die einzelnen Ziffern dieser Zahl und berechnen die Summe
4) Wiederholen Sie die Schritte 2 und 3 , bis Sie eine einstellige Zahl erreichen. Diese Ziffer ist das Ergebnis.

Die ersten zwanzig Terme der Sequenz sind unten:

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

Hinweis: Diese Sequenz ist NICHT in OEIS.

I / O und Regeln

  • Zahlen werden schnell sehr groß, daher muss die Lösung in der Lage sein, Eingabezahlen von bis zu 100.000 ohne Fehler zu verarbeiten (es ist in Ordnung, wenn Ihr Code darüber hinausgeht).
  • Die Eingabe und Ausgabe kann durch jede bequeme Methode erfolgen .
  • Es ist entweder ein vollständiges Programm oder eine Funktion zulässig. Bei einer Funktion können Sie die Ausgabe zurückgeben, anstatt sie zu drucken.
  • Standardlücken sind verboten.
  • Dies ist daher gelten alle üblichen Golfregeln, und der kürzeste Code (in Byte) gewinnt.

Beispiele

n     output
1234   9
3005   3
5007   5
9854   8
75849  8
100000 0
AdmBorkBork
quelle
3
+1 für eine Sequenzherausforderung, die nicht in der OEIS
JAD
2
Immer wenn n ≤ 100000 ist , sind nur zwei Iterationen der Schritte 2 und 3 ausreichend, um das Ergebnis zu erhalten. Können wir das ausnutzen oder sollte der gewählte Algorithmus für größere Werte von n funktionieren ?
Dennis
2
@Dennis Der Algorithmus sollte für jeden Wert von funktionieren n. Die eingestellte Lösung muss nur noch funktionieren n = 100000.
AdmBorkBork
3
Numbers will get very large quicklynein, tut es nicht
l4m2
3
@ l4m2 Nicht die Ausgabe. Aber 100000 + 99999 + ... + 1 = 5000050000 ist eine 33-Bit - Zahl, die die Sprache Ihrer Wahl oder keine Probleme haben können darstellen.
Dennis

Antworten:

10

Python 2 , 77 72 71 62 60 Bytes

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

Vielen Dank an @xnor für das Golfen mit 2 Bytes!

Probieren Sie es online!

Dennis
quelle
Ich habe gerade zu einer for-Schleife gewechselt, aber ich muss mich für die Zukunft an diesen Trick erinnern.
Dennis
Wo ist der repeat until you reach a single digit?
Titus
2
@Titus Ich führe einfach n Iterationen der Schritte 2 und 3 durch, was immer ausreicht. Tatsächlich wären drei Iterationen ausreichend , da n ≤ 100000 ist.
Dennis
Nun, da Sie es erwähnen: Tatsächlich ist die kleinste Eingabe, die drei Iterationen erfordern würde, Folgendes 236172: und das ist die einzige unter 1 Million.
Titus
Sie können
xnor
8

05AB1E , 7 Bytes

LOΔSPSO

Probieren Sie es 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
Emigna
quelle
Fast nur ASCII! : D
AdmBorkBork
@AdmBorkBork: Ja, nicht so üblich: P
Emigna
4

Gelee , 8 Bytes

RSDPDƲÐL

Probieren Sie es online!

Vollständiges Programm (es gibt ein Singleton-Array mit dem Ergebnis zurück, die Klammern sind jedoch in STDOUT nicht sichtbar).

Erik der Outgolfer
quelle
Dies ist die "natürlich aussehende" Gelee-Antwort, die ich bisher gesehen habe. Es gibt nur 2 Nicht-ASCII-Zeichen
RedClover
Äh, können wir bitte nicht die Diskussion hier haben, danke. : P TNB könnte ein alternativer Ort sein, um dies zu diskutieren, wenn kein Lärm gemacht wird. ;)
Erik der Outgolfer
4

MATL , 15 13 Bytes

Zu Ehren der Sprache des Monats :

:`sV!UpV!Utnq

Probieren Sie es online!

Ich glaube nicht, dass es eine einfachere Möglichkeit gibt, die Ziffern einer Zahl zu ermitteln, als die Zahl in eine Zeichenfolge umzuwandeln V, sie dann zu transponieren !und diesen vertikalen Vektor wieder in einen numerischen Vektor umzuwandeln U.

2 Bytes gespart dank dem Creator 1 selbst! Ich habe das implizite Ende vergessen, das heißt, ich konnte es entfernen ], und anstatt die Anzahl der Elemente mit zu vergleichen 1, konnte ich diesen Wert einfach dekrementieren und ihn direkt als Booleschen Wert verwenden.

Die Erklärung lautet also wie folgt:

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

Stewie Griffin
quelle
3

JavaScript (ES6), 60 Byte

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

Probieren Sie es online!

Kommentiert

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

Alternative Version, 59 Bytes (nicht konkurrierend)

Eine nicht rekursive Version, die nur für n <236172 funktioniert . (Es deckt den angeforderten Bereich ab, ist jedoch kein gültiger generischer Algorithmus.)

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

Probieren Sie es online!

Arnauld
quelle
Ihre Hauptversion bricht ab, wenn N> = 77534568790. Es funktioniert, wenn N = 7753456879; Ich weiß nicht genau, wo sich der Haltepunkt befindet. Natürlich spielt dies keine Rolle, da die Anforderung nur bis zu N = 100.000 zu bewältigen ist. Ich bin mir nicht sicher, warum ich das geschrieben habe ....
Ross Presser,
1
@ RossPresser Als grobe Schätzung würde ich sagen, es funktioniert eher bis zu 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]

Danke an @BMO für ein Byte und @nimi für 8 Bytes!

Probieren Sie es online!

Angs
quelle
2

Stax , 14 13 10 Bytes

ñu┌↕a√äJ²┐

Führen Sie es aus und debuggen Sie es

War ziemlich lustig zu machen. Ich frage mich, ob es eine präzisere Möglichkeit gibt, den Vergleich am Ende durchzuführen.

Erläuterung

|+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 dank ovs

-3 Bytes dank Scrooble

Multi
quelle
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

Probieren Sie es online!

@ Giuseppe hat 21 42 Bytes mit verschiedenen R-Dingen gefunden, an die ich noch nicht gewöhnt bin, zusammen mit einer Möglichkeit, die Ziffern einer Zahl zu erhalten, ohne sie auf String und Back zu zwingen, und mit weniger 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) wird wurde für den Fall von 9854 für die alte Funktion erforderlich, weil das erste Produkt der Bühne als 80000 endet, die R druckt als 8e + 05.

ngm
quelle
Ah ich sehe. Ausgabe in wissenschaftlicher Notation. Guter Fang!
AdmBorkBork
1
Endlich umgangen scipen: Online ausprobieren ! beachte das max(0,log10(x))is weil wenn x=0dann log10(0)=-Infwas einen fehler verursacht.
Giuseppe
1

Pyth , 11 Bytes

usj*FjGTTsS

Probieren Sie es hier aus!

usj * FjGTTsS - Volles Programm. N = Die Eingabe.
          S - Bereich. Ausbeute [1, N] ⋂ ⋂.
         s - Summe.
u - Während keine zwei aufeinanderfolgenden Iterationen dasselbe Ergebnis liefern, tun Sie (var: G):
   * FjGT - Digitales Produkt.
 sj T - Digitale Summe.
Mr. Xcoder
quelle
1

Kohle , 18 Bytes

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

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Erläuterung:

≔Σ…·¹Nθ

Summiere die ganzen Zahlen bis zur Eingabe.

 W›θ⁹≔ΣΠθθ

Während das Ergebnis größer als 9 ist, nehmen Sie die Summe der Ziffern des Produkts der Ziffern.

Iθ

Wandeln Sie das Ergebnis in eine Zeichenfolge um und drucken Sie es implizit aus.

Neil
quelle
1

Gaia , 8 Bytes

┅⟨Σ₸∨Π⟩°

Probieren Sie es online!

Die alte Erklärung (vor dem Beheben eines Fehlers, der Gaias Fehler ist IMO: P):

┅⟨ΣΠ⟩ ° - Volles Programm. N = Die Eingabe.
┅ - Reichweite. Schieben Sie [1, N] ⋂ ⋂ zum Stapel.
 ⟨⟩ ° - Während keine zwei aufeinander folgenden Iterationen das gleiche Ergebnis liefern, tun Sie Folgendes:
  Σ - Summe (oder digitale Summe, wenn auf eine ganze Zahl angewendet).
   Π - Digitales Produkt.

Dank Dennis 1 Byte gespeichert .

Mr. Xcoder
quelle
┅⟨ΣΠ⟩°Speichert ein Byte.
Dennis
Dies funktioniert nicht für Werte, bei denen die digitale Summe 0 ist, wie z. B.4
Jo King,
@JoKing Behoben, danke, dass du das entdeckt hast. Leider in Gaia, nehmen die Ziffern der 0Ergebnisse []aus irgendeinem Grund :(
Mr. Xcoder
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

Probieren Sie es online!

Der einzige Nachteil der Funktion ist, dass der Eingabewert vom Typ sein muss uint64.

Ungolfed ist es ein bisschen so:

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

Die Funktion d nwandelt die Zahl nin ihre Bestandteile um. Es wird zuerst in eine Zeichenfolge konvertiert und dann jedes Zeichen in der Zeichenfolge abgerufen. Jedes Zeichen muss dann wieder in eine Zeichenfolge konvertiert werden, andernfalls werden die Zeichen in ihre ASCII-Werte anstelle ihrer "echten" Werte konvertiert.

Die c nFunktion ist die Hauptfunktion mit ndem Anfangswert. In dieser Funktion rliegt unser laufender Wert. Die whileSchleife führt Folgendes aus:

  • Konvertieren Sie rin die entsprechenden Ziffern ( d r).
  • Erhalten Sie das Produkt all dieser Ziffern. Dabei wird verwendet, Seq.reducewas eine Funktion mit dem akkumulierten Wert ( a) und dem nächsten Wert in der Sequenz ( x) übernimmt und in diesem Fall das Produkt zurückgibt. Der Anfangswert ist das erste Element in der Sequenz.
  • Konvertieren Sie diesen Produktwert in die entsprechenden Ziffern ( d).
  • Summieren Sie die Ziffern von zuvor und weisen Sie diese zu r.
Ciaran_McCarthy
quelle
1

Befunge, 136 Bytes

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

Sie können es hier ausprobieren .

Obwohl nicht alle Dolmetscher eine ausreichend große Zelle haben, funktioniert es mit kleinen Zahlen für so ziemlich jeden da draußen. Für eine größere Anzahl nbenötigen Sie möglicherweise einen Dolmetscher wie BefunExec .

Gegell
quelle
1

Gol> <> , 35 33 Bytes

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

Probieren Sie es online!

-2 Bytes von Jo King.

Umfangreiche Nutzung von Funktionen und impliziten Endlosschleifen.

Beispiel volles Programm & wie es funktioniert

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
quelle
33 Bytes
Jo King
1

Japt, 16 14 13 Bytes

_ì ×ìx}gN®õ x

Versuch es


Erläuterung

                  :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
Zottelig
quelle
Ordentlich, ich habe versucht, dieses Problem selbst zu lösen, aber keine gute Lösung gefunden. Es ist also interessant, Ihre zu sehen.
Nit
Danke, @Nit. Es muss aber einen kürzeren Weg geben.
Shaggy
@Nein, verstanden! Immer noch überzeugt, dass es einen kürzeren Weg geben muss.
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;

Laufen Sie als Pipe mit -roder versuchen Sie es online .

  • PHP nimmt Eingaben immer als Zeichenkette, also muss ich sie verwenden +, um nach int umzuwandeln, damit ~sie wie gewünscht funktionieren.
  • Pre-Increment würde nicht funktionieren: Egal wo ich es platziere, es würde beide Operanden beeinflussen.
  • Aber: Es ist egal, ob die einzelne Ziffer vor oder nach der Iteration stattfindet (zusätzliche Iterationen würden nichts ändern); also kann ich for()statt verwenden do ... while().
  • Für die Inline-Vergabe des Funktionsnamens wird PHP 7 oder höher benötigt.
    Für älteres PHP ist ein weiteres Byte erforderlich: for($s=str_split,$a=...;$a>9;)$a=array_sum($s(...));
    (Wenn Sie str_spliteiner Variablen nichts zuweisen , wird ein weiteres Byte verschwendet.)
Titus
quelle
0

Perl 6 , 49 Bytes

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

Probieren Sie es online!

Sean
quelle
Sie können [*](.comb).combanstelle von([*] .comb).comb
Brad Gilbert b2gills
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}

Probieren Sie es online!

Ein wenig ungolfed ...

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

Die ersten Schritte bestanden darin, die Ganzzahlen in Ziffern aufzuteilen. Dazu wurde die Ganzzahl in ein Array von Zeichenfolgen aufgeteilt . Fügen Sie anschließend den Operanden ein und werten Sie den String als Befehl aus. Dann ist es eine Frage des Mehrfachadditionszyklus, bis die Eingabe eine Ziffer ist.

iexist ein Alias, bei Invoke-Commanddem ein String ausgewertet wird, der an die erste Parameterposition übergeben wurde.

Bearbeiten: Wie von @AdmBorkBork angefordert , habe ich der Byteanzahl einen Funktionsheader hinzugefügt. Außerdem habe ich ein wenig nachgerechnet und festgestellt, dass eine Obergrenze für die Anzahl der Iterationen vorliegt < log log 10^6 < log 6 < 2, sodass weitere sechs Bytes eingespart wurden.

Edit x2: @AdmBorkBork hat eine genauere Möglichkeit gefunden, die Ganzzahl in einen mathematischen Ausdruck umzuwandeln, und hat dann vorgeschlagen, sie mit Pipes zu versehen iex. Dies sparte 8 Bytes. Vielen Dank!

Jeff Freeman
quelle
Schön, einen anderen PowerSheller in der Nähe zu sehen! Ich denke jedoch, dass Sie die Funktionsdefinition Function F($a){ }in Ihre Byteanzahl einschließen müssen . Sie sollten jedoch in der Lage sein, einige zu sparen, [char[]]anstatt -split''-ne'', denke ich.
AdmBorkBork
[char[]]1234=Ӓ, was ungültig ist; Vielleicht kann ich es zum Laufen bringen, aber vielleicht ist es gerade nicht offensichtlich. Danke für den Vorschlag!
Jeff Freeman
Tut mir leid, ich war nicht klar - [char[]]"$o"und |iexeher als iex( ).
AdmBorkBork
Dieser Tipp hat 8% meines Codes entfernt. Genial. Vielen Dank!
Jeff Freeman
0

Ruby , 57 Bytes

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

Probieren Sie es online!

Kirill L.
quelle
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;}

Probieren Sie es online aus.

Erläuterung:

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
quelle
0

Julia 0,6 , 56 Bytes

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

Probieren Sie es online!

Ganz einfach: Berechnen Sie die (n+1)n÷2Summe aus 1..n. Prüfen Sie, ob es sich um eine einstellige Zahl handelt ( >9). Wenn dies nicht der Fall ist , versuchen Sie es erneut, indem Sie k auf die Summe der Stellen des Produkts der Stellen von k setzen. Anderenfalls geben Sie k zurück.

Sundar - Setzen Sie Monica wieder ein
quelle