Digital root/Multiplicative digital root: Difference between revisions
(→{{header|Python}}: Remove del loop - keep all of table.) |
(+ 3 D versions) |
||
Line 28: | Line 28: | ||
* [[wp:Multiplicative digital root|Multiplicative digital root]] on Wikipedia. |
* [[wp:Multiplicative digital root|Multiplicative digital root]] on Wikipedia. |
||
* [http://oeis.org/A031347 Multiplicative digital root] on The On-Line Encyclopedia of Integer Sequences. |
* [http://oeis.org/A031347 Multiplicative digital root] on The On-Line Encyclopedia of Integer Sequences. |
||
=={{header|D}}== |
|||
{{trans|Python}} |
|||
<lang d>import std.stdio, std.algorithm, std.typecons, std.range, std.conv; |
|||
/// Multiplicative digital root. |
|||
auto mdRoot(in int n) pure /*nothrow*/ { |
|||
auto mdr = [n]; |
|||
while (mdr.back > 9) |
|||
mdr ~= reduce!q{a * b}(1, mdr.back.text.map!(d => d - '0')); |
|||
//mdr ~= mdr.back.text.map!(d => d - '0').mul; |
|||
//mdr ~= mdr.back.reverseDigits.mul; |
|||
return tuple(mdr.length - 1, mdr.back); |
|||
} |
|||
void main() { |
|||
"Number: (MP, MDR)\n====== =========".writeln; |
|||
foreach (immutable n; [123321, 7739, 893, 899998]) |
|||
writefln("%6d: (%s, %s)", n, n.mdRoot[]); |
|||
auto table = 10.iota.zip((int[]).init.repeat).assocArray; |
|||
auto n = 0; |
|||
while (table.byValue.map!walkLength.reduce!min < 5) { |
|||
table[n.mdRoot[1]] ~= n; |
|||
n++; |
|||
} |
|||
"\nMP: [n0..n4]\n== ========".writeln; |
|||
foreach (const mp; table.byKey.array.sort()) |
|||
writefln("%2d: %s", mp, table[mp].take(5)); |
|||
}</lang> |
|||
{{out}} |
|||
<pre>Number: (MP, MDR) |
|||
====== ========= |
|||
123321: (3, 8) |
|||
7739: (3, 8) |
|||
893: (3, 2) |
|||
899998: (2, 0) |
|||
MP: [n0..n4] |
|||
== ======== |
|||
0: [0, 10, 20, 25, 30] |
|||
1: [1, 11, 111, 1111, 11111] |
|||
2: [2, 12, 21, 26, 34] |
|||
3: [3, 13, 31, 113, 131] |
|||
4: [4, 14, 22, 27, 39] |
|||
5: [5, 15, 35, 51, 53] |
|||
6: [6, 16, 23, 28, 32] |
|||
7: [7, 17, 71, 117, 171] |
|||
8: [8, 18, 24, 29, 36] |
|||
9: [9, 19, 33, 91, 119]</pre> |
|||
===Alternative Version=== |
|||
<lang d>import std.stdio, std.algorithm, std.typecons, std.range; |
|||
uint digitsProduct(uint n) pure nothrow { |
|||
typeof(return) result = !!n; |
|||
while (n) { |
|||
result *= n % 10; |
|||
n /= 10; |
|||
} |
|||
return result; |
|||
} |
|||
/// Multiplicative digital root. |
|||
Tuple!(size_t, uint) mdRoot(uint m) pure nothrow { |
|||
auto mdr = m |
|||
.recurrence!((a, n) => a[n - 1].digitsProduct) |
|||
.until!q{ a <= 9 }(OpenRight.no).array; |
|||
return tuple(mdr.length - 1, mdr.back); |
|||
} |
|||
void main() { |
|||
"Number: (MP, MDR)\n====== =========".writeln; |
|||
foreach (immutable n; [123321, 7739, 893, 899998]) |
|||
writefln("%6d: (%s, %s)", n, n.mdRoot[]); |
|||
auto table = 10.iota.zip((int[]).init.repeat).assocArray; |
|||
auto n = 0; |
|||
while (table.byValue.map!walkLength.reduce!min < 5) { |
|||
table[n.mdRoot[1]] ~= n; |
|||
n++; |
|||
} |
|||
"\nMP: [n0..n4]\n== ========".writeln; |
|||
foreach (const mp; table.byKey.array.sort()) |
|||
writefln("%2d: %s", mp, table[mp].take(5)); |
|||
}</lang> |
|||
===More Efficient Version=== |
|||
<lang d>import std.stdio, std.algorithm, std.range; |
|||
/// Multiplicative digital root. |
|||
uint[2] mdRoot(in uint n) pure nothrow { |
|||
uint mdr = n; |
|||
uint count = 0; |
|||
while (mdr > 9) { |
|||
uint m = mdr; |
|||
uint digitsMul = !!m; |
|||
while (m) { |
|||
digitsMul *= m % 10; |
|||
m /= 10; |
|||
} |
|||
mdr = digitsMul; |
|||
count++; |
|||
} |
|||
return [count, mdr]; |
|||
} |
|||
void main() { |
|||
"Number: [MP, MDR]\n====== =========".writeln; |
|||
foreach (immutable n; [123321, 7739, 893, 899998]) |
|||
writefln("%6d: %s", n, n.mdRoot); |
|||
auto table = 10.iota.zip((uint[]).init.repeat).assocArray; |
|||
auto n = 0; |
|||
while (table.byValue.map!walkLength.reduce!min < 5) { |
|||
table[n.mdRoot[1]] ~= n; |
|||
n++; |
|||
} |
|||
"\nMP: [n0..n4]\n== ========".writeln; |
|||
foreach (const mp; table.byKey.array.sort()) |
|||
writefln("%2d: %s", mp, table[mp].take(5)); |
|||
}</lang> |
|||
The output is similar. |
|||
=={{header|Python}}== |
=={{header|Python}}== |
Revision as of 00:03, 12 April 2014
The multiplicative digital root (MDR) and multiplicative persistence (MP) of a number (N) is calculated rather like the Digital root except digits are multiplied:
- Set MDR to N and MP to 0
- While MDR has more than one digit:
- Find a replacement MDR as the multiplication of the digits of the current MDR
- Increment MP
- Return MP and MDR
- Task
- Tabulate the MP and MDR of the numbers 123321, 7739, 893, 899998
- Tabulate MP versus the first five numbers having that MP, something like:
MP: [n0..n4] == ======== 0: [0, 10, 20, 25, 30] 1: [1, 11, 111, 1111, 11111] 2: [2, 12, 21, 26, 34] 3: [3, 13, 31, 113, 131] 4: [4, 14, 22, 27, 39] 5: [5, 15, 35, 51, 53] 6: [6, 16, 23, 28, 32] 7: [7, 17, 71, 117, 171] 8: [8, 18, 24, 29, 36] 9: [9, 19, 33, 91, 119]
Show all output on this page.
- References
- Multiplicative Digital Root on Wolfram Mathworld.
- Multiplicative digital root on Wikipedia.
- Multiplicative digital root on The On-Line Encyclopedia of Integer Sequences.
D
<lang d>import std.stdio, std.algorithm, std.typecons, std.range, std.conv;
/// Multiplicative digital root. auto mdRoot(in int n) pure /*nothrow*/ {
auto mdr = [n]; while (mdr.back > 9) mdr ~= reduce!q{a * b}(1, mdr.back.text.map!(d => d - '0')); //mdr ~= mdr.back.text.map!(d => d - '0').mul; //mdr ~= mdr.back.reverseDigits.mul; return tuple(mdr.length - 1, mdr.back);
}
void main() {
"Number: (MP, MDR)\n====== =========".writeln; foreach (immutable n; [123321, 7739, 893, 899998]) writefln("%6d: (%s, %s)", n, n.mdRoot[]);
auto table = 10.iota.zip((int[]).init.repeat).assocArray; auto n = 0; while (table.byValue.map!walkLength.reduce!min < 5) { table[n.mdRoot[1]] ~= n; n++; } "\nMP: [n0..n4]\n== ========".writeln; foreach (const mp; table.byKey.array.sort()) writefln("%2d: %s", mp, table[mp].take(5));
}</lang>
- Output:
Number: (MP, MDR) ====== ========= 123321: (3, 8) 7739: (3, 8) 893: (3, 2) 899998: (2, 0) MP: [n0..n4] == ======== 0: [0, 10, 20, 25, 30] 1: [1, 11, 111, 1111, 11111] 2: [2, 12, 21, 26, 34] 3: [3, 13, 31, 113, 131] 4: [4, 14, 22, 27, 39] 5: [5, 15, 35, 51, 53] 6: [6, 16, 23, 28, 32] 7: [7, 17, 71, 117, 171] 8: [8, 18, 24, 29, 36] 9: [9, 19, 33, 91, 119]
Alternative Version
<lang d>import std.stdio, std.algorithm, std.typecons, std.range;
uint digitsProduct(uint n) pure nothrow {
typeof(return) result = !!n; while (n) { result *= n % 10; n /= 10; } return result;
}
/// Multiplicative digital root. Tuple!(size_t, uint) mdRoot(uint m) pure nothrow {
auto mdr = m .recurrence!((a, n) => a[n - 1].digitsProduct) .until!q{ a <= 9 }(OpenRight.no).array; return tuple(mdr.length - 1, mdr.back);
}
void main() {
"Number: (MP, MDR)\n====== =========".writeln; foreach (immutable n; [123321, 7739, 893, 899998]) writefln("%6d: (%s, %s)", n, n.mdRoot[]);
auto table = 10.iota.zip((int[]).init.repeat).assocArray; auto n = 0; while (table.byValue.map!walkLength.reduce!min < 5) { table[n.mdRoot[1]] ~= n; n++; } "\nMP: [n0..n4]\n== ========".writeln; foreach (const mp; table.byKey.array.sort()) writefln("%2d: %s", mp, table[mp].take(5));
}</lang>
More Efficient Version
<lang d>import std.stdio, std.algorithm, std.range;
/// Multiplicative digital root. uint[2] mdRoot(in uint n) pure nothrow {
uint mdr = n; uint count = 0;
while (mdr > 9) { uint m = mdr; uint digitsMul = !!m; while (m) { digitsMul *= m % 10; m /= 10; } mdr = digitsMul; count++; }
return [count, mdr];
}
void main() {
"Number: [MP, MDR]\n====== =========".writeln; foreach (immutable n; [123321, 7739, 893, 899998]) writefln("%6d: %s", n, n.mdRoot);
auto table = 10.iota.zip((uint[]).init.repeat).assocArray; auto n = 0; while (table.byValue.map!walkLength.reduce!min < 5) { table[n.mdRoot[1]] ~= n; n++; } "\nMP: [n0..n4]\n== ========".writeln; foreach (const mp; table.byKey.array.sort()) writefln("%2d: %s", mp, table[mp].take(5));
}</lang> The output is similar.
Python
<lang python>try:
from functools import reduce
except:
pass
def mdroot(n):
'Multiplicative digital root' mdr = [n] while mdr[-1] > 9: mdr.append(reduce(int.__mul__, (int(dig) for dig in str(mdr[-1])), 1)) return len(mdr) - 1, mdr[-1]
if __name__ == '__main__':
print('Number: (MP, MDR)\n====== =========') for n in (123321, 7739, 893, 899998): print('%6i: %r' % (n, mdroot(n))) table, n = {i: [] for i in range(10)}, 0 while min(len(row) for row in table.values()) < 5: mpersistence, mdr = mdroot(n) table[mdr].append(n) n += 1 print('\nMP: [n0..n4]\n== ========') for mp, val in sorted(table.items()): print('%2i: %r' % (mp, val[:5]))</lang>
- Output:
Number: (MP, MDR) ====== ========= 123321: (3, 8) 7739: (3, 8) 893: (3, 2) 899998: (2, 0) MP: [n0..n4] == ======== 0: [0, 10, 20, 25, 30] 1: [1, 11, 111, 1111, 11111] 2: [2, 12, 21, 26, 34] 3: [3, 13, 31, 113, 131] 4: [4, 14, 22, 27, 39] 5: [5, 15, 35, 51, 53] 6: [6, 16, 23, 28, 32] 7: [7, 17, 71, 117, 171] 8: [8, 18, 24, 29, 36] 9: [9, 19, 33, 91, 119]