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\$
  • 4
    \$\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

3
\$\begingroup\$

Pyt, 3 bytes

ąžΠ

Explanation:

ą       Convert input to array of digits (implicit input as stack is empty)
 ž      Remove all zeroes from the array
  Π     Get the product of the elements of the array

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Surprised that this relatively new golfing lang is the only one that appears to be capable of solving this challenge in 3 bytes! \$\endgroup\$ – ETHproductions Jan 15 '18 at 21:55
  • \$\begingroup\$ I was surprised by that too! \$\endgroup\$ – mudkip201 Jan 15 '18 at 23:58
  • \$\begingroup\$ I didn't see your answer when I first accepted, but this is the shortest one! \$\endgroup\$ – FantaC Feb 17 '18 at 17:24
11
\$\begingroup\$

Haskell, 27 bytes

foldr((*).max 1.read.pure)1

Try it online!

Ungolfed with UniHaskell and -XUnicodeSyntax

import UniHaskell

f ∷ String → Int
f = product ∘ map (max 1 ∘ read ∘ pure)

Explanation

I'll start with what I initially had:

product.map(max 1.read.pure)

This is a point-free expression that evaluates to a function taking a string (or a list of characters) s ("301") as an argument. It maps max 1.read.pure over s, essentially taking each character i, injecting it into a list (which makes it a string) (["3", "0", "1"]), then reading it, which evaluates the string ([3, 0, 1]) and finally taking the greater of i and 1 ([3, 1, 1]). Then it takes the product of the resulting list of integers (3).

I then golfed it by a byte with:

foldr((*).max 1.read.pure)1

This works because product is equivalent to foldr (*) 1. Instead of mapping and folding, I combined the two by folding with (*).max 1.read.pure which takes each non-zero digit and multiplies it with the accumulator.

\$\endgroup\$
9
\$\begingroup\$

Python 2, 34 bytes

f=lambda n:n<1or(n%10or 1)*f(n/10)

Try it online!

\$\endgroup\$
7
\$\begingroup\$

Jelly, 4 bytes

Do1P

Try it online! or see the test suite

How it works

Do1P - Main link. Argument: n (integer)  e.g. 1230456
D    - Digits                                 [1, 2, 3, 0, 4, 5, 6]
 o1  - Replace 0 with 1                       [1, 2, 3, 1, 4, 5, 6]
   P - Product                                720
\$\endgroup\$
  • \$\begingroup\$ @tfbninja Calls the main link with each of the inputs \$\endgroup\$ – caird coinheringaahing Jan 15 '18 at 20:41
6
\$\begingroup\$

R, 40 bytes

cat(prod((x=scan()%/%10^(0:12)%%10)+!x))

Try it online!

Since input is guaranteed to have no more than 12 digits, this should work nicely. Computes the digits as x (including leading zeros), then replaces zeros with 1 and computes the product.

cat(					#output
    prod(				#take the product of
         (x=				#set X to
	    scan()			#stdin
		  %/%10^(0:12)%%10)	#integer divide by powers of 10, mod 10, yields digits of the input, with leading zeros. So x is the digits of the input
                                   +!x  #add logical negation, elementwise. !x maps 0->1 and nonzero->0. adding this to x yields 0->1, leaving others unchanged
                                      ))
\$\endgroup\$
  • \$\begingroup\$ So this is how to codegolf with R... Nice one ;) Still trying to figure out how this one works though! \$\endgroup\$ – Florian Jan 20 '18 at 9:23
  • 1
    \$\begingroup\$ @Florian I've added a more verbose explanation. \$\endgroup\$ – Giuseppe Jan 20 '18 at 15:01
  • \$\begingroup\$ That's a new way to split digits that I'll have to try! \$\endgroup\$ – BLT Mar 1 '18 at 13:56
  • \$\begingroup\$ @BLT that's one of my tips for golfing in R! \$\endgroup\$ – Giuseppe Mar 1 '18 at 14:01
5
\$\begingroup\$

C (gcc), 39 bytes

k;f(n){for(k=1;n;n/=10)k*=n%10?:1;k=k;}

Needs to be compiled without optimizations (which is the default setting for gcc, anyway).

Try it online!

\$\endgroup\$
  • \$\begingroup\$ That k=k; putting k in the return register accidentally is just plain evil. You should probably add that this only works without optimisations on possibly only x86/x64. +1. \$\endgroup\$ – tomsmeding Jan 16 '18 at 23:34
  • 1
    \$\begingroup\$ @tomsmeding Somewhat surprisingly, it does work on architectures other than x86. No optimizations (O0) is the default for gcc, so there is no need for explicitly using that flag. I guess I'll add a mention of it to the post anyway. \$\endgroup\$ – Steadybox Jan 16 '18 at 23:40
  • \$\begingroup\$ You might want to specify the exact version of GCC it works with, for future proofing. \$\endgroup\$ – moonheart08 Mar 1 '18 at 14:32
  • \$\begingroup\$ @moonheart08 I doubt that it would stop working after some version. Anyway, it works with the latest version, so the time of posting can be used to find a version with which it at least works. \$\endgroup\$ – Steadybox Mar 2 '18 at 20:13
5
+100
\$\begingroup\$

Brain-Flak, 74 72 70 bytes

-2 thanks to Nitrodon for suggesting getting the negation of the number so that you only have to increment rather than decrement later

{([{}]((((()()()){}){}){}){}){({<({}())><>([[]](){})<>}<><{}>)<>}{}}<>

Try it online!

There might be a few ways to golf this further, such as redoing the multiplication to avoid having to initialise the total with 1. (-2 bytes)

How It Works:

{ Loop over every number
  ([{}]((((()()()){}){}){}){}) Add 48 to the negative of the ASCII to get the negation of the digit
  { If the number is not 0
     ({<({}())><>([[]](){})<>}<><{}>)<> Multiply the total by the number
                                          If the total is on an empty stack, add 1
  } 
  {} Pop the excess 0
}<> Switch to the stack with the total
\$\endgroup\$
  • 1
    \$\begingroup\$ You can golf two more bytes by computing the negation of the actual digit, then counting up to 0 instead of down to 0. \$\endgroup\$ – Nitrodon Jan 18 '18 at 5:21
4
\$\begingroup\$

05AB1E, 4 bytes

0KSP

Try it online!

Explanation

0K     # remove zeroes
  S    # split to list of digits
   P   # product
\$\endgroup\$
  • \$\begingroup\$ I accepted this answer because it was a four way tie between Jelly, husk, and 05AB1E, and you answered first. \$\endgroup\$ – FantaC Jan 29 '18 at 2:05
4
\$\begingroup\$

J, 17 14 13 bytes

-4 bytes courtesy of @GalenIvanov

[:*/1>.,.&.":

Try it online!

Probably can be improved some. Edit: and so it was.

Explanation

[: */ 1 >. ,.&.":
                 ": Convert to string
             ,.     Convert row to column vector
               &.   Convert to numbers
      1 >.        Maximum of each element with 1 (convert 0 to 1)
   */              Product
[:                 Cap fork

&.-under is a nifty adverb that applies the verb on the right, then the verb on the left, then the inverse of the verb on the right. Also converting back to numbers is technically using eval (".-do).

\$\endgroup\$
  • 1
    \$\begingroup\$ You can save a byte by changing +0=] to *#] Try it online \$\endgroup\$ – Galen Ivanov Jan 16 '18 at 8:18
  • 1
    \$\begingroup\$ [:*/0-.~,.&.": for 14 bytes. Try it online \$\endgroup\$ – Galen Ivanov Jan 16 '18 at 12:22
  • \$\begingroup\$ @GalenIvanov I knew that signum would be useful! My original thought was (+-.@*), guess I'm inclined to add. I had tried using '0'-.~ assuming an input of a string, not sure why it didn't cross my mind to do it on the split digits. Thanks! \$\endgroup\$ – cole Jan 16 '18 at 16:30
  • 1
    \$\begingroup\$ 1>. does the job of 0-.~ for a byte less. [:*/1>.,.&.": Try it! \$\endgroup\$ – Galen Ivanov Jan 16 '18 at 18:25
3
\$\begingroup\$

Python 2, 43 bytes

lambda n:eval('*'.join(`n`.replace(*'01')))

Try it online!

\$\endgroup\$
3
\$\begingroup\$

JavaScript (ES6), 28 bytes

Designed for 32-bit integers.

f=n=>!n||(n%10||1)*f(n/10|0)

Test cases

f=n=>!n||(n%10||1)*f(n/10|0)

console.log(f(1))        // => 1
console.log(f(10))       // => 1
console.log(f(20))       // => 2
console.log(f(100))      // => 1
console.log(f(999))      // => 729
console.log(f(21333))    // => 54
console.log(f(17801))    // => 56
console.log(f(4969279))  // => 244944

\$\endgroup\$
3
\$\begingroup\$

Bash + coreutils + sed + bc, 27 24 23 bytes

tr 0 1|sed s/\\B/*/g|bc

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Brachylog, 5 bytes

⊇ẹ×ℕ₁

Try it online!

Explanation

⊇        Take a subset of the input
 ẹ       Split the subset into a list of digits
  ×      Product
   ℕ₁    This product must be in [1, +∞)

This works because unifies from large subsets to small subsets, so the first one that will result in a non-zero product is when all zeroes are excluded and nothing else.

\$\endgroup\$
3
\$\begingroup\$

Perl 5, 23 + 1 (-p) = 24 bytes

$\=1;s/./$\*=$&||1/ge}{

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Java 8, 55 54 53 51 bytes

int f(int n){return n>0?(n%10>0?n%10:1)*f(n/10):1;}

Port of @Dennis' Python 2 answer.
-1 byte thanks to @RiaD.

Try it here.

55 54 bytes version:

n->{int r=1;for(;n>0;n/=10)r*=n%10>0?n%10:1;return r;}

Try it online.

\$\endgroup\$
  • 1
    \$\begingroup\$ you can save parens like this: long f(long n){return n>0?(n%10>0?n%10:1)*f(n/10):1;} \$\endgroup\$ – RiaD Jan 16 '18 at 10:16
  • 1
    \$\begingroup\$ Sorry, I'm claiming this one (45 bytes) because the algorithm is totally different ;-) \$\endgroup\$ – Olivier Grégoire Jan 17 '18 at 13:45
3
\$\begingroup\$

Julia 0.6, 26 bytes

!x=prod(max.(digits(x),1))

Example of use:

julia> !54
20

Try it online!

\$\endgroup\$
  • \$\begingroup\$ could you add an example of how to call this, as well as a byte count? you can use TIO! \$\endgroup\$ – Giuseppe Jan 17 '18 at 14:56
  • \$\begingroup\$ @Giuseppe oops, I got distracted. I counted the length but didn't add it. Huh TIO supports julia now. Neat. \$\endgroup\$ – Lyndon White Jan 17 '18 at 15:15
  • \$\begingroup\$ In fact, TIO supports Julia 0.4-0.6! very nice, +1. \$\endgroup\$ – Giuseppe Jan 17 '18 at 15:22
3
\$\begingroup\$

JavaScript (Node.js), 30 bytes

f=([a,...b])=>a?(+a||1)*f(b):1

Try it online!

Takes string as an input, treats it as array, and by array destructuring separates the first element [a,...b]. +a||1 returns digit corresponding to a character. I guess that rest is self explaining..

\$\endgroup\$
3
\$\begingroup\$

Octave, 21 bytes

Thanks to @Luis Mendo for saving a byte and thanks to @alephalpha for saving another byte!

@(n)prod((k=n-48)+~k)

Takes input as a string of digits.

Try it online!

30 bytes:

@(n)prod((k=num2str(n)-48)+~k)

Takes input as a number.

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Brain-Flak, 88 bytes

Readable version:

#Push a 1 onto the alternate stack. Return to the main stack
(<>())<>

#While True:
{

    #Push the current digit minus 48 (the ASCII value of '0') onto the alternate stack
    ({}[((((()()()){}){}){}){}]<>)

    #If it's not 0...
    {
        (<

            #Multiply the top two values (the current digit and the current product that started at 1)
            ({}<>)({<({}[()])><>({})<>}{}<><{}>)

        #Also push a 0
        >)

    #Endwhile
    }

    #Pop the 0
    {}

    #Return to the main stack
    <>

#Endwhile
}

#Toggle to the alternate stack, and implicitly display
<>

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ 74 bytes \$\endgroup\$ – Jo King Jan 16 '18 at 2:06
  • \$\begingroup\$ I literally forgot I posted that comment, and rewrote it from scratch. I'm just going to post separately \$\endgroup\$ – Jo King Jan 18 '18 at 1:15
2
\$\begingroup\$

Clojure, 56 bytes

(fn[n](apply *(replace{0 1}(map #(-(int %)48)(str n)))))

Pretty basic. Turns the number into a string, then subtracts 48 from each character to turn them back into numbers. It then replaces each 0 with a 1, and applies * to the resulting list of numbers (which reduces * over the list). Can accept a number, or a stringified number.

Try it online!

(defn non-zero-prod [n]
  (let [; Abusing strings to get each digit individually
        str-n (str n)

        ; Then turn them back into numbers
        digits (map #(- (int %) 48) str-n)

        ; Substitute each 0 for a 1
        replaced (replace {0 1} digits)]

    ; Then get the product
    (apply * replaced)))
\$\endgroup\$
2
\$\begingroup\$

MATL, 5 bytes

!UXzp

Input is taken as a string

Try it at MATL Online! Or verify test cases in Try It Online!

Explanation

!     % Implicit input: string (row vector of chars). Transpose into
      % a column vector of chars
U     % Convert from string to number. Treats each row independently,
      % producing a column vector of numbers
Xz    % Keep only nonzeros
p     % Product. Implicit display
\$\endgroup\$
2
\$\begingroup\$

Befunge, 23 22 bytes

1<*_$#`.#0@#:+!:-"0"~$

Try it online!

Explanation

1<                        Push 1, turn back left, and push a second 1.       
                     $    Drop one of them, leaving a single 1, the initial product.

                -"0"~     Read a char and subtract ASCII '0', converting to a number.
             +!:          If it's 0, make it 1 (this is n + !n).
      `  0  :             Then test if it's greater than 0, to check for EOF.
   _                      If it is greater than 0, it wasn't EOF, so we continue left.
  *                       Multiply with the current product, becoming the new product.
1<                        Now we repeat the loop, but this time push only a single 1...
                     $    ...which is immediately dropped, leaving the current product.

   _                      On EOF, the input value will be negative, so we branch right.
    $                     We don't need the input, so drop it.
       .  @               Leaving us with the product, which we output, then exit.
\$\endgroup\$
2
\$\begingroup\$

JavaScript (Node.js), 36 33 bytes

Simple Javascript (ES6) method that takes input as number string, spreads it into an array, then reduces it through multiplication or returns the value if the result is 0.

3 bytes saved thanks to Shaggy

s=>[...s].reduce((a,b)=>b*a||a,1)

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Save 3 bytes by taking input as a string. \$\endgroup\$ – Shaggy Jan 16 '18 at 8:18
  • \$\begingroup\$ I don't know why I thought it had to be converted, thanks :D \$\endgroup\$ – Wilson Johnson Reta232 Jan 16 '18 at 15:27
2
\$\begingroup\$

Ruby, 42 40 35 32 27 bytes

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

Assumes no newlines in input Major influence

-2 bytes thanks to @GolfWolf

-5 bytes thanks to @Conor O'Brien

\$\endgroup\$
  • \$\begingroup\$ Even shorter than tr: 32 bytes \$\endgroup\$ – Cristian Lupascu Jan 16 '18 at 6:50
  • \$\begingroup\$ @GolfWolf Clever :) \$\endgroup\$ – Håvard Nygård Jan 16 '18 at 7:19
  • \$\begingroup\$ Might your perhaps use * to join? p eval (gets.chars-[?0])*?* ? \$\endgroup\$ – Conor O'Brien Jan 16 '18 at 23:20
2
\$\begingroup\$

Java (OpenJDK 8), 45 bytes

s->s.chars().reduce(1,(a,b)->b<49?a:a*(b-48))

Try it online!

\$\endgroup\$
2
\$\begingroup\$

C#, 97 Bytes (First code golf)

static int X(int y){var z=y.ToString();int r=1;foreach(var q in z){if(q!=48){r*=q-48;}}return r;}

Not sure if i had to wrap it in a method or not so just included it to be safe.

Takes an Int in, converts it to a string and returns the multiple of each of the characters ignoring 0's. Had to minus 48 due to the program using the ascii value as it reads it as a char.

\$\endgroup\$
  • 2
    \$\begingroup\$ Welcome to PPCG! I no nothing of C#, but this should help you understand the rules for golfing in it. \$\endgroup\$ – H.PWiz Mar 1 '18 at 17:00
  • \$\begingroup\$ Thanks @H.PWiz I really am starting to love these little challenges, definitely making me change my regular programming to be more concise and efficient. \$\endgroup\$ – James m Mar 15 '18 at 11:47
  • \$\begingroup\$ Welcome and nice first try :D Some tips for your answer: you can remove the var z=y.ToString(); and place it directly in the foreach, like so: foreach(var q in y.ToString()); and to get the result you can save more bytes by replacing {if(q!=48){r*=q-48;}} with r*=(q>48?q:1);, shaving off the brackets and the if. \$\endgroup\$ – auhmaan Sep 23 at 16:56
2
\$\begingroup\$

C# (Visual C# Interactive Compiler), 46 bytes

i.Select(c=>c>48?c-48:1).Aggregate((p,c)=>p*c)

Try it online!

\$\endgroup\$
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\$
  • \$\begingroup\$ Also 36 \$\endgroup\$ – H.PWiz Jan 15 '18 at 20:56
1
\$\begingroup\$

Jelly, 6, 5 bytes

ṢU×\Ṁ

Try it online!

\$\endgroup\$
  • \$\begingroup\$ 5 mins, not bad! \$\endgroup\$ – FantaC Jan 15 '18 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 '18 at 20:34
  • 5
    \$\begingroup\$ Multiplicative root with ṢUṀ \$\endgroup\$ – Uriel Jan 15 '18 at 20:44
1
\$\begingroup\$

><>, 19 bytes

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

Try it online!

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