27
\$\begingroup\$

(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
\$\endgroup\$
  • 3
    \$\begingroup\$ +1 for a sequence challenge that's not in the OEIS \$\endgroup\$ – JAD May 4 '18 at 14:20
  • 2
    \$\begingroup\$ 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? \$\endgroup\$ – Dennis May 4 '18 at 14:45
  • 2
    \$\begingroup\$ @Dennis The algorithm should work for any value of n. The solution posted only has to work up to n = 100000. \$\endgroup\$ – AdmBorkBork May 4 '18 at 14:52
  • 3
    \$\begingroup\$ Numbers will get very large quickly no it doesn't \$\endgroup\$ – l4m2 May 5 '18 at 0:01
  • 3
    \$\begingroup\$ @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. \$\endgroup\$ – Dennis May 5 '18 at 1:51

24 Answers 24

10
\$\begingroup\$

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!

\$\endgroup\$
  • \$\begingroup\$ I just switched to a for loop, but I'll have to remember that trick for the future. \$\endgroup\$ – Dennis May 4 '18 at 14:02
  • \$\begingroup\$ Where´s the repeat until you reach a single digit? \$\endgroup\$ – Titus May 4 '18 at 14:28
  • 2
    \$\begingroup\$ @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. \$\endgroup\$ – Dennis May 4 '18 at 14:30
  • \$\begingroup\$ 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. \$\endgroup\$ – Titus May 4 '18 at 15:14
  • \$\begingroup\$ You can reduce \$\endgroup\$ – xnor May 5 '18 at 18:21
8
\$\begingroup\$

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
\$\endgroup\$
  • \$\begingroup\$ Almost ASCII-only! :D \$\endgroup\$ – AdmBorkBork May 4 '18 at 14:26
  • \$\begingroup\$ @AdmBorkBork: Yeah, not terribly common :P \$\endgroup\$ – Emigna May 4 '18 at 15:33
4
\$\begingroup\$

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

\$\endgroup\$
  • \$\begingroup\$ This is the most "natural-looking" Jelly answer I've seen yet. There are only 2 non-ASCII characters \$\endgroup\$ – RedClover May 5 '18 at 18:57
  • \$\begingroup\$ @Soaku codegolf.stackexchange.com/questions/69424/… \$\endgroup\$ – Esolanging Fruit May 5 '18 at 19:19
  • \$\begingroup\$ 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. ;) \$\endgroup\$ – Erik the Outgolfer May 5 '18 at 19:21
4
\$\begingroup\$

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.

\$\endgroup\$
3
\$\begingroup\$

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!

\$\endgroup\$
  • \$\begingroup\$ 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 .... \$\endgroup\$ – Ross Presser May 4 '18 at 17:38
  • 1
    \$\begingroup\$ @RossPresser As a rough estimate, I'd say it rather works up to Number.MAX_SAFE_INTEGER ** 0.5 ~= 94906265. \$\endgroup\$ – Arnauld May 4 '18 at 17:45
3
\$\begingroup\$

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!

\$\endgroup\$
2
\$\begingroup\$

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

\$\endgroup\$
2
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ Ah, I see. Scientific notation output. Good catch! \$\endgroup\$ – AdmBorkBork May 4 '18 at 15:14
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ – Giuseppe May 4 '18 at 21:26
1
\$\begingroup\$

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.
\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ ┅⟨ΣΠ⟩° saves a byte. \$\endgroup\$ – Dennis May 4 '18 at 20:00
  • \$\begingroup\$ This doesn’t work for values were the digital sum is 0, like 4 \$\endgroup\$ – Jo King May 4 '18 at 20:59
  • \$\begingroup\$ @JoKing Fixed, thanks for spotting that. Unfortunately, in Gaia, taking the digits of 0 results in [] for some reason :( \$\endgroup\$ – Mr. Xcoder May 4 '18 at 21:09
1
\$\begingroup\$

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.
\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

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
\$\endgroup\$
1
\$\begingroup\$

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
\$\endgroup\$
  • \$\begingroup\$ Neat, I tried to solve this one myself but didn't find a good solution so it's interesting to see yours. \$\endgroup\$ – Nit May 4 '18 at 17:38
  • \$\begingroup\$ Thanks, @Nit. There's gotta be a shorter way, though. \$\endgroup\$ – Shaggy May 4 '18 at 18:16
  • \$\begingroup\$ @Nit, got it! Still convinced there has to be a shorter way, though. \$\endgroup\$ – Shaggy May 4 '18 at 22:55
0
\$\begingroup\$

Husk, 7 bytes

ωöΣdΠdΣ

Try it online!

\$\endgroup\$
0
\$\begingroup\$

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.)
\$\endgroup\$
0
\$\begingroup\$

Perl 6, 49 bytes

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

Try it online!

\$\endgroup\$
  • \$\begingroup\$ You can use [*](.comb).comb instead of ([*] .comb).comb \$\endgroup\$ – Brad Gilbert b2gills May 4 '18 at 18:23
0
\$\begingroup\$

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!

\$\endgroup\$
0
\$\begingroup\$

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!

\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – AdmBorkBork May 4 '18 at 18:12
  • \$\begingroup\$ [char[]]1234=Ӓ, which is invalid; I might be able to make it work, but it might not obvious just now. Thanks for the suggestion! \$\endgroup\$ – Jeff Freeman May 4 '18 at 18:37
  • \$\begingroup\$ Sorry I wasn't clear -- [char[]]"$o" and a |iex rather than iex( ). \$\endgroup\$ – AdmBorkBork May 4 '18 at 18:56
  • \$\begingroup\$ This tip shaved 8% of my code off. Awesome. Thanks! \$\endgroup\$ – Jeff Freeman May 4 '18 at 19:20
0
\$\begingroup\$

Perl 5 -p, 61 bytes

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

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Ruby, 57 bytes

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

Try it online!

\$\endgroup\$
0
\$\begingroup\$

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
\$\endgroup\$
0
\$\begingroup\$

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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.