28
\$\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

Note: Treat the digit 0 in numbers as 1.

Test Cases

1 => 1
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\$
6
  • 6
    \$\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\$ Jan 15, 2018 at 20:46
  • 1
    \$\begingroup\$ Can we take input as a string? Or (pushing it) an array of digits? \$\endgroup\$
    – Shaggy
    Jan 15, 2018 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, 2018 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\$
    – qqq
    Jan 15, 2018 at 21:21
  • 8
    \$\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\$ Jan 16, 2018 at 8:27

69 Answers 69

1
\$\begingroup\$

Haskell, 36 bytes

f n=product[read[d]|d<-show n,d>'0']

Same byte count:

f n=product[max 1$read[d]|d<-show n]

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Also 36 \$\endgroup\$
    – H.PWiz
    Jan 15, 2018 at 20:56
1
\$\begingroup\$

Jelly, 6, 5 bytes

ṢU×\Ṁ

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ 5 mins, not bad! \$\endgroup\$
    – qqq
    Jan 15, 2018 at 20:26
  • \$\begingroup\$ DTịDP would save a byte, but there are better ways to strip zeroes or replace them with something else. \$\endgroup\$
    – Dennis
    Jan 15, 2018 at 20:34
  • 5
    \$\begingroup\$ Multiplicative root with ṢUṀ \$\endgroup\$
    – Uriel
    Jan 15, 2018 at 20:44
1
\$\begingroup\$

><>, 19 bytes

1i:&0(?n&c4*-:0=+*!

Try it online!

\$\endgroup\$
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\$
1
  • \$\begingroup\$ f(n/10,n%10*v or v) saves 2 bytes. \$\endgroup\$
    – Lynn
    Jan 15, 2018 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\$
1
  • \$\begingroup\$ 7 bytes (although I doubt you can take the number as a string, but then still 9 bytes) \$\endgroup\$ Jan 15, 2018 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\$
3
  • \$\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, 2018 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, 2018 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, 2018 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\$
2
  • \$\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, 2018 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, 2019 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\$
1
  • \$\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\$ Jan 18, 2018 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\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.