El desafío del producto digital distinto de cero


26

Originalmente la raíz digital multiplicativa

Reto

Básicamente haz lo que dice el título

Método

Dado un entero positivo 1 <= N <= 100000000 a través de uno de nuestros métodos de entrada estándar , multiplique cada dígito, ignorando los ceros.

Ej .: toma un número y di 361218402:

  • 3* 6=18
  • 18* 1=18
  • 18* 2=36
  • 36* 1=36
  • 36* 8=288
  • 288* 4=1152
  • 1152* 1 (ignore los ceros o conviértalos en unos) =1152
  • 1152* 2=2304

La salida para 361218402es2304

Casos de prueba

1 => 1
cada dos dígitos> 0 => sí mismo
10 => 1
20 => 2
100 => 1
999 => 729
21333 => 54
17801 => 56
4969279 => 244944
100000000 => 1

Las lagunas estándar no están permitidas, y este es el , por lo que gana el conteo de bytes más corto.

¡Enhorabuena a Jo King que obtuvo la recompensa con su respuesta de 70 bytes!


55
Prefiero llamar a este producto digital distinto de cero . "root" sugiere que se reduce a un solo dígito, lo cual no siempre es cierto aquí.
Erik the Outgolfer

1
¿Podemos tomar la entrada como una cadena? ¿O (empujándolo) una serie de dígitos?
Shaggy

@EriktheOutgolfer Sí, sin embargo, si repite el proceso suficientes veces , parece que siempre va a un solo dígito.
DJMcMayhem

Puede tomar la entrada citada, pero no, no puede tomar una lista de dígitos previamente analizada si eso es lo que está preguntando
FantaC

77
Si tenemos que soportar un máximo de 100000000000, sugiero el caso de prueba 99999999999 => 31381059609, ya que no cabe en un entero predeterminado de 32 bits. Quizás sea mejor reducir la salida máxima a un máximo de 32 bits (2147483647).
Kevin Cruijssen

Respuestas:


3

Pyt , 3 bytes

ąžΠ

Explicación:

ą       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

Pruébalo en línea!


¡Sorprendido de que este idioma de golf relativamente nuevo sea el único que parece ser capaz de resolver este desafío en 3 bytes!
ETHproductions

¡También me sorprendió eso!
mudkip201

No vi tu respuesta cuando acepté por primera vez, ¡pero esta es la más corta!
FantaC

11

Haskell , 27 bytes

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

Pruébalo en línea!

Ungolfed con UniHaskell y-XUnicodeSyntax

import UniHaskell

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

Explicación

Comenzaré con lo que tenía inicialmente:

product.map(max 1.read.pure)

Esta es una expresión sin puntos que se evalúa como una función que toma una cadena (o una lista de caracteres) s ( "301") como argumento. Se asigna max 1.read.puresobre s , esencialmente tomando cada carácter i , inyectándolo en una lista (lo que lo convierte en una cadena) ( ["3", "0", "1"]), luego lo lee, lo que evalúa la cadena ( [3, 0, 1]) y finalmente toma el mayor de i y 1 ( [3, 1, 1]). Luego toma la productlista resultante de enteros ( 3).

Luego lo jugué por un byte con:

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

Esto funciona porque productes equivalente a foldr (*) 1. En lugar de mapear y doblar, combiné los dos doblando con lo (*).max 1.read.pureque toma cada dígito distinto de cero y lo multiplica con el acumulador.




6

R , 40 bytes

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

Pruébalo en línea!

Como se garantiza que la entrada no tiene más de 12 dígitos, esto debería funcionar bien. Calcula los dígitos como x(incluidos los ceros iniciales), luego reemplaza los ceros con 1y calcula el producto.

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

Así que así es como codegolf con R ... Nice one;) ¡Todavía estoy tratando de descubrir cómo funciona este!
Florian

1
@ Florian He agregado una explicación más detallada.
Giuseppe

¡Esa es una nueva forma de dividir dígitos que tendré que probar!
BLT


5

C (gcc) , 39 bytes

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

Necesita compilarse sin optimizaciones (que es la configuración predeterminada para gcc, de todos modos).

Pruébalo en línea!


Que k=k;poner ken el registro de retorno accidentalmente es simplemente malvado. Usted debe probablemente añadir que esto sólo funciona sin optimizaciones, posiblemente, sólo en x86 / x64. +1.
tomsmeding

1
@tomsmeding Algo sorprendentemente, funciona en arquitecturas distintas a x86 . Sin optimizaciones ( O0) es el valor predeterminado para gcc, por lo que no hay necesidad de usar explícitamente ese indicador. Creo que de todos modos agregaré una mención a la publicación.
Steadybox

Es posible que desee especificar la versión exacta de GCC con la que funciona, para futuras pruebas.
moonheart08

@ moonheart08 Dudo que deje de funcionar después de alguna versión. De todos modos, funciona con la última versión, por lo que el tiempo de publicación se puede utilizar para encontrar una versión con la que al menos funcione.
Steadybox

5

Brain-Flak , 74 72 70 bytes

-2 gracias a Nitrodon por sugerir obtener la negación del número para que solo tenga que aumentar en lugar de disminuir más adelante

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

Pruébalo en línea!

Puede haber algunas formas de jugar más al golf, como rehacer la multiplicación para evitar tener que inicializar el total con 1. (-2 bytes)

Cómo funciona:

{ 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

1
Puede jugar golf dos bytes más calculando la negación del dígito real, luego contando hasta 0 en lugar de hasta 0.
Nitrodon

4

05AB1E , 4 bytes

0KSP

Pruébalo en línea!

Explicación

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

Acepté esta respuesta porque era un vínculo de cuatro vías entre Jelly, husk y 05AB1E, y tú respondiste primero.
FantaC

4

J , 17 14 13 bytes

-4 bytes cortesía de @GalenIvanov

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

Pruébalo en línea!

Probablemente se pueda mejorar algo. Editar: y así fue.

Explicación

[: */ 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 es un ingenioso adverbio que aplica el verbo a la derecha, luego el verbo a la izquierda, luego el inverso del verbo a la derecha. También convertir de nuevo a números es técnicamente usando eval ( ".-do).


1
Puede guardar un byte cambiando +0=]a *#] Probar en línea
Galen Ivanov

1
[:*/0-.~,.&.":por 14 bytes. Pruébelo en línea
Galen Ivanov el

@GalenIvanov ¡Sabía que signum sería útil! Mi pensamiento original era (+-.@*), supongo que me inclino a agregar. Intenté usar '0'-.~asumiendo una entrada de una cadena, no estoy seguro de por qué no se me ocurrió hacerlo en los dígitos divididos. ¡Gracias!
cole

1
1>.hace el trabajo de 0-.~un byte menos. [:*/1>.,.&.": ¡Intentalo!
Galen Ivanov


3

JavaScript (ES6), 28 bytes

Diseñado para enteros de 32 bits.

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

Casos de prueba



3

Brachylog , 5 bytes

⊇ẹ×ℕ₁

Pruébalo en línea!

Explicación

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

Esto funciona porque unifica desde subconjuntos grandes a subconjuntos pequeños, por lo que el primero que dará como resultado un producto distinto de cero es cuando se excluyen todos los ceros y nada más.



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

Puerto de @Dennis 'Python 2 respuesta .
-1 byte gracias a @RiaD .

Pruébalo aquí

55 Versión de 54 bytes:

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

Pruébalo en línea.


1
puede salvar a los padres de esta manera:long f(long n){return n>0?(n%10>0?n%10:1)*f(n/10):1;}
RiaD

1
Lo siento, estoy reclamando este (45 bytes) porque el algoritmo es totalmente diferente ;-)
Olivier Grégoire

3

Julia 0.6, 26 bytes

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

Ejemplo de uso:

julia> !54
20

Pruébalo en línea!


¿podría agregar un ejemplo de cómo llamar a esto, así como un recuento de bytes? puedes usar TIO !
Giuseppe

@Giuseppe oops, me distraje. Conté la longitud pero no la agregué. Huh TIO ahora apoya a Julia. Ordenado.
Lyndon White

De hecho, TIO es compatible con Julia 0.4-0.6. muy agradable, +1.
Giuseppe

3

JavaScript (Node.js) , 30 bytes

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

Pruébalo en línea!

Toma una cadena como entrada, la trata como una matriz y, mediante la desestructuración de la matriz, se separa el primer elemento [a,...b]. +a||1Devuelve el dígito correspondiente al acarácter. Supongo que el descanso se explica por sí mismo.



2

Brain-Flak , 88 bytes

Versión legible:

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

Pruébalo en línea!



Literalmente olvidé que publiqué ese comentario y lo reescribí desde cero. Solo voy a publicar por separado
Jo King

2

Clojure , 56 bytes

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

Bastante básico Convierte el número en una cadena, luego resta 48 de cada carácter para volverlos a convertir en números. Luego reemplaza cada 0 con un 1, y aplica* a la lista de números resultante (que se reduce *sobre la lista). Puede aceptar un número o un número en cadena.

Pruébalo en línea!

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


2

Befunge, 23 22 bytes

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

Pruébalo en línea!

Explicación

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.

2

JavaScript (Node.js) , 36 33 bytes

Método Javascript simple (ES6) que toma la entrada como una cadena de números, la distribuye en una matriz y luego la reduce a través de la multiplicación o devuelve el valor si el resultado es 0.

3 bytes guardados gracias a Shaggy

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

Pruébalo en línea!


Ahorre 3 bytes tomando la entrada como una cadena.
Shaggy

No sé por qué pensé que tenía que ser convertido, gracias: D
Wilson Johnson Reta232



2

C # , 97 Bytes (primer código de 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;}

No estoy seguro si tuve que envolverlo en un método o no, así que solo lo incluí para que sea seguro.

Toma un Int, lo convierte en una cadena y devuelve el múltiplo de cada uno de los caracteres ignorando los 0. Tuvo que menos 48 debido a que el programa usa el valor ascii ya que lo lee como un char.


2
Bienvenido a PPCG! No tengo nada de C #, pero esto debería ayudarlo a comprender las reglas para jugar golf en él.
H.PWiz

Gracias @ H.PWiz Realmente estoy empezando a amar estos pequeños desafíos, definitivamente haciéndome cambiar mi programación regular para ser más conciso y eficiente.
James m

Bienvenido y buen primer intento: D Algunos consejos para su respuesta: puede quitar el var z=y.ToString();y colocarlo directamente en el foreach, así: foreach(var q in y.ToString()); y para obtener el resultado, puede guardar más bytes reemplazándolos {if(q!=48){r*=q-48;}}con r*=(q>48?q:1);, quitando los corchetes y el if.
auhmaan




Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.