26
\$\begingroup\$

Originally the Multiplicative digital root

Challenge

Basically do what the title says

Method

Given a positive integer 1 <= N <= 100000000 through one of our standard input methods, multiply every digit together, ignoring zeroes.

Ex: Take a number, say 361218402:

  • 3 * 6 = 18
  • 18 * 1 = 18
  • 18 * 2 = 36
  • 36 * 1 = 36
  • 36 * 8 = 288
  • 288 * 4 = 1152
  • 1152 * 1 (ignore zeroes or turn them into ones) = 1152
  • 1152 * 2 = 2304

The output for 361218402 is 2304

Test Cases

1 => 1
every other digit > 0 => itself
10 => 1
20 => 2
100 => 1
999 => 729
21333 => 54
17801 => 56
4969279 => 244944
100000000 => 1

Standard Loopholes are disallowed, and this is , so shortest byte count wins!

Congrats to Jo King who got the bounty with his 70 byte brain-flak answer!

\$\endgroup\$
  • 5
    \$\begingroup\$ I'd rather call this non-zero digital product. "root" suggests it reduces to a single digit, which isn't always true here. \$\endgroup\$ – Erik the Outgolfer Jan 15 '18 at 20:46
  • 1
    \$\begingroup\$ Can we take input as a string? Or (pushing it) an array of digits? \$\endgroup\$ – Shaggy Jan 15 '18 at 21:19
  • \$\begingroup\$ @EriktheOutgolfer Yes, however, if you repeat the process enough times, it does appear to always go to a single digit. \$\endgroup\$ – DJMcMayhem Jan 15 '18 at 21:21
  • \$\begingroup\$ You can take quoted input, but no, you can't take a pre-parsed list of digits if that's what you're asking \$\endgroup\$ – FantaC Jan 15 '18 at 21:21
  • 7
    \$\begingroup\$ If we have to support to a max of 100000000000 I suggest the test case 99999999999 => 31381059609, since it doesn't fit in a default 32-bit integer. Perhaps better would be to lower the maximum output to a 32-bit maximum (2147483647). \$\endgroup\$ – Kevin Cruijssen Jan 16 '18 at 8:27

63 Answers 63

1
\$\begingroup\$

Add++, 12 bytes

L,EDBFEZB]B*

Try it online!

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

Clean, 55 bytes

import StdEnv
@n=prod[toInt c-48\\c<-:toString n|c>'0']

Try it online!

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

APL+WIN, 9 bytes

×/(⍎¨⎕)~0

Prompts for screen input as a character string, convert to digits, drop zeros and multiply all.

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

Python 2, 46 44 bytes

f=lambda n,v=1:n and f(n/10,n%10*v or v)or v

Try it online!

2 bytes thx to Lynn.

\$\endgroup\$
  • \$\begingroup\$ f(n/10,n%10*v or v) saves 2 bytes. \$\endgroup\$ – Lynn Jan 15 '18 at 21:08
1
\$\begingroup\$

Forth (gforth), 62 bytes

: f 1 swap begin ?dup while 10 /mod -rot 1 max * swap repeat ;

Try it online!

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

APL (Dyalog), 11 7 bytes

4 bytes saved thanks to @EriktheOutgolfer

×/0~⍨⍎¨

Try it online!

\$\endgroup\$
  • \$\begingroup\$ 7 bytes (although I doubt you can take the number as a string, but then still 9 bytes) \$\endgroup\$ – Erik the Outgolfer Jan 15 '18 at 21:13
1
\$\begingroup\$

Lua, 45 bytes

a=1(...):gsub("[^0]",load("a=a*..."))print(a)

Try it online!

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

Pyth, 10 9 Bytes

.U*s!BsZs

Try it!

Explanation

.U*s!BsZs
.U        Q     Fold over the implicit input string
      sZ        Convert each char to int
   s!B          Form the list [d,not d] and sum it, so that 0 becomes 1
  *     sb      Multiply by the prev product (implicit). s needed because 1st value is char
\$\endgroup\$
1
\$\begingroup\$

Japt, 5 bytes

ì f ×

Test it here


Explanation

In order: split to an array of digits, filter to remove zeroes and reduce by multiplication.

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

Perl 6, 19 bytes

{[*] grep +*,.comb}

Test it

Expanded:

{  # bare block lambda with implicit parameter 「$_」

  [*]        # reduce using &infix:«*»

    grep     # find the values
      +*,    # that aren't "0"
      .comb  # split 「$_」 into digits (returns single character strings)
}
\$\endgroup\$
1
\$\begingroup\$

Batch, 78 bytes

@set/ap=%2+0,p+=!p,d=%1%%10,p*=d+!d,n=%1/10
@if %1 gtr 0 %0 %n% %p%
@echo %2

Previous 80-byte solution:

@set/an=%1,p=1
:l
@set/ad=n%%10,p*=d+!d,n/=10
@if %n% gtr 0 goto l
@echo %p%

(This version outputs 1 for an input of zero, rather than failing.)

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

Husk, 4 bytes

ΠfId

Try it online!

ΠfId  -- implicit input N, for example 1607
   d  -- digigts: [1,6,0,7]
 fI   -- filter by identity function: [1,6,7]
Π     -- product: 42
\$\endgroup\$
1
\$\begingroup\$

dc, 40 bytes

Sad to see dc so underrepresented here.

This is essentially my first code golf post, so if I've misjudged how bytes should be counted, go easy on me! :)

?[1+]sc[10~rdZ1<a]dsax1[rd0=c*z1<b]dsbxp

You can run this in the terminal like so:

$ echo 361218402 | dc -e '?[1+]sc[10~rdZ1<a]dsax1[rd0=c*z1<b]dsbxp'
2304

Or you can try it online!


Explanation (probably too verbose):

? # Read and execute a line from standard input
  # (A number just goes on the stack)
[ # Begin a literal string (ended by a matched ']')
1 # Push 1 onto the stack (when this string is executed as a macro)
+ # Pop top two numbers, add them, push result
] # End literal string
s # Pop top of stack (the string) and store it in...
c # ...register c
[
10 # Push 10 (duh)
~ # Pop top two numbers, divide second popped by first popped, push quotient and then remainder
r # Reverse top two numbers of stack
d # Duplicate top of stack (pop and then push it twice)
Z # Pop top of stack and push its length in digits
1
< # Pop two numbers and compare; if first popped is less than second then...
a # ...run macro stored in register a (a recursive call, here)
] # End string
d # Duplicate top of stack
s # Store in...
a # ...register a
x # Execute the top of stack!
  # At this point the stack will consist of one digit entries, the digits of input
1
[
r # Reverse
d # Duplicate
0
= # If top two numbers are equal then...
c # ...run macro in register c
* # Pop two, multiply, push product
z # Push "height" of stack
1
< # If height of stack is greater than 1 then...
b # ...run macro b
]
d # Duplicate the string on the stack
sb # Store it as macro b
x # Execute!
p # Print top of stack
\$\endgroup\$
  • \$\begingroup\$ Always nice to see dc around :) I added a TIO link, hope you don't mind - feel free to rollback if you don't like my edit. \$\endgroup\$ – ბიმო Jan 16 '18 at 9:00
  • \$\begingroup\$ @BMO thanks! And I don’t know if this is maximally golfed; it’s pretty straightforward implementation. \$\endgroup\$ – Wildcard Jan 16 '18 at 9:01
  • \$\begingroup\$ You might be able to get rid of the first macro and 0=c with this tip, but I haven't tried myself. \$\endgroup\$ – ბიმო Jan 16 '18 at 9:10
1
\$\begingroup\$

Red, 68 bytes

func[n][p: 1 while[n > 0][d: n // 10 n: n / 10 if d > 0[p: p * d]]p]

Try it online!

Since 100000000000 is beyond the integer range of the Red language, here's another approach that solves this issue, using string manipulation:

Red, 74 bytes

func[n][p: 1 foreach c to-string n[if c >#"0"[p: p * to-integer c - 48]]p]

Try it online!

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

Javascript, 58 bytes

f=a=>{b=1;for(i=0;a[i];i++){(a[i]>0)&&(b=+b*a[i])}alert(b)

Input via function(arg) outputs alert

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

K (oK), 10 7 bytes

Solution:

*/1|.:'

Try it online!

Example:

*/1|.:'"4969279"
244944

Explanation:

Convert the input string to a list of integers, take max compared to 1 (inspiration from the J solution) and then multiply over the list.

Evaluation is performed right to left.

*/1|.:' / the solution
    .:' / value (.:) each (')
  1|    / or with 1 ( 0=>1, 1=>1, 2=>2 )
*/      / multiply (*) over (/) 
\$\endgroup\$
1
\$\begingroup\$

SNOBOL4 (CSNOBOL4), 83 bytes

	DEFINE('O(N)')
O	O =1
R	N LEN(1) . X REM . N	:F(RETURN)
	X =EQ(X) 1
	O =O * X	:(R)

Try it online!

A function that takes input as a string.

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

Julia 0.6, 33 bytes

x->prod(filter(x->x>0,digits(x)))

Try it online!

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

Pyth, 7 bytes

*FsMs#Q

Try it online!


*FsMs#Q Full program, takes input in "" from stdin and prints to stdout
    s#Q Filter input for truthiness of int-parse(digit), then
  sM    map int-parse to this,
*F      then fold over multiplication
\$\endgroup\$
1
\$\begingroup\$

C# (.NET Core), 78 bytes

using System.Linq

n=>n.Replace("0","").Select(c=>c-'0').Aggregate(1,(a,b)=>a*b)

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Smaller is n=>n.Select(c=>c-'0').Aggregate(1,(a,b)=>a*(b==0?1:b)); You ought to include the terminating ';' \$\endgroup\$ – user230118 Jan 19 '18 at 0:36
  • \$\begingroup\$ Following @user230118 suggestion, you can shrink it more by replacing '0' with 48, and (b==0?1:b) with (b>0?b:1) \$\endgroup\$ – auhmaan Sep 23 '19 at 16:50
1
\$\begingroup\$

Pari/GP, 34 bytes

n->fold((a,b)->a*(b+!b),digits(n))

Try it online!

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

Pyth, 6 bytes

*F #sM

Try it Online!

Explanation:

    sM   Get digits of implicit string input
   #     Filter on identity, removing 0s
*F       Fold on multiplication
\$\endgroup\$
1
\$\begingroup\$

Pip, 7 bytes

$*YaDC0

Try it online!

Delete Character 0 from the argument a and fold ($) on multiplication (*). The Yank operator is used to adjust the precedence of the subexpression (one byte shorter than $*(aDC0)).

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

Jelly, 4 bytes

Dḟ0P

Try it online!

Dḟ0P    main link

D       int to dec
 ḟ0     filter out 0
   P    product of list
\$\endgroup\$
1
\$\begingroup\$

Befunge-98 (PyFunge), 14 bytes

1<*+!:-0'~.j@#

Try it online!

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

Microsoft Excel - 62 47 Bytes

{=PRODUCT(IFERROR(1/(1/MID(A1,ROW(A:A),1)),1))}

Explanation

Converts value in cell A1 to array of digits, changes 0s to 1s using absolute value, then multiplies.

15 bytes saved thanks to Engineer Toast

\$\endgroup\$
  • \$\begingroup\$ Save 15 bytes: {=PRODUCT(IFERROR(1/(1/MID(A1,ROW(A:A),1)),1))}. It drops zeroes by trying to divide by them to get an error. You can drop the INDIRECT stuff, too, because dividing by blank text values will also give you an error. All the errors are replaced by 1. \$\endgroup\$ – Engineer Toast Jan 18 '18 at 13:11
1
\$\begingroup\$

Stax, 4 bytesCP437

┤caü

5 bytes when unpacked,

E0-k*

Run and debug online!

Explanation

E         Convert number to digits
 0-       Remove all zeros
   k*     Reduce array with multiplication
\$\endgroup\$
1
\$\begingroup\$

JavaScript, 33 32 bytes

Feels like ages since I've done an array mapping solution in JS!

Takes input as a string.

n=>[...n].map(x=>t*=+x||1,t=1)|t

Try it

o.innerText=(f=
n=>[...n].map(x=>t*=+x||1,t=1)|t
)(i.value="361218402");oninput=_=>o.innerText=f(i.value)
<input id=i type=number><pre id=o>

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

Ruby + -n, 25 bytes

p eval ($_.chars-[?0])*?*

Try it online!

Ruby (vanilla), 27 bytes

p eval (gets.chars-[?0])*?*

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Using ruby -n you can use $_ instead of gets for -2! \$\endgroup\$ – Dom Hastings Mar 1 '18 at 12:19
  • \$\begingroup\$ @DomHastings Thanks, I'm pretty sure that flag still counts for 1 byte though \$\endgroup\$ – Asone Tuhid Mar 1 '18 at 12:36
  • \$\begingroup\$ I believe the new consensus is Ruby + -n is counted as a different lang without the +1 for -n. Meta \$\endgroup\$ – Dom Hastings Mar 1 '18 at 13:23
  • \$\begingroup\$ @DomHastings it's a proposal but I'm not going to argue with fewer bytes \$\endgroup\$ – Asone Tuhid Mar 1 '18 at 13:45
1
\$\begingroup\$

Attache, 20 19 bytes

Prod##Max&1=>Digits

Try it online! Function that takes an integer as an argument and returns an integer.

Explanation

This first takes the Digits of the input number, then each number's Max with 1 is taken, then the Product is taken.

Other solutions

Prod@Larger&1@Digits
Prod@Map[Max&1]@Digits
Prod@Map&:(Max&1)@Digits
{Prod[Max&1=>Digits[_]]}
\$\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.