(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 code-golf 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
26 Answers 26
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!
-
\$\begingroup\$ I just switched to a for loop, but I'll have to remember that trick for the future. \$\endgroup\$Dennis– Dennis2018年05月04日 14:02:25 +00:00Commented May 4, 2018 at 14:02
-
\$\begingroup\$ Where´s the
repeat until you reach a single digit? \$\endgroup\$Titus– Titus2018年05月04日 14:28:19 +00:00Commented 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\$Dennis– Dennis2018年05月04日 14:30:19 +00:00Commented 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\$Titus– Titus2018年05月04日 15:14:04 +00:00Commented May 4, 2018 at 15:14 -
\$\begingroup\$ You can reduce \$\endgroup\$xnor– xnor2018年05月05日 18:21:17 +00:00Commented May 5, 2018 at 18:21
05AB1E, 7 bytes
LOΔSPSO
Exlpanation
L # push range [1 ... input]
O # sum range
Δ # loop until top of stack stops changing
SP # product of digits
SO # sum of digits
-
\$\begingroup\$ Almost ASCII-only! :D \$\endgroup\$AdmBorkBork– AdmBorkBork2018年05月04日 14:26:52 +00:00Commented May 4, 2018 at 14:26
-
\$\begingroup\$ @AdmBorkBork: Yeah, not terribly common :P \$\endgroup\$Emigna– Emigna2018年05月04日 15:33:01 +00:00Commented May 4, 2018 at 15:33
Jelly, 8 bytes
RSDPDƲÐL
Full program (it returns a singleton array containing the result, but the brackets aren't visible in STDOUT).
-
1\$\begingroup\$ This is the most "natural-looking" Jelly answer I've seen yet. There are only 2 non-ASCII characters \$\endgroup\$RedClover– RedClover2018年05月05日 18:57:11 +00:00Commented May 5, 2018 at 18:57
-
\$\begingroup\$ @Soaku codegolf.stackexchange.com/questions/69424/… \$\endgroup\$Esolanging Fruit– Esolanging Fruit2018年05月05日 19:19:03 +00:00Commented 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\$Erik the Outgolfer– Erik the Outgolfer2018年05月05日 19:21:05 +00:00Commented May 5, 2018 at 19:21
MATL, (削除) 15 (削除ここまで) 13 bytes
In tribute to the Language of the month:
:`sV!UpV!Utnq
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.
JavaScript (ES6), 60 bytes
f=(n,k=n*++n/2)=>k>9?f(!n,eval([...k+''].join('*+'[+!n]))):k
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
-
\$\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– Ross Presser2018年05月04日 17:38:50 +00:00Commented 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\$Arnauld– Arnauld2018年05月04日 17:45:05 +00:00Commented May 4, 2018 at 17:45
Stax, (削除) 14 (削除ここまで) (削除) 13 (削除ここまで) 10 bytes
ñu┌↕a√äJ2┐
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
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
@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.
-
\$\begingroup\$ Ah, I see. Scientific notation output. Good catch! \$\endgroup\$AdmBorkBork– AdmBorkBork2018年05月04日 15:14:47 +00:00Commented May 4, 2018 at 15:14
-
1\$\begingroup\$ Finally got around the
scipen: Try it online! note themax(0,log10(x))is because ifx=0, thenlog10(0)=-Infwhich causes an error. \$\endgroup\$Giuseppe– Giuseppe2018年05月04日 21:26:03 +00:00Commented May 4, 2018 at 21:26
-
\$\begingroup\$ Try putting the sum inside. Not sure if it's safe, but it should probably work. \$\endgroup\$user– user2020年12月23日 20:39:42 +00:00Commented Dec 23, 2020 at 20:39
Pyth, 11 bytes
usj*FjGTTsS
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.
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.
Iθ
Cast the result to string and implicitly print it.
Gaia, 8 bytes
┅⟨Σ₸∨Π⟩°
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.
-
\$\begingroup\$
┅⟨ΣΠ⟩°saves a byte. \$\endgroup\$Dennis– Dennis2018年05月04日 20:00:14 +00:00Commented May 4, 2018 at 20:00 -
\$\begingroup\$ This doesn’t work for values were the digital sum is 0, like
4\$\endgroup\$Jo King– Jo King2018年05月04日 20:59:09 +00:00Commented May 4, 2018 at 20:59 -
\$\begingroup\$ @JoKing Fixed, thanks for spotting that. Unfortunately, in Gaia, taking the digits of
0results in[]for some reason :( \$\endgroup\$Mr. Xcoder– Mr. Xcoder2018年05月04日 21:09:38 +00:00Commented May 4, 2018 at 21:09
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
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
rinto its component digits (d r). - Get the product of all those digits. This uses
Seq.reducewhich 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.
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.
Gol><>, (削除) 35 (削除ここまで) 33 bytes
1AY:P*2,TYMR*YR+:a(?Bt
:a(qlBaSD$
-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
Japt, (削除) 16 (削除ここまで) (削除) 14 (削除ここまで) 13 bytes
_ì ×ばつìx}gN®õ x
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
-
\$\begingroup\$ Neat, I tried to solve this one myself but didn't find a good solution so it's interesting to see yours. \$\endgroup\$Etheryte– Etheryte2018年05月04日 17:38:44 +00:00Commented May 4, 2018 at 17:38
-
\$\begingroup\$ Thanks, @Nit. There's gotta be a shorter way, though. \$\endgroup\$Shaggy– Shaggy2018年05月04日 18:16:38 +00:00Commented May 4, 2018 at 18:16
-
\$\begingroup\$ @Nit, got it! Still convinced there has to be a shorter way, though. \$\endgroup\$Shaggy– Shaggy2018年05月04日 22:55:00 +00:00Commented May 4, 2018 at 22:55
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 ofdo ... 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 assigningstr_splitto a variable at all would waste another byte.)
-
\$\begingroup\$ You can use
[*](.comb).combinstead of([*] .comb).comb\$\endgroup\$Brad Gilbert b2gills– Brad Gilbert b2gills2018年05月04日 18:23:51 +00:00Commented May 4, 2018 at 18:23
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}
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!
-
\$\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– AdmBorkBork2018年05月04日 18:12:15 +00:00Commented 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\$Jeff Freeman– Jeff Freeman2018年05月04日 18:37:02 +00:00Commented May 4, 2018 at 18:37 -
\$\begingroup\$ Sorry I wasn't clear --
[char[]]"$o"and a|iexrather thaniex( ). \$\endgroup\$AdmBorkBork– AdmBorkBork2018年05月04日 18:56:12 +00:00Commented May 4, 2018 at 18:56 -
\$\begingroup\$ This tip shaved 8% of my code off. Awesome. Thanks! \$\endgroup\$Jeff Freeman– Jeff Freeman2018年05月04日 19:20:13 +00:00Commented May 4, 2018 at 19:20
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;}
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
Julia 0.6, 56 bytes
f(n,k=(n+1)n÷2)=k>9?f(0,sum(digits(prod(digits(k))))):k
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.
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)
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
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}
-
\$\begingroup\$ Failed outgolf, 119 \$\endgroup\$sergiol– sergiol2018年05月07日 12:06:21 +00:00Commented May 7, 2018 at 12:06
-
n. The solution posted only has to work up ton = 100000. \$\endgroup\$Numbers will get very large quicklyno it doesn't \$\endgroup\$