Reduce un número por su dígito más grande

33

Tarea:

Dado un número entero en el sistema de números decimales, reduzca a un solo dígito decimal de la siguiente manera:

  1. Convierta el número en una lista de dígitos decimales.
  2. Encuentra el dígito más grande, D
  3. Eliminar D de la lista. Si hay más de una aparición de D, elija la primera desde la izquierda (en la posición más significativa), todas las demás deben permanecer intactas.
  4. Convierta la lista resultante en un número decimal y multiplíquelo por D.
  5. Si el número es mayor que 9 (tiene más de 1 dígito decimal), repita todo el procedimiento, ingresando el resultado. Deténgase cuando obtenga un resultado de un solo dígito.
  6. Muestra el resultado.

Ejemplo:

26364 -> 
1. 2 6 3 6 4 
2. The largest digit is 6, so D=6
3. There are two occurrences or 6: at positions 1 and 3 (0-based). We remove the left one,
    at position 1 and get the list 2 3 6 4 
4. we convert the list 2 3 6 4 to 2364 and multiply it by D:
   2364 * 6 = 14184
5. 14184 is greater than 9 so we repeat the procedure, feeding 14184 into it.

Continuamos repitiendo el procedimiento para 14184 y así sucesivamente y pasamos por los siguientes resultados intermedios, llegando finalmente a 8:

11312
3336
1998
1782
1376
952
468
368
288
224
88
64
24
8

Entonces el resultado para 26364 es 8.

Entrada: un entero / una cadena que representa un entero

Salida: un solo dígito, el resultado de la reducción aplicada al número.

Casos de prueba:

9 -> 9
27 -> 4
757 -> 5
1234 -> 8
26364 -> 8
432969 -> 0
1234584 -> 8
91273716 -> 6

Este es el , por lo que ganan las respuestas más cortas en bytes en cada idioma.

Galen Ivanov
fuente
3
Cuál es si el número es mayor que 10 o tiene más de 1 dígito decimal . El número 10 tiene más de 1 dígito decimal, pero no es más grande que diez.
Adám
@ Adám Al codificar las lógicas, ¿entonces debería 10 -> 10?
Ian H.
1
@ Adám Tienes razón, debería haber escrito "más grande que 9". Voy a editar la descripción. ¡Gracias!
Galen Ivanov
¿Alguien ha examinado el histograma de esta función para regiones suficientemente grandes? Parece tener muchos ceros; También obtuve muchos 8 mientras componía los casos de prueba.
Galen Ivanov
2
Además, un número aleatorio divisible por 4 tiene una probabilidad de 3/5 de que el producto de los dos últimos dígitos sea divisible por 8.
Ørjan Johansen

Respuestas:

18

05AB1E , 6 bytes

Código:

[Dg#à*

Utiliza la codificación 05AB1E . Pruébalo en línea!

Explicación

[Dg#     # While the length of the number is not 1
    à    # Extract the largest element from the current number
     *   # Multiply it with the leftover number
Adnan
fuente
11

JavaScript (ES6), 49 bytes

f=n=>n>9?f(""+n.replace(m=Math.max(...n),"")*m):n

Toma la entrada como una representación de cadena de un entero, como f("26364").

Casos de prueba

Justin Mariner
fuente
6

Pyth , 16 bytes

.WtH`*s.-ZKeSZsK

Toma la entrada como una cadena. Pruébalo aquí! (Alternativa: .WtH`*s.-ZeSZseS)

Pyth , 18 bytes

.WgHT*s.-`ZKeS`ZsK

Toma la entrada como un entero. Pruébalo aquí!

Cómo funciona

16 byter

.WtH` * s.-ZKeSZsK ~ Programa completo.

.W ~ Funcional mientras. Mientras que A (valor) es verdadero, valor = B (valor).
                 ~ Se devuelve el valor final.
  tH ~ A, condición: ¿Es verdadero el valor [1:]? ¿Es la longitud ≥ 2?
    `* s.-ZKeSZsK ~ B, setter.
       .- ~ Sustracción en bolsa, utilizada para eliminar el dígito más alto, con ...
         Z ~ El valor actual Z, y ...
          KeSZ ~ El dígito más alto de Z (como una cadena). También se asigna a una variable K.
      s ~ Fundido a un entero.
     * ~ Multiplicado por ...
              sK ~ El dígito más alto.
    `~ Convertir a una cadena.

18 byter

.WgHT * s.-`ZKeS`ZsK ~ Programa completo.

.W ~ Funcional mientras. Mientras que A (valor) es verdadero, valor = B (valor).
                   ~ Se devuelve el valor final.
  gHT ~ A, condición: ¿es el valor (H) ≥ 10?
     * s.-`ZKeS`ZsK ~ B, setter.
       .- ~ Substracción en bolsa (utilizada para eliminar la primera aparición).
         `Z ~ La representación de cadena de Z.
           KeS`Z ~ Y el carácter más alto (lexicográficamente) de Z (dígito más alto).
                     También lo asigna a una variable llamada K.
      s ~ Transmitir a entero.
     * ~ Multiplicar por ...
                sK ~ K fundido a int.

Estar tan cerca de Jelly en este tipo de desafío es muy bueno para Pyth IMO :-)

Sr. Xcoder
fuente
6

Casco , 14 13 12 bytes

Gracias Zgarb por guardar 1 byte.

Ω≤9oṠS*od-▲d

Pruébalo en línea!

Explicación:

Ω≤9            Repeat the following function until the result is ≤ 9
           d     Convert to a list of digits
         -▲      Remove the largest one
       od        Convert back to an integer
   oṠS*          Multiply by the maximum digit
H.PWiz
fuente
12 bytes con algo de reorganización.
Zgarb
@ Zgarb Gracias, estaba buscando algo así.
H.PWiz
6

R , 99 95 bytes

f=function(x)"if"(n<-nchar(x)-1,f(10^(n:1-1)%*%(d=x%/%10^(n:0)%%10)[-(M=which.max(d))]*d[M]),x)

Pruébalo en línea!

Una función recursiva. Agregar f(number)en el pie de página se puede utilizar para probar otros valores de number. Implementación sencilla, des la lista de dígitos y 10^(n:2-2)%*%d[-M]calcula el número con el dígito más grande eliminado.

Giuseppe
fuente
5

Python 2 , 72 bytes

f=lambda n:`n`*(n<=9)or f(int(`n`.replace(max(`n`),'',1))*int(max(`n`)))

Pruébalo en línea!

FlipTack
fuente
1
... Estaba depurando un error tonto en esto . Maldición, me dieron ninja.
totalmente humano
Recibo un error en la entrada 9
RoryT
Esto parece fallar para el caso de prueba 432969. "ValueError: literal no válido para int () con base 10: ''"
James Webster el
@JamesWebster debería repararse ahora.
FlipTack
1
@recursive No, como entonces si nfuera 0 n*(n<=9), todavía se evaluaría a un valor falso, 0, haciendo que la recursión continúe y causando un error, mientras que la cadena '0'es un valor verdadero y, por lo tanto, la recursión se detiene.
FlipTack
4

Ruby , 59 bytes

f=->n{m=n.digits.max;n>9?f[n.to_s.sub(m.to_s,"").to_i*m]:n}

Pruébalo en línea!

Función lambda recursiva llamada like f[26364].

Justin Mariner
fuente
4

Jalea , 15 bytes

D×Ṁ$œṡṀ$FḌµ>9µ¿

Pruébalo en línea! o ver el conjunto de pruebas .

¿Cómo?

D×Ṁ$œṡṀ$FḌµ>9µ¿ - Link: number, n
              ¿ - while:
             µ  - ...condition (monadic):
            9   -    literal 9
           >    -    loop value greater than (9)?
          µ     - ...do (monadic):               e.g. 432969
D               -    convert to a decimal list        [4,3,2,9,6,9]
   $            -    last two links as a monad:
  Ṁ             -      maximum                         9
 ×              -      multiply (vectorises)          [36,27,18,81,54,81]
       $        -    last two links as a monad:
      Ṁ         -      maximum                         81
    œṡ          -      split at first occurrence      [[36,27,18],[54,81]]
        F       -    flatten                          [36,27,18,54,81]
         Ḍ      -    convert from base 10              389421  (i.e. 360000 + 27000 + 1800 + 540 + 81)
Jonathan Allan
fuente
4

Haskell , 70 67 66 bytes

Guardado 3 4 bytes gracias a nimi!

f x|x<10=x|(a,b:c)<-span=<<(>).maximum$show x=f$read[b]*read(a++c)

Pruébalo en línea!

H.PWiz
fuente
Una recursión explícita es más corta que until. Pruébalo en línea! .
nimi
un byte más para guardar: ...span=<<(>).maximum....
nimi
Ooh ... Nice :)
H.PWiz
4

C # (.NET Core) , 126 bytes

int F(int n){var x=(n+"").ToList();var m=x.Max();x.RemoveAt(x.IndexOf(m));return n>9?F(int.Parse(string.Concat(x))*(m-48)):n;}

Pruébalo en línea!

Timmeh
fuente
Bienvenido a PPCG! Puedes eliminar un espacio .
Erik the Outgolfer
@ EriktheOutgolfer Gracias, perdí esa.
Timmeh
1
@totallyhuman Gracias, hasta 137 después de algunas refactorizaciones.
Timmeh
Puede cambiar if(n<10)return n;...return F(...);a un solo retorno con ternary-if, así: int F(int n){var x=(n+"").ToList();var m=x.Max(d=>d);x.RemoveAt(x.IndexOf(m));return n<10?n:F(int.Parse(string.Concat(x))*(m-48));}( 131 bytes )
Kevin Cruijssen
Creo que debe incluir using System.Linq;(18 bytes) en el bytecount.
Ian H.
4

APL (Dyalog) , 36 35 33 bytes

-1 debido a las especificaciones OP actualizadas. -2 gracias a ngn.

Función de prefijo tácito anónimo. Toma un entero como argumento.

{⍵>9:∇(⌈/×10⊥⊂⌷⍨¨⍳∘≢~⊢⍳⌈/)⍎¨⍕⍵⋄⍵}

Pruébalo en línea!

{... }una función donde está el argumento:

⍵>9: si el argumento es mayor que 9, entonces:

  ⍕⍵ formatear (stringify) el argumento

  ⍎¨ ejecutar (evaluar) cada uno (esto nos da los dígitos como números)

  (... ) aplique la siguiente función tácita en aquellos

   ⌈/ el dígito más grande

   × veces

   10⊥ la decodificación de base 10 de (recoge dígitos)

    todos los dígitos

   ⌷⍨¨ indexado por cada uno de

   ⍳∘≢ los i ndices del número de dígitos

    difiere de

   ⊢⍳⌈/ el más grande de dígitos i ndice de toda la lista de dígitos

   recurse (es decir, llamarse a sí mismo) en ese

 más

   devolver el argumento sin modificar

Adán
fuente
No debe >10ser >9?
Erik the Outgolfer
@EriktheOutgolfer Probablemente, pero OP en realidad no está claro (autocontradictorio) sobre eso.
Adám
Eso es cierto, pero >9 ahorraría un byte.
Erik the Outgolfer
@EriktheOutgolfer Actualizado.
Adám
@ Adám ∇ en lugar de ⍣ = para -1 byte: {⍵> 9: ∇ (⌈ / ... ⋄⍵}
ngn
3

Perl 6 ,  45  41 bytes

{($_,{$/=.comb.max;S/"$/"//*$/}...10>*).tail}

Pruébalo

{($_,{S/"{.comb.max}"//*$/}...10>*).tail}

Pruébalo

Expandido:

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

  (  # generate the sequence

      $_,                      # start the sequence with the input

      {                        # generate the rest of the values in the sequence

          S/                   # find and replace (not in-place)
            "{  .comb.max  }"  # find the max digit and match against it
          //                   # replace it with nothing
          *                    # multiply the result with
          $/                   # the digit that was removed
      }

      ...                      # keep generating values until

      10 > *                   # the value is less than 10

  ).tail                       # get the last value from the sequence
}
Brad Gilbert b2gills
fuente
3

Retina , 67 bytes

{1`(..+)?
1$&;$&
O`\G\d
.+((.);.*?)\2
$1
\d+
$*
1(?=.*;(1+))|.
$1
1

Pruébalo en línea! Link incluye los casos de prueba lo suficientemente rápido como para no dañar el servidor de Dennis. Explicación:

{1`(..+)?
1$&;$&

Para números de dos dígitos, esto duplica el número con un ; separador, prefijando un 1 al duplicado. Para números de un dígito, este prefijo 1;al número.

O`\G\d

Ordenar los dígitos del duplicado. (Para números de un dígito, esto no tiene efecto).

.+((.);.*?)\2
$1

Encuentre la primera aparición del dígito más grande y elimínelo, y también los otros dígitos en el duplicado, y el 1 adicional que se agregó anteriormente. (Para números de un dígito, la coincidencia falla, por lo que esto no hace nada).

\d+
$*
1(?=.*;(1+))|.
$1
1

Multiplica el número por el dígito. Para números de un dígito, esto da como resultado el número original y el ciclo termina. De lo contrario, el programa se repite hasta que se alcanza un solo dígito.

Neil
fuente
3

C # (.NET Core) , 177164 + 18 bytes

¡Guardado 13 bytes gracias a @raznagul!

int f(int n){string s=n+"",m=s.Max(d=>d)+"";if(n<10)return n;var x=s.ToList();x.RemoveAt(s.IndexOf(m));int y=int.Parse(string.Join("",x))*int.Parse(m);return f(y);}

Pruébalo en línea!

Ian H.
fuente
Puedes cambiar s.Length<2a n<10. Además, puede eliminar el operador ternario y solo return f(y)al final, ya que el caso se maneja ifen el siguiente paso de la recursión.
raznagul
3

Java 8, 126104 bytes

n->{for(;n>9;n=new Long((n+"").replaceFirst((n=(n+"").chars().max().getAsInt()-48)+"",""))*n);return n;}

-22 bytes gracias a @ OlivierGrégoire .

Explicación:

Pruébalo aquí.

n->{         // Method with long as both parameter and return-type
  for(;n>9;  //  Loop as long as the number contains more than 1 digit
    n=       //   Replace the current number with:
      new Long((n+"").replaceFirst((n=(n+"").chars().max().getAsInt()-48)+"",""))
             //    Remove the first largest digit from the number,
      *n     //    and multiply this new number with the removed digit
  );         //  End of loop
  return n;  //  Return the result
}            // End of method
Kevin Cruijssen
fuente
111 bytes
Olivier Grégoire
1
104 bytes (igual que el anterior, pero iterativo en lugar de recursivo, también: n>9y revierte las condiciones en lugar de n<10).
Olivier Grégoire
2

Jq 1.5 , 86 bytes

until(.<10;"\(.)"|(./""|max)as$v|index($v)as$x|.[:$x]+.[1+$x:]|tonumber*($v|tonumber))

Expandido

until(
    .<10                    # until number is below 10
  ; "\(.)"                  # convert to string
  | (./""|max) as $v        # find largest digit, call it $v
  | index($v) as $x         # find index of digit
  | .[:$x]+.[1+$x:]         # remove digit
  | tonumber*($v|tonumber)  # convert back to number and multiply by $v
)

Pruébalo en línea!

jq170727
fuente
2

Lua, 137108 bytes

function f(n)while n>9 do b="0"g=b.gsub g(n,".",function(m)b=math.max(m,b)end)n=b*g(n,b,"",1)end print(n)end

Gracias a Jonathan S por jugar golf en 29 bytes.

Pruébalo en línea!

MCAdventure10
fuente
1
108 bytes
Jonathan S.
Gracias. Eso parece digno de una respuesta propia: se vinculará a una publicación que realice para él, de lo contrario se editará y acreditará.
MCAdventure10
Solo edítelo. Sigue siendo su código, no lo he escrito desde cero.
Jonathan S.
2

D , 188 186 185 bytes

import std.conv,std.algorithm;T f(T,U=string)(T u){if(u<10)return u;T[]r;u.text.each!(n=>r~=n.to!T-48);T m=r.maxElement;U s;r.remove(r.maxIndex).each!(n=>s~=n.to!U);return f(m*s.to!T);}

Pruébalo en línea!

Odio la evaluación perezosa, mucho. Cualquier consejo es bienvenido!

Zacharý
fuente
2

Lua, 154 Bytes

Debería tener algunas formas de jugar golf, estoy experimentando ahora mismo.

n=...z=table
while n+0>9 do
t={}T={}n=n..''n:gsub(".",function(c)t[#t+1]=c T[#T+1]=c
end)z.sort(t)x=t[#t]z.remove(T,n:find(x))n=z.concat(T)*x
end
print(n)

Pruébalo en línea!

Explicaciones

n=...                    -- define n as a shorthand for the argument
z=table                  -- define z as a pointer to the object table
while n+0>9              -- iterate as long as n is greater than 9
do                       -- n+0 ensure that we're using a number to do the comparison
  t={}                   -- intialise two tables, one is used to find the greatest digit
  T={}                   -- the other one is used to remove it from the string
  n=n..''                -- ensure that n is a string (mandatory after the first loop)
  n:gsub(".",function(c) -- apply an anonymous function to each character in n
               t[#t+1]=c -- fill our tables with the digits
               T[#T+1]=c
             end)        
  z.sort(t)              -- sort t to put the greatest digit in the last index
  x=t[#t]                -- intialise x to the value of the greatest digit
  z.remove(T,n:find(x))  -- remove the first occurence of x from the table T 
                         -- based on its position in the input string
  n=z.concat(T)*x        -- assign the new value to n
end                      -- if it still isn't a single digit, we're looping over again
print(n)                 -- output the answer
Katenkyo
fuente
2

PowerShell , 123 bytes

[Collections.ArrayList]$a=[char[]]"$args"
while(9-lt-join$a){$a.remove(($b=($a|sort)[-1]));$a=[char[]]"$(+"$b"*-join$a)"}$a

Pruébalo en línea!

Ooof Las matrices de PowerShell son inmutables, por lo que debemos usar la larga [Collections.ArrayList]conversión aquí para poder llamar.remove() más tarde.

Toma entrada $args, la convierte en una cadena, luego una charmatriz, luego un ArrayList. Almacena eso en $a. Luego whilegiramos hasta que estamos en o debajo 9. En cada iteración, invocamos .removeel elemento más grande de $a(hecho por sorty tomando el último elemento[-1] ), almacenando el elemento más grande en$b al mismo tiempo. Esto sucede porque los valores ASCII se ordenan de la misma manera que los dígitos literales.

A continuación, volvemos a calcular $a, nuevamente como una charmatriz (e ArrayListimplícitamente), lanzando nuestro $b(que actualmente es a char) a una cadena, luego un int con +, y multiplicando eso por$a -join ed en una cadena (implícitamente convertido a int). Esto satisface la parte "multiplicar por D" del desafío.

Finalmente, una vez que estamos fuera del ciclo, lo colocamos $aen la tubería y la salida es implícita.

AdmBorkBork
fuente
2

Pip , 22 21 bytes

Wa>9a:aRAa@?YMXax*:ya

Toma entrada como argumento de línea de comando. Verifique todos los casos de prueba: ¡ Pruébelo en línea!

Explicación

Sin golf, con comentarios:

                 a is 1st cmdline arg
W a>9 {          While a > 9:
  Y MXa           Yank max(a) into y
  a RA: a@?y ""   Find index of y in a; replace the character at that position with ""
  a *: y          Multiply a by y
}
a                Autoprint a

En la versión de golf, el cuerpo del bucle se condensa en una sola expresión:

a:aRAa@?YMXax*:y
        YMXa      Yank max(a)
     a@?          Find its index in a
  aRA       x     Replace at that index with x (preinitialized to "")
             *:y  Multiply that result by y (using : meta-operator to lower the precedence)
a:                Assign back to a
DLosc
fuente
2

do 103 , 95 , 90 bytes

a,b;t,m;f(n){for(t=m=0,a=b=1e9;a/=10;)if((t=n/a%10)>m)m=t,b=a;n=n>9?f(m*=n/b/10*b+n%b):n;}

Pruébalo en línea!

PrincePolka
fuente
2

Java 8: 115 bytes


-10 bytes gracias a Jo King

Desafortunadamente no se puede llamar a una función lambda de forma recursiva, por lo que se necesitan 11 bytes adicionales para el encabezado del método. Soy consciente de que hay una respuesta Java más corta que se repite en su lugar, pero decidí proponer esto por mi cuenta.

long f(long n){int m=(n+"").chars().max().getAsInt()-48;return n>9?f(new Long((n+"").replaceFirst(""+m,""))*m):n;};

Pruébalo en línea

Benjamin Urquhart
fuente
Puede mover el -48mapa al final de la mdefinición. Pruébalo en línea! También tiene espacio en blanco adicional en su enlace TIO
Jo King
@JoKing gracias.
Benjamin Urquhart
1

J, 40 bytes

((]*<^:3@i.{[)>./)&.(10&#.inv)^:(9&<)^:_

Pruébalo en línea!

explicación

(      iterate                   )^:(9&<)^:_    NB. keep iterating while the number is > 9
 (     stuff         )&.(10&#.inv)              NB. convert to digits, do stuff, convert back to number
 (           )>./)                              NB. stuff is a hook, with max digit >./  on the right
 (]*<^:3@i.{[)                                  NB. so that in this phrase, ] means "max" and [ means "all digits"
  ]                                             NB. the max digit...
   *                                            NB. times...        
    <^:3@                                       NB. triple box...
         i.                                     NB. the first index of the max in the list of all digits
           {                                    NB. "from" -- which because of the triple box means "take all indexes except..."
            [                                   NB. from all the digits of the number
Jonás
fuente
1
Hoy me enteré de la selección de cajas triples, ¡gracias!
Galen Ivanov
1

PowerShell , 230 bytes

$n="$args";do{$n=$n.ToString();$a=@();0..$n.Length|%{$a+=$n[$_]};$g=[convert]::ToInt32(($a|sort|select -last 1),10);[regex]$p=$g.ToString();[int]$s=$p.replace($n,'',1);if($n.Length-eq1){$n;exit}else{$r=$s*$g}$n=$r}until($r-lt10)$r

Pruébalo en línea!

Se desperdicia demasiado en todo el tipo de fundición.

raíz
fuente
1

PHP, 82 77 + 1 bytes

for($n=$argn;$n>9;)$n=join("",explode($d=max(str_split($n)),$n,2))*$d;echo$n;

Ejecutar como tubería -nRo probarlo en línea .

Titus
fuente
1

dc , 98 85 bytes

?dsj[0dsosclj[soIlc^sr0]sn[I~dlo!>nrlc1+scd0<i]dsixljdlr%rlrI*/lr*+lo*dsj9<T]sT9<Tljp

Muchas gracias a esta respuesta por la idea de utilizar~ en la extracción de dígitos de un número, lo que resulta en dos bytes guardados sobre la versión original del código.

Esto fue bastante bien para completar en dc con sus capacidades inexistentes de manipulación de cadenas.

Pruébalo en línea!

R. Kap
fuente
1

Bash, 80 bytes

Utiliza paquetes Core Utilities (para sorty tail) y grep.

while((n>9));do m=$(grep -o .<<<$n|sort|tail -n1);n=$((${n/$m/}*m));done;echo $n

¿Como funciona?

while (( n > 9 )); do  # C-style loop conditional
    grep -o .          # Separate the string into one char per line
              <<< $n   # Use the content of variable `n` as its stdin
    | sort             # Pipe to `sort`, which sorts strings by line
    | tail -n 1        # Take the last line

m=$(                 ) # Assign the output of the command chain to `m`
n=$((          ))      # Assign the result of the evaluation to n
     ${n/$m/}          # Replace the first occurrence of $m with empty
             *m        # ... and multiply it by the value of `m`
done; echo $n          # After loop, print the value of `n`
iBug
fuente