Compute the Digit Difference Sum of a Number
Python 2, 73
Luckily, I managed to avoid any string operations.
t=lambda n:n>9and abs(n%10-n/10%10)+10*t(n/10)
g=lambda n:n and n+g(t(n))
g
is the function that computes the answer.
Matlab, 101 105 bytes
Thanks a lot to @beaker for his suggestion to use polyval
instead if base2dec
. That allowed me to
- save 4 bytes;
- greatly simplify the generalization to arbitrary base (see below) and save 22 bytes there; and most of all,
- helped me realize that the code for the general case was wrong (leading zeros were not being removed). The code and the graphs are correct now.
Code:
function y=f(y)
x=+num2str(y);while numel(x)>1
x=polyval(abs(diff(x)),10);y=y+x;x=+dec2base(x,10);end
Example:
>> f(8675309)
ans =
8898683
Bonus: arbitrary base
A small generalization allows one to use an arbitrary number base, not necessarily decimal:
Arbitrary base from 2 to 10,
108104 bytesfunction y=f(y,b) x=+dec2base(y,b);while numel(x)>1 x=polyval(abs(diff(x)),b);y=y+x;x=+dec2base(x,b);end
The reason why this works only for base up to
10
is that Matlab'sdec2base
function uses digits0
,1
, ...,9
,A
,B
, ..., and there's a jump in character (ASCII) codes from9
toA
.Arbitrary base from 2 to 36, 124
146bytesThe jump from
9
toA
referred to above needs special treatment. The maximum base is36
as per Matlab'sdec2base
function.function y=f(y,b) x=+dec2base(y,b);x(x>57)=x(x>57)-7;while numel(x)>1 x=abs(diff(x));x=x(find(x,1):end);y=y+polyval(x,b);end
This is how the dentist's staircases look for different bases:
CJam, 22 21 bytes
ri_{\s2ew::-:zsi_@+}h
Note that this program exits with an error, which is allowed by default.
With the Java interpreter, errors can be suppressed by closing STDERR. If you try this code online in the CJam interpreter, ignore all output before the last line.
Thanks to @Sp3000 for pointing out an error in the original revision.
Thanks to @MartinBüttner for golfing off 1 byte.
Example run
$ cjam digit-difference.cjam 2>&- <<< 8675309
8898683
How it works
ri_ e# Read an integer (I) from STDIN and push a copy (A).
{ e# Do:
\ e# Swap I on top of A.
s e# Cast I to string.
e# For example, 123 -> "123".
2ew e# Push the overlapping slices of length 2 (pair of adjacent digits).
::- e# Replace each pair by its difference.
:z e# Apply absolute value to each difference.
si e# Cast to string, then to integer. This is the new I.
e# For example, [1 2 3] -> "123" -> 123.
_ e# Push a copy of I.
@ e# Rotate A on top of the copy of I.
+ e# Add I to A, updating A.
}h e# While A is truthy, repeat the loop.
A will always be truthy when checked by h
. However, once I is a single-digit integer, 2ew
will fail with an error after consuming the array it was called on. This leaves only the desired result on the stack, which is printed before exiting.