The Non-Zero Digital Product Challenge

26

0

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!

FantaC

Posted 2018-01-15T20:16:27.720

Reputation: 1 425

5I'd rather call this non-zero digital product. "root" suggests it reduces to a single digit, which isn't always true here. – Erik the Outgolfer – 2018-01-15T20:46:32.520

1Can we take input as a string? Or (pushing it) an array of digits? – Shaggy – 2018-01-15T21:19:57.523

@EriktheOutgolfer Yes, however, if you repeat the process enough times, it does appear to always go to a single digit.

– James – 2018-01-15T21:21:17.840

You can take quoted input, but no, you can't take a pre-parsed list of digits if that's what you're asking – FantaC – 2018-01-15T21:21:31.390

This seems like a variation on the persistence of a number.

– boboquack – 2018-01-15T22:59:10.443

7If 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). – Kevin Cruijssen – 2018-01-16T08:27:52.237

Answers

3

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!

mudkip201

Posted 2018-01-15T20:16:27.720

Reputation: 833

Surprised that this relatively new golfing lang is the only one that appears to be capable of solving this challenge in 3 bytes! – ETHproductions – 2018-01-15T21:55:12.560

I was surprised by that too! – mudkip201 – 2018-01-15T23:58:07.780

I didn't see your answer when I first accepted, but this is the shortest one! – FantaC – 2018-02-17T17:24:30.423

11

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.

totallyhuman

Posted 2018-01-15T20:16:27.720

Reputation: 15 378

9

Python 2, 34 bytes

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

Try it online!

Dennis

Posted 2018-01-15T20:16:27.720

Reputation: 196 637

7

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

caird coinheringaahing

Posted 2018-01-15T20:16:27.720

Reputation: 13 702

@tfbninja Calls the main link with each of the inputs – caird coinheringaahing – 2018-01-15T20:41:35.903

6

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
                                      ))

Giuseppe

Posted 2018-01-15T20:16:27.720

Reputation: 21 077

So this is how to codegolf with R... Nice one ;) Still trying to figure out how this one works though! – Florian – 2018-01-20T09:23:04.740

1@Florian I've added a more verbose explanation. – Giuseppe – 2018-01-20T15:01:16.603

That's a new way to split digits that I'll have to try! – BLT – 2018-03-01T13:56:15.887

@BLT that's one of my tips for golfing in R!

– Giuseppe – 2018-03-01T14:01:51.217

5

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!

Steadybox

Posted 2018-01-15T20:16:27.720

Reputation: 15 798

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. – tomsmeding – 2018-01-16T23:34:51.060

1

@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.

– Steadybox – 2018-01-16T23:40:16.170

You might want to specify the exact version of GCC it works with, for future proofing. – moonheart08 – 2018-03-01T14:32:28.963

@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. – Steadybox – 2018-03-02T20:13:29.893

5

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

Jo King

Posted 2018-01-15T20:16:27.720

Reputation: 38 234

1You can golf two more bytes by computing the negation of the actual digit, then counting up to 0 instead of down to 0. – Nitrodon – 2018-01-18T05:21:04.920

4

05AB1E, 4 bytes

0KSP

Try it online!

Explanation

0K     # remove zeroes
  S    # split to list of digits
   P   # product

Emigna

Posted 2018-01-15T20:16:27.720

Reputation: 50 798

I accepted this answer because it was a four way tie between Jelly, husk, and 05AB1E, and you answered first. – FantaC – 2018-01-29T02:05:06.163

4

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).

cole

Posted 2018-01-15T20:16:27.720

Reputation: 3 526

1

You can save a byte by changing +0=] to *#] Try it online

– Galen Ivanov – 2018-01-16T08:18:54.240

1[:*/0-.~,.&.": for 14 bytes. Try it online – Galen Ivanov – 2018-01-16T12:22:30.217

@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! – cole – 2018-01-16T16:30:25.337

11>. does the job of 0-.~ for a byte less. [:*/1>.,.&.": Try it! – Galen Ivanov – 2018-01-16T18:25:48.153

3

Python 2, 43 bytes

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

Try it online!

Rod

Posted 2018-01-15T20:16:27.720

Reputation: 17 588

3

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!

Steadybox

Posted 2018-01-15T20:16:27.720

Reputation: 15 798

@(n)prod((k=n-48)+~k) – alephalpha – 2018-01-20T07:35:47.953

3

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

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

Try it online!

Dennis

Posted 2018-01-15T20:16:27.720

Reputation: 196 637

3

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

Arnauld

Posted 2018-01-15T20:16:27.720

Reputation: 111 334

3

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.

Fatalize

Posted 2018-01-15T20:16:27.720

Reputation: 32 976

3

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.

Kevin Cruijssen

Posted 2018-01-15T20:16:27.720

Reputation: 67 575

1you can save parens like this: long f(long n){return n>0?(n%10>0?n%10:1)*f(n/10):1;} – RiaD – 2018-01-16T10:16:35.197

1

Sorry, I'm claiming this one (45 bytes) because the algorithm is totally different ;-)

– Olivier Grégoire – 2018-01-17T13:45:58.487

3

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

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

Try it online!

Xcali

Posted 2018-01-15T20:16:27.720

Reputation: 7 671

3

Julia 0.6, 26 bytes

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

Example of use:

julia> !54
20

Try it online!

Lyndon White

Posted 2018-01-15T20:16:27.720

Reputation: 1 021

could you add an example of how to call this, as well as a byte count? you can use TIO!

– Giuseppe – 2018-01-17T14:56:47.793

@Giuseppe oops, I got distracted. I counted the length but didn't add it. Huh TIO supports julia now. Neat. – Lyndon White – 2018-01-17T15:15:49.953

In fact, TIO supports Julia 0.4-0.6! very nice, +1. – Giuseppe – 2018-01-17T15:22:10.623

3

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

zworek

Posted 2018-01-15T20:16:27.720

Reputation: 31

2

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!

James

Posted 2018-01-15T20:16:27.720

Reputation: 54 537

174 bytes – Jo King – 2018-01-16T02:06:26.280

I literally forgot I posted that comment, and rewrote it from scratch. I'm just going to post separately – Jo King – 2018-01-18T01:15:21.020

2

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)))

Carcigenicate

Posted 2018-01-15T20:16:27.720

Reputation: 3 295

2

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

Håvard Nygård

Posted 2018-01-15T20:16:27.720

Reputation: 341

Even shorter than tr: 32 bytes

– Cristian Lupascu – 2018-01-16T06:50:43.703

@GolfWolf Clever :) – Håvard Nygård – 2018-01-16T07:19:19.517

Might your perhaps use * to join? p eval (gets.chars-[?0])*?* ? – Conor O'Brien – 2018-01-16T23:20:25.817

2

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!

Wilson Johnson Reta232

Posted 2018-01-15T20:16:27.720

Reputation: 41

Save 3 bytes by taking input as a string. – Shaggy – 2018-01-16T08:18:43.700

I don't know why I thought it had to be converted, thanks :D – Wilson Johnson Reta232 – 2018-01-16T15:27:09.733

2

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

Luis Mendo

Posted 2018-01-15T20:16:27.720

Reputation: 87 464

2

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.

James Holderness

Posted 2018-01-15T20:16:27.720

Reputation: 8 298

2

Java (OpenJDK 8), 45 bytes

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

Try it online!

Olivier Grégoire

Posted 2018-01-15T20:16:27.720

Reputation: 10 647

2

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.

James m

Posted 2018-01-15T20:16:27.720

Reputation: 41

2

Welcome to PPCG! I no nothing of C#, but this should help you understand the rules for golfing in it.

– H.PWiz – 2018-03-01T17:00:52.327

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. – James m – 2018-03-15T11:47:32.600

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. – auhmaan – 2019-09-23T16:56:15.503

2

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

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

Try it online!

auhmaan

Posted 2018-01-15T20:16:27.720

Reputation: 906

1

Jelly, 6, 5 bytes

ṢU×\Ṁ

Try it online!

James

Posted 2018-01-15T20:16:27.720

Reputation: 54 537

5 mins, not bad! – FantaC – 2018-01-15T20:26:12.140

DTịDP would save a byte, but there are better ways to strip zeroes or replace them with something else. – Dennis – 2018-01-15T20:34:33.697

5Multiplicative root with ṢUṀ – Uriel – 2018-01-15T20:44:08.153

1

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!

Cristian Lupascu

Posted 2018-01-15T20:16:27.720

Reputation: 8 369

Also 36 – H.PWiz – 2018-01-15T20:56:12.497

1

APL (Dyalog), 11 7 bytes

4 bytes saved thanks to @EriktheOutgolfer

×/0~⍨⍎¨

Try it online!

Uriel

Posted 2018-01-15T20:16:27.720

Reputation: 11 708

7 bytes (although I doubt you can take the number as a string, but then still 9 bytes) – Erik the Outgolfer – 2018-01-15T21:13:01.653

1

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.

Chas Brown

Posted 2018-01-15T20:16:27.720

Reputation: 8 959

f(n/10,n%10*v or v) saves 2 bytes. – Lynn – 2018-01-15T21:08:26.267

1

><>, 19 bytes

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

Try it online!

Emigna

Posted 2018-01-15T20:16:27.720

Reputation: 50 798

1

Add++, 12 bytes

L,EDBFEZB]B*

Try it online!

caird coinheringaahing

Posted 2018-01-15T20:16:27.720

Reputation: 13 702

1

Clean, 55 bytes

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

Try it online!

Οurous

Posted 2018-01-15T20:16:27.720

Reputation: 7 916

1

APL+WIN, 9 bytes

×/(⍎¨⎕)~0

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

Graham

Posted 2018-01-15T20:16:27.720

Reputation: 3 184

1

Japt, 5 bytes

ì f ×

Test it here


Explanation

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

Shaggy

Posted 2018-01-15T20:16:27.720

Reputation: 24 623

1

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 (/) 

streetster

Posted 2018-01-15T20:16:27.720

Reputation: 3 635

1

Forth (gforth), 62 bytes

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

Try it online!

reffu

Posted 2018-01-15T20:16:27.720

Reputation: 1 361

1

Lua, 45 bytes

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

Try it online!

Jonathan S.

Posted 2018-01-15T20:16:27.720

Reputation: 423

1

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

KarlKastor

Posted 2018-01-15T20:16:27.720

Reputation: 2 352

1

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>

Shaggy

Posted 2018-01-15T20:16:27.720

Reputation: 24 623

1

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)
}

Brad Gilbert b2gills

Posted 2018-01-15T20:16:27.720

Reputation: 12 713

1

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.)

Neil

Posted 2018-01-15T20:16:27.720

Reputation: 95 035

1

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[_]]}

Conor O'Brien

Posted 2018-01-15T20:16:27.720

Reputation: 36 228

1

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

Wildcard

Posted 2018-01-15T20:16:27.720

Reputation: 153

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. – ბიმო – 2018-01-16T09:00:02.297

@BMO thanks! And I don’t know if this is maximally golfed; it’s pretty straightforward implementation. – Wildcard – 2018-01-16T09:01:31.280

You might be able to get rid of the first macro and 0=c with this tip, but I haven't tried myself.

– ბიმო – 2018-01-16T09:10:10.293

1

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

Jarom C

Posted 2018-01-15T20:16:27.720

Reputation: 11

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. – Engineer Toast – 2018-01-18T13:11:41.000

1

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

ბიმო

Posted 2018-01-15T20:16:27.720

Reputation: 15 345

1

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

david

Posted 2018-01-15T20:16:27.720

Reputation: 51

1

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!

Galen Ivanov

Posted 2018-01-15T20:16:27.720

Reputation: 13 815

1

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.

Giuseppe

Posted 2018-01-15T20:16:27.720

Reputation: 21 077

1

Julia 0.6, 33 bytes

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

Try it online!

gggg

Posted 2018-01-15T20:16:27.720

Reputation: 1 715

1

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

Dave

Posted 2018-01-15T20:16:27.720

Reputation: 432

1

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!

kakkarot

Posted 2018-01-15T20:16:27.720

Reputation: 269

Smaller is n=>n.Select(c=>c-'0').Aggregate(1,(a,b)=>a*(b==0?1:b)); You ought to include the terminating ';' – user230118 – 2018-01-19T00:36:26.220

Following @user230118 suggestion, you can shrink it more by replacing '0' with 48, and (b==0?1:b) with (b>0?b:1) – auhmaan – 2019-09-23T16:50:31.707

1

Pari/GP, 34 bytes

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

Try it online!

alephalpha

Posted 2018-01-15T20:16:27.720

Reputation: 23 988

1

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

Steven H.

Posted 2018-01-15T20:16:27.720

Reputation: 2 841

1

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)).

DLosc

Posted 2018-01-15T20:16:27.720

Reputation: 21 213

1

Jelly, 4 bytes

Dḟ0P

Try it online!

Dḟ0P    main link

D       int to dec
 ḟ0     filter out 0
   P    product of list

chromaticiT

Posted 2018-01-15T20:16:27.720

Reputation: 211

1

Ruby + -n, 25 bytes

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

Try it online!

Ruby (vanilla), 27 bytes

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

Try it online!

Asone Tuhid

Posted 2018-01-15T20:16:27.720

Reputation: 1 944

Using ruby -n you can use $_ instead of gets for -2! – Dom Hastings – 2018-03-01T12:19:14.100

@DomHastings Thanks, I'm pretty sure that flag still counts for 1 byte though – Asone Tuhid – 2018-03-01T12:36:28.647

I believe the new consensus is Ruby + -n is counted as a different lang without the +1 for -n. Meta

– Dom Hastings – 2018-03-01T13:23:03.743

@DomHastings it's a proposal but I'm not going to argue with fewer bytes

– Asone Tuhid – 2018-03-01T13:45:29.617

1

Befunge-98 (PyFunge), 14 bytes

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

Try it online!

MildlyMilquetoast

Posted 2018-01-15T20:16:27.720

Reputation: 2 907

1

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

Weijun Zhou

Posted 2018-01-15T20:16:27.720

Reputation: 3 396

1

Java 8, 52 bytes

n->(n+"").chars().reduce(1,(x,y)->x*=(y-=48)>0?y:1);

Try it online!
Obligatory stream answer.

Benjamin Urquhart

Posted 2018-01-15T20:16:27.720

Reputation: 1 262

0

PHP, 52 Bytes

$t=1;foreach(array_filter(str_split($n))as$b)$t*=$b;

th3pirat3

Posted 2018-01-15T20:16:27.720

Reputation: 271

0

tinylisp, 67 bytes

(load library
(d f(q((N)(i N(*(i(mod N 10)(mod N 10)1)(f(/ N 10)))1

Try it online!

Explanation + ungolfed

The function f computes the non-zero digit product of its argument N. It uses a divmod algorithm to process the digits: If N is nonzero, it computes (N mod 10 if N mod 10 is nonzero, 1 otherwise), and multiplies that quantity by the result of recursing on N divided by 10. Once N becomes zero, all the digits have been processed and we return 1.

(load library)

(def digit-product
 (lambda (num)
  (if num
   (*
    (if (mod num 10) (mod num 10) 1)
    (digit-product (/ num 10)))
   1)))

This implementation commits the cardinal sin of not using tail recursion. It's not a problem for the size of number this challenge requires us to handle, but for big enough numbers, we would eventually hit the max recursion depth. Here's a proper tail-recursive implementation (with helper function) in 83 bytes:

(load library
(d _(q((N P)(i N(_(/ N 10)(*(i(mod N 10)(mod N 10)1)P))P
(q((N)(_ N 1

Try it online!

Ungolfed:

(load library)

(def _digit-product
 (lambda (num accum)
  (if num
   (_digit-product
    (/ num 10)
    (*
     (if (mod num 10) (mod num 10) 1)
     accum))
   accum)))

(lambda (num) (_digit-product num 1))

DLosc

Posted 2018-01-15T20:16:27.720

Reputation: 21 213