The Add-Multiply-Add Sequence

27

1

(Related)

Given an integer n > 1,
1) Construct the range of numbers n, n-1, n-2, ... 3, 2, 1 and calculate the sum
2) Take the individual digits of that number and calculate the product
3) Take the individual digits of that number and calculate the sum
4) Repeat steps 2 and 3 until you reach a single digit. That digit is the result.

The first twenty terms of the sequence are below:

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

Note: This sequence is NOT in OEIS.

I/O and Rules

  • Numbers will get very large quickly, so the solution must be able to handle input numbers up to 100,000 without failure (it's fine if your code can handle past that).
  • The input and output can be given by any convenient method.
  • Either a full program or a function are acceptable. If a function, you can return the output rather than printing it.
  • Standard loopholes are forbidden.
  • This is so all usual golfing rules apply, and the shortest code (in bytes) wins.

Examples

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

AdmBorkBork

Posted 2018-05-04T12:52:04.347

Reputation: 41 581

4+1 for a sequence challenge that's not in the OEIS – JAD – 2018-05-04T14:20:43.443

2

Whenever n ≤ 100000, only two iterations of steps 2 and 3 are sufficient to get the result. Can we take advantage of that or should the algorithm we choose work for larger values of n?

– Dennis – 2018-05-04T14:45:56.027

2@Dennis The algorithm should work for any value of n. The solution posted only has to work up to n = 100000. – AdmBorkBork – 2018-05-04T14:52:18.783

@AdmBorkBork That seems like a subjective winning criteria. If you say that the algorithm only has to work up to N=100k and will only be tested up to 100k, how can you say whether or not it's "correct" for larger values? – Harry – 2018-05-04T21:28:43.173

1@AdmBorkBork Maybe just remove 100k altogether, submissions don't have to work for all possible inputs practically, only theoretically. – Erik the Outgolfer – 2018-05-04T21:41:03.753

3Numbers will get very large quickly no it doesn't – l4m2 – 2018-05-05T00:01:41.907

3@l4m2 Not the output. But 100000 + 99999 + ... + 1 = 5000050000 is a 33-bit number, which your language of choice may or may not have trouble representing. – Dennis – 2018-05-05T01:51:21.343

Should we add this to OEIS? :) – Winny – 2018-05-05T03:40:06.750

@Dennis "quickly" usually mean exponential increasing don't it? – l4m2 – 2018-05-05T08:39:16.877

Answers

10

Python 2, 77 72 71 62 60 bytes

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

Thanks to @xnor for golfing off 2 bytes!

Try it online!

Dennis

Posted 2018-05-04T12:52:04.347

Reputation: 196 637

I just switched to a for loop, but I'll have to remember that trick for the future. – Dennis – 2018-05-04T14:02:25.750

Where´s the repeat until you reach a single digit? – Titus – 2018-05-04T14:28:19.643

2@Titus I simply perform n iterations of steps 2 and 3, which is always enough. In fact, since n ≤ 100000, three iterations would be sufficient. – Dennis – 2018-05-04T14:30:19.753

Now that you mention it: Actually, the smallest input that would require three iterations is 236172; and that´s the only one below 1 million. – Titus – 2018-05-04T15:14:04.940

You can reduce

– xnor – 2018-05-05T18:21:17.147

@xnor Thanks! I think this is the first time I've reduced in a Python answer. – Dennis – 2018-05-05T18:31:02.653

8

05AB1E, 7 bytes

LOΔSPSO

Try it 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

Posted 2018-05-04T12:52:04.347

Reputation: 50 798

Almost ASCII-only! :D – AdmBorkBork – 2018-05-04T14:26:52.563

@AdmBorkBork: Yeah, not terribly common :P – Emigna – 2018-05-04T15:33:01.553

4

Jelly, 8 bytes

RSDPDƲÐL

Try it online!

Full program (it returns a singleton array containing the result, but the brackets aren't visible in STDOUT).

Erik the Outgolfer

Posted 2018-05-04T12:52:04.347

Reputation: 38 134

This is the most "natural-looking" Jelly answer I've seen yet. There are only 2 non-ASCII characters – RedClover – 2018-05-05T18:57:11.670

Uh, can we please not have the discussion over here, thanks. :P TNB could be an alternative place to discuss this, if no noise is made. ;) – Erik the Outgolfer – 2018-05-05T19:21:05.683

4

MATL, 15 13 bytes

In tribute to the Language of the month:

:`sV!UpV!Utnq

Try it online!

I don't think there's a simpler way to get the digits of a number than to convert the number to a string V, then transposing it !, and converting this vertical vector back to a numeric one U.

Saved 2 bytes thanks to the Creator1 himself! I forgot the implicit end, meaning I could remove ], and instead of comparing the number of elements with 1, I could simply decrement that value and use it as a boolean directly.

So, the explanation goes like this:

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

Stewie Griffin

Posted 2018-05-04T12:52:04.347

Reputation: 43 471

3

JavaScript (ES6), 60 bytes

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

Try it online!

Commented

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

Alternate version, 59 bytes (non-competing)

A non-recursive version that only works for n < 236172. (It covers the requested range but does not qualify as a valid generic algorithm.)

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

Try it online!

Arnauld

Posted 2018-05-04T12:52:04.347

Reputation: 111 334

your main version breaks when N >= 77534568790. It works when N=7753456879; not sure exactly where the breakpoint is. Of course, this doesn't matter because the requirment is only to handle up to N=100,000, so I'm not sure why I wrote this .... – Ross Presser – 2018-05-04T17:38:50.827

1@RossPresser As a rough estimate, I'd say it rather works up to Number.MAX_SAFE_INTEGER ** 0.5 ~= 94906265. – Arnauld – 2018-05-04T17:45:05.900

3

Haskell, 72 71 63 bytes

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

Thanks to @BMO for a byte and @nimi for 8 bytes!

Try it online!

Angs

Posted 2018-05-04T12:52:04.347

Reputation: 4 825

2

Stax, 14 13 10 bytes

ñu┌↕a√äJ²┐

Run and debug it

Was pretty fun to make. I wonder if there is a more concise way to do the comparison at the end.

Explanation

|+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 thanks to ovs

-3 bytes thanks to Scrooble

Multi

Posted 2018-05-04T12:52:04.347

Reputation: 425

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

Try it online!

@Giuseppe found 21 42 bytes with various R things I'm not used to yet, along with a way to get the digits of a number without coercing to string and back, and with fewer 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) is was required for the case of 9854 for the old function, because the first product stage ends up as 80000, which R prints as 8e+05.

ngm

Posted 2018-05-04T12:52:04.347

Reputation: 3 974

Ah, I see. Scientific notation output. Good catch! – AdmBorkBork – 2018-05-04T15:14:47.057

1

Finally got around the scipen: Try it online! note the max(0,log10(x)) is because if x=0, then log10(0)=-Inf which causes an error.

– Giuseppe – 2018-05-04T21:26:03.193

1

Pyth, 11 bytes

usj*FjGTTsS

Try it here!

usj*FjGTTsS – Full program. N = The input.
          S – Range. Yield [1, N] ⋂ ℤ.
         s  – Sum.
u           – While no two consecutive iterations yield the same result, do (var: G):
   *FjGT    – Digital product.
 sj     T   – Digital sum.

Mr. Xcoder

Posted 2018-05-04T12:52:04.347

Reputation: 39 774

1

Gaia, 8 bytes

┅⟨Σ₸∨Π⟩°

Try it online!

The old explanation (before fixing a bug that is Gaia’s fault IMO :P):

┅⟨ΣΠ⟩° – Full program. N = The input.
┅      – Range. Push [1, N] ⋂ ℤ to the stack.
 ⟨  ⟩° – While no two consecutive iterations yield the same result, do:
  Σ    – Sum (or digital sum, when applied to an integer).
   Π   – Digital product.

Saved 1 byte thanks to Dennis.

Mr. Xcoder

Posted 2018-05-04T12:52:04.347

Reputation: 39 774

┅⟨ΣΠ⟩° saves a byte. – Dennis – 2018-05-04T20:00:14.927

This doesn’t work for values were the digital sum is 0, like 4 – Jo King – 2018-05-04T20:59:09.017

@JoKing Fixed, thanks for spotting that. Unfortunately, in Gaia, taking the digits of 0 results in [] for some reason :( – Mr. Xcoder – 2018-05-04T21:09:38.510

1

Japt, 16 14 13 bytes

_ì ×ìx}gN®õ x

Try it


Explanation

                  :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

Posted 2018-05-04T12:52:04.347

Reputation: 24 623

Neat, I tried to solve this one myself but didn't find a good solution so it's interesting to see yours. – Nit – 2018-05-04T17:38:44.497

Thanks, @Nit. There's gotta be a shorter way, though. – Shaggy – 2018-05-04T18:16:38.677

@Nit, got it! Still convinced there has to be a shorter way, though. – Shaggy – 2018-05-04T22:55:00.167

1

Charcoal, 18 bytes

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

Try it online! Link is to verbose version of code. Explanation:

≔Σ…·¹Nθ

Sum the integers up to the input.

 W›θ⁹≔ΣΠθθ

While the result is greater than 9, take the sum of digits of the product of digits.

Iθ

Cast the result to string and implicitly print it.

Neil

Posted 2018-05-04T12:52:04.347

Reputation: 95 035

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

Try it online!

The only caveat to the function is that the input value must be of type uint64.

Ungolfed it's a little like this:

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

The function d n converts the number n into its component digits. It first converts to a string, then gets each character in the string. Each character must then be converted back into a string, otherwise the characters will be converted to their ASCII values instead of their "real" values.

The c n function is the main function, with n as the initial value. In this function r is our running value. The while loop does the following:

  • Convert r into its component digits (d r).
  • Get the product of all those digits. This uses Seq.reduce which takes a function with the accumulated value (a) and the next value in the sequence (x) and in this case returns the product. The initial value is the first element in the sequence.
  • Convert this product value into its component digits (d).
  • Sum the digits from before, and assign this to r.

Ciaran_McCarthy

Posted 2018-05-04T12:52:04.347

Reputation: 689

1

Befunge, 136 bytes

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

You can try it here.

While not all interpreters have a large enough cell size, it works with small numbers for pretty much anyone out there. For a larger number of n you might need a interpreter like BefunExec.

Gegell

Posted 2018-05-04T12:52:04.347

Reputation: 81

1

Gol><>, 35 33 bytes

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

Try it online!

-2 bytes by Jo King.

Extensive use of functions and implicit infinite loops.

Example full program & How it works

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

Posted 2018-05-04T12:52:04.347

Reputation: 16 616

33 bytes – Jo King – 2018-05-14T02:06:32.807

0

Husk, 7 bytes

ωöΣdΠdΣ

Try it online!

Erik the Outgolfer

Posted 2018-05-04T12:52:04.347

Reputation: 38 134

0

PHP 7, 89 bytes

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

Run as pipe with -r or try it online.

  • PHP always takes input as string, so I have to use + to cast to int for ~ to work as wanted.
  • Pre-increment would not work: no matter where I put it, it would effect both operands.
  • But: It doesn´t matter if the single digit takes place before or after the iteration (additional iterations wouldn´t change a thing); so I can use for() instead of do ... while().
  • PHP 7 or later is required for the inline assignment of the function name.
    Older PHP requires one more byte: for($s=str_split,$a=...;$a>9;)$a=array_sum($s(...));
    (Not assigning str_split to a variable at all would waste another byte.)

Titus

Posted 2018-05-04T12:52:04.347

Reputation: 13 814

0

Tcl, 118 bytes

proc S n {set r [expr $n*($n+1)/2]
while \$r>9 {set r [expr [join [split [expr [join [split $r ""] *]] ""] +]]}
set r}

Try it online!

sergiol

Posted 2018-05-04T12:52:04.347

Reputation: 3 055

Failed outgolf, 119 – sergiol – 2018-05-07T12:06:21.267

0

PowerShell Core, 91 101 93 bytes

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

Try it online!

Ungolfed a little...

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

First steps were to split the integers into digits -- did this by splitting the integer into an array of stringscharacters. Afterwards, insert the operand, and then evaluate the string as a command. Then, it's a matter of doing the multiple-add cycle until the input is one digit.

iex is an alias for Invoke-Command which evaluates a string passed into the first param position.

Edit: As requested by @AdmBorkBork, I have added a function header to the byte count. Also, I did a little math and realized that an upper bound on the number of iterations is < log log 10^6 < log 6 < 2, so that saved another six bytes.

Edit x2: @AdmBorkBork found a more terse way of converting the integer into a math expression, and then suggested piping it into iex. This saved 8 bytes. Thank you!

Jeff Freeman

Posted 2018-05-04T12:52:04.347

Reputation: 221

Nice to see another PowerSheller around! However, I think you need to include the function definition Function F($a){ } in your byte count. However, you should be able to save some using [char[]] instead of -split''-ne'', I think. – AdmBorkBork – 2018-05-04T18:12:15.903

[char[]]1234=Ӓ, which is invalid; I might be able to make it work, but it might not obvious just now. Thanks for the suggestion! – Jeff Freeman – 2018-05-04T18:37:02.983

Sorry I wasn't clear -- [char[]]"$o" and a |iex rather than iex( ). – AdmBorkBork – 2018-05-04T18:56:12.667

This tip shaved 8% of my code off. Awesome. Thanks! – Jeff Freeman – 2018-05-04T19:20:13.150

0

Perl 6, 49 bytes

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

Try it online!

Sean

Posted 2018-05-04T12:52:04.347

Reputation: 4 136

You can use [*](.comb).comb instead of ([*] .comb).comb – Brad Gilbert b2gills – 2018-05-04T18:23:51.303

0

Ruby, 57 bytes

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

Try it online!

Kirill L.

Posted 2018-05-04T12:52:04.347

Reputation: 6 693

0

Perl 5 -p, 61 bytes

$_*=$_/2+.5;$_=eval((eval s/./$&*/gr.1)=~s/./+$&/gr)while$_>9

Try it online!

Xcali

Posted 2018-05-04T12:52:04.347

Reputation: 7 671

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

Try it online.

Explanation:

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

Posted 2018-05-04T12:52:04.347

Reputation: 67 575

0

Julia 0.6, 56 bytes

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

Try it online!

Pretty straightforward: calculate (n+1)n÷2 for sum from 1..n, check if it's a single digit number (>9), if it's not, try again with k set to the sum of the digits of the product of the digits of k, else return k.

sundar - Reinstate Monica

Posted 2018-05-04T12:52:04.347

Reputation: 5 296