28
\$\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
asked May 4, 2018 at 12:52
\$\endgroup\$
9
  • 5
    \$\begingroup\$ +1 for a sequence challenge that's not in the OEIS \$\endgroup\$ Commented May 4, 2018 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\$ Commented May 4, 2018 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\$ Commented May 4, 2018 at 14:52
  • 3
    \$\begingroup\$ Numbers will get very large quickly no it doesn't \$\endgroup\$ Commented May 5, 2018 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\$ Commented May 5, 2018 at 1:51

26 Answers 26

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!

answered May 4, 2018 at 13:33
\$\endgroup\$
6
  • \$\begingroup\$ I just switched to a for loop, but I'll have to remember that trick for the future. \$\endgroup\$ Commented May 4, 2018 at 14:02
  • \$\begingroup\$ Where´s the repeat until you reach a single digit? \$\endgroup\$ Commented May 4, 2018 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\$ Commented May 4, 2018 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\$ Commented May 4, 2018 at 15:14
  • \$\begingroup\$ You can reduce \$\endgroup\$ Commented May 5, 2018 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
answered May 4, 2018 at 13:59
\$\endgroup\$
2
  • \$\begingroup\$ Almost ASCII-only! :D \$\endgroup\$ Commented May 4, 2018 at 14:26
  • \$\begingroup\$ @AdmBorkBork: Yeah, not terribly common :P \$\endgroup\$ Commented May 4, 2018 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).

answered May 4, 2018 at 13:06
\$\endgroup\$
3
  • 1
    \$\begingroup\$ This is the most "natural-looking" Jelly answer I've seen yet. There are only 2 non-ASCII characters \$\endgroup\$ Commented May 5, 2018 at 18:57
  • \$\begingroup\$ @Soaku codegolf.stackexchange.com/questions/69424/… \$\endgroup\$ Commented May 5, 2018 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\$ Commented May 5, 2018 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.

answered May 4, 2018 at 13:29
\$\endgroup\$
0
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!

answered May 4, 2018 at 13:18
\$\endgroup\$
2
  • \$\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\$ Commented May 4, 2018 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\$ Commented May 4, 2018 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!

answered May 4, 2018 at 14:42
\$\endgroup\$
0
2
\$\begingroup\$

Stax, (削除) 14 (削除ここまで) (削除) 13 (削除ここまで) 10 bytes

ñu┌↕a√äJ2┐

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

answered May 4, 2018 at 13:34
\$\endgroup\$
0
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.

answered May 4, 2018 at 14:49
\$\endgroup\$
2
  • \$\begingroup\$ Ah, I see. Scientific notation output. Good catch! \$\endgroup\$ Commented May 4, 2018 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\$ Commented May 4, 2018 at 21:26
2
\$\begingroup\$

APL (Dyalog Unicode), 16 bytes

-4 thanks to @user

f←{⍎ ×ばつ/⍎ ̈⍕+/⍵}⍣≡⍳

Try it online!

answered Dec 23, 2020 at 20:30
\$\endgroup\$
1
  • \$\begingroup\$ Try putting the sum inside. Not sure if it's safe, but it should probably work. \$\endgroup\$ Commented Dec 23, 2020 at 20:39
1
\$\begingroup\$

Husk, 7 bytes

ωöΣdΠdΣ

Try it online!

answered May 4, 2018 at 13:31
\$\endgroup\$
1
\$\begingroup\$

Pyth, 11 bytes

usj*FjGTTsS

Try it here!

usj*FjGTTsS – Full program. N = The input.
 S – Range. Yield [1, N] ⋂ Z.
 s – Sum.
u – While no two consecutive iterations yield the same result, do (var: G):
 *FjGT – Digital product.
 sj T – Digital sum.
answered May 4, 2018 at 14:22
\$\endgroup\$
1
\$\begingroup\$

Charcoal, 18 bytes

≔Σ...·1NθW›θ9≔ΣΠθθIθ

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

≔Σ...·1Nθ

Sum the integers up to the input.

 W›θ9≔ΣΠθθ

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

Cast the result to string and implicitly print it.

answered May 4, 2018 at 19:18
\$\endgroup\$
0
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] ⋂ Z 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.

answered May 4, 2018 at 14:26
\$\endgroup\$
3
  • \$\begingroup\$ ┅⟨ΣΠ⟩° saves a byte. \$\endgroup\$ Commented May 4, 2018 at 20:00
  • \$\begingroup\$ This doesn’t work for values were the digital sum is 0, like 4 \$\endgroup\$ Commented May 4, 2018 at 20:59
  • \$\begingroup\$ @JoKing Fixed, thanks for spotting that. Unfortunately, in Gaia, taking the digits of 0 results in [] for some reason :( \$\endgroup\$ Commented May 4, 2018 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.
answered May 5, 2018 at 15:03
\$\endgroup\$
1
\$\begingroup\$

Ruby, 57 bytes

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

Try it online!

answered May 4, 2018 at 20:17
\$\endgroup\$
1
\$\begingroup\$

Befunge, 136 bytes

101p&::*+2/>:82+%01g*01p82+/:#v_01ドルgv
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.

answered May 13, 2018 at 23:43
\$\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
answered May 14, 2018 at 0:53
\$\endgroup\$
1
  • \$\begingroup\$ 33 bytes \$\endgroup\$ Commented May 14, 2018 at 2:06
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
answered May 4, 2018 at 15:26
\$\endgroup\$
3
  • \$\begingroup\$ Neat, I tried to solve this one myself but didn't find a good solution so it's interesting to see yours. \$\endgroup\$ Commented May 4, 2018 at 17:38
  • \$\begingroup\$ Thanks, @Nit. There's gotta be a shorter way, though. \$\endgroup\$ Commented May 4, 2018 at 18:16
  • \$\begingroup\$ @Nit, got it! Still convinced there has to be a shorter way, though. \$\endgroup\$ Commented May 4, 2018 at 22:55
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.)
answered May 4, 2018 at 15:28
\$\endgroup\$
0
\$\begingroup\$

Perl 6, 49 bytes

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

Try it online!

answered May 4, 2018 at 18:17
\$\endgroup\$
1
  • \$\begingroup\$ You can use [*](.comb).comb instead of ([*] .comb).comb \$\endgroup\$ Commented May 4, 2018 at 18:23
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 (削除) strings (削除ここまで)characters. 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!

answered May 4, 2018 at 18:05
\$\endgroup\$
4
  • \$\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\$ Commented May 4, 2018 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\$ Commented May 4, 2018 at 18:37
  • \$\begingroup\$ Sorry I wasn't clear -- [char[]]"$o" and a |iex rather than iex( ). \$\endgroup\$ Commented May 4, 2018 at 18:56
  • \$\begingroup\$ This tip shaved 8% of my code off. Awesome. Thanks! \$\endgroup\$ Commented May 4, 2018 at 19:20
0
\$\begingroup\$

Perl 5 -p, 61 bytes

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

Try it online!

answered May 4, 2018 at 21:05
\$\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
answered May 7, 2018 at 7:06
\$\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.

answered Jul 2, 2018 at 15:10
\$\endgroup\$
0
\$\begingroup\$

J-uby, 38 bytes

This is me resisting forking J-uby to add a bunch of single-character aliases for useful functions.

:+|:sum|:!~&((d=:digits)|:/&:*|d|:sum)

Attempt This Online!

Explanation

:+ | :sum | :!~ & ((d = :digits) | :/ & :* | d | :sum)
:+ | :sum | # Range 1..n, then sum, then
 :!~ & ( ) # Until a fixed point is reached...
 ((d = :digits) | # Get digits (while saving the function to d for later), then
 :/ & :* | # Reduce with product, then
 d | :sum # Get digits, then sum
answered Jul 12, 2023 at 19:39
\$\endgroup\$
0
\$\begingroup\$

Tcl, 113 bytes

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

Try it online!

answered May 4, 2018 at 16:15
\$\endgroup\$
2
  • \$\begingroup\$ Failed outgolf, 119 \$\endgroup\$ Commented May 7, 2018 at 12:06
  • \$\begingroup\$ Failed outgolf: 121: tio.run/… \$\endgroup\$ Commented Apr 27 at 10:06

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.