Reduce a number by its largest digit

33

4

Task:

Given an integer number in decimal number system, reduce it to a single decimal digit as follows:

  1. Convert the number to a list of decimal digits.
  2. Find the largest digit, D
  3. Remove D from the list. If there is more than one occurrence of D, choose the first from the left (at the most significant position), all others should remain intact.
  4. Convert the resulting list to a decimal number and multiply it by D.
  5. If the number is bigger than 9 (has more than 1 decimal digit), repeat the whole procedure, feeding the result into it. Stop when you get a single-digit result.
  6. Display the result.

Example:

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.

We continue by repeating the procedure for 14184 and so on and we go through the following intermediate results, finally reaching 8:

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

So the result for 26364 is 8.

Input: An integer / a string representing an integer

Output: A single digit, the result of the reduction applied to the number.

Test cases:

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

This is , so the shortest answers in bytes in each language win.

Galen Ivanov

Posted 2017-11-18T20:05:21.537

Reputation: 13 815

3Which is it If the number is bigger than 10 or has more than 1 decimal digit. The number 10 has more than 1 decimal digit, but it isn't bigger than ten. – Adám – 2017-11-18T22:00:43.327

@Adám By coding logics, should then 10 -> 10? – Ian H. – 2017-11-19T00:16:29.857

1@Adám You are right, I should have written "bigger than 9". I'm going to edit the description. Thanks! – Galen Ivanov – 2017-11-19T07:37:56.470

Has someone examined the histogram of this function for sufficiently large regions? It seems to have a lot of zeroes; I also got many 8s while composing the test cases. – Galen Ivanov – 2017-11-19T09:54:07.730

Being divisible by 2 or 5 is preserved once it happens, so it's no wonder you easily get 0. That might also increase the chance of 8s. – Ørjan Johansen – 2017-11-19T17:54:48.030

2Also, a random number divisible by 4 has 3/5 probability of the product of the last two digits being divisible by 8. – Ørjan Johansen – 2017-11-21T18:36:15.067

Answers

18

05AB1E, 6 bytes

Code:

[Dg#à*

Uses the 05AB1E encoding. Try it online!

Explanation

[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

Posted 2017-11-18T20:05:21.537

Reputation: 41 965

11

JavaScript (ES6), 49 bytes

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

Takes input as a string representation of an integer, like f("26364").

Test Cases

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

;["9", "27", "757", "1234", "26364", "432969", "1234584", "91273716"]
.forEach(num => console.log(num + " -> " + f(num)))
.as-console-wrapper{max-height:100%!important}

Justin Mariner

Posted 2017-11-18T20:05:21.537

Reputation: 4 746

8

Jelly, 13 bytes

œṡṀẎḌ×ṀD
DÇḊ¿

Try it online!

-1 thanks to a trick I found in Jonathan Allan's answer.

Full program.

Erik the Outgolfer

Posted 2017-11-18T20:05:21.537

Reputation: 38 134

6

Pyth, 16 bytes

.WtH`*s.-ZKeSZsK

Takes input as a String. Try it here! (Alternative: .WtH`*s.-ZeSZseS)

Pyth, 18 bytes

.WgHT*s.-`ZKeS`ZsK

Takes input as an integer. Try it here!

How it works

16-byter

.WtH`*s.-ZKeSZsK ~ Full program.

.W               ~ Functional while. While A(value) is truthy, value = B(value).
                 ~ The final value is returned.
  tH             ~ A, condition: Is value[1:] truthy?  Is the length ≥ 2?
    `*s.-ZKeSZsK ~ B, setter.
       .-        ~ Bagwise subtraction, used for removing the highest digit, with...
         Z       ~ The current value Z, and...
          KeSZ   ~ The highest digit of Z (as a String). Also assigns to a variable K.
      s          ~ Casted to an integer.
     *           ~ Multiplied by...
              sK ~ The highest digit.
    `            ~ Convert to a String.

18-byter

.WgHT*s.-`ZKeS`ZsK ~ Full program.

.W                 ~ Functional while. While A(value) is truthy, value = B(value).
                   ~ The final value is returned.
  gHT              ~ A, condition: is value (H) ≥ 10?
     *s.-`ZKeS`ZsK ~ B, setter.
       .-          ~ Bagwise substraction (used for removing first occurrence).
         `Z        ~ The string representation of Z.
           KeS`Z   ~ And the highest (lexicographically) character of Z (highest digit).
                     It also assigns it to a variable called K.
      s            ~ Cast to integer.
     *             ~ Multiply by...
                sK ~ K casted to int.

Being that close to Jelly at such type of challenge is very good for Pyth IMO :-)

Mr. Xcoder

Posted 2017-11-18T20:05:21.537

Reputation: 39 774

6

Husk, 14 13 12 bytes

Thanks Zgarb for saving 1 byte.

Ω≤9oṠS*od-▲d

Try it online!

Explanation:

Ω≤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

Posted 2017-11-18T20:05:21.537

Reputation: 10 962

12 bytes with some rearranging. – Zgarb – 2017-11-18T21:31:23.887

@Zgarb Thanks, I was looking for something like that. – H.PWiz – 2017-11-18T21:33:33.203

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)

Try it online!

A recursive function. Adding f(number) in the footer can be used to test for other values of number. Straightforward implementation, d is the list of digits, and 10^(n:2-2)%*%d[-M] computes the number with the largest digit removed.

Giuseppe

Posted 2017-11-18T20:05:21.537

Reputation: 21 077

5

Python 2, 72 bytes

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

Try it online!

FlipTack

Posted 2017-11-18T20:05:21.537

Reputation: 13 242

1

...I was debugging a dumb mistake in this. Darn, I got ninja'd.

– totallyhuman – 2017-11-18T20:21:59.003

I'm getting an error on input 9 – RoryT – 2017-11-19T07:27:55.787

This seems to fail for the test case 432969. "ValueError: invalid literal for int() with base 10: ''" – James Webster – 2017-11-20T13:25:05.810

@JamesWebster should be fixed now. – FlipTack – 2017-11-20T18:15:25.683

I believe you can remove the first set of backticks. – recursive – 2017-11-21T22:06:58.390

1@recursive No, as then if n was 0 then n*(n<=9) would still evaluate to a falsy value, 0, making the recursion continue and causing an error, whereas the string '0' is a truthy value and therefore the recursion is halted. – FlipTack – 2017-11-21T22:16:43.753

Those particular backticks were particularly bothering me. You were right, of course, about why they're needed in this solution. But I rearranged it to eliminate them and save a byte. It uses if ... else. https://tio.run/##NYzBDsIgEAXvfAW3sqYxYaEgTfRbigppE7qSilG/HsXE48y8vPwu842w1nhMfj1fPacxioWKmGjabyEnfwli9a/G0HddLwF2rf8dwBI5nVxI98CpPuclBS7HvH1HvF3lRxEA1TG0zA6WSVSaoVFGM63QGfczw0EzJ9EqK80H

– recursive – 2017-11-21T23:17:00.577

4

Jelly, 15 bytes

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

Try it online! or see the test-suite.

How?

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

Posted 2017-11-18T20:05:21.537

Reputation: 67 804

4

Ruby, 59 bytes

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

Try it online!

Recursive lambda function called like f[26364].

Justin Mariner

Posted 2017-11-18T20:05:21.537

Reputation: 4 746

4

Haskell, 70 67 66 bytes

Saved 3 4 bytes thanks to nimi!

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

Try it online!

H.PWiz

Posted 2017-11-18T20:05:21.537

Reputation: 10 962

An explicit recursion is shorter than until. Try it online!.

– nimi – 2017-11-18T21:52:58.063

one more byte to save: ...span=<<(>).maximum.... – nimi – 2017-11-18T22:06:53.870

Ooh ... Nice :) – H.PWiz – 2017-11-18T22:10:14.710

4

APL (Dyalog), 36 35 33 bytes

-1 due to updated OP specs. -2 thanks to ngn.

Anonymous tacit prefix function. Takes integer as argument.

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

Try it online!

{}a function where is the argument:

⍵>9: if the argument is greater than 9, then:

  ⍕⍵ format (stringify) the argument

  ⍎¨ execute (evaluate) each (this gets us the digits as numbers)

  () apply the following tacit function on those

   ⌈/ the largest digit

   × times

   10⊥ the base-10 decoding of (collects digits)

    all the digits

   ⌷⍨¨ indexed by each of

   ⍳∘≢ the indices of the number of digits

    differs from

   ⊢⍳⌈/ the largest digit's index in the entire list of digits

   recurse (i.e. call self) on that

 else

   return the argument unmodified

Adám

Posted 2017-11-18T20:05:21.537

Reputation: 37 779

Shouldn't >10 be >9? – Erik the Outgolfer – 2017-11-18T21:49:12.433

@EriktheOutgolfer Probably, but OP is actually unclear (self-contradictory) about that. – Adám – 2017-11-18T21:59:32.103

That's true, but >9 would save a byte. – Erik the Outgolfer – 2017-11-18T22:10:40.673

@EriktheOutgolfer Updated. – Adám – 2017-11-19T09:33:56.407

@Adám ∇ instead of ⍣= for -1 byte: {⍵>9:∇(⌈/ ... ⋄⍵} – ngn – 2017-11-20T18:26:12.367

@Adám another -1: use ⌷ instead of / for removing D - replace ⊢(/⍨)⍳∘≢≠⊢⍳⌈/ with ⊂⌷⍨¨⍳∘≢~⊢⍳⌈/ – ngn – 2017-11-20T18:43:21.660

@ngn Thanks for both. – Adám – 2017-11-20T23:45:10.663

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

Try it online!

Timmeh

Posted 2017-11-18T20:05:21.537

Reputation: 141

Welcome to PPCG! You can remove a space.

– Erik the Outgolfer – 2017-11-20T11:25:10.593

@EriktheOutgolfer Thank you, missed that one. – Timmeh – 2017-11-20T11:51:49.650

1@totallyhuman Thank you, down to 137 after some refactoring. – Timmeh – 2017-11-20T12:13:16.047

You can change if(n<10)return n;...return F(...); to a single return with ternary-if, like this: 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 – 2017-11-20T13:38:27.193

I think you need to include using System.Linq; (18 bytes) into the bytecount. – Ian H. – 2017-11-21T17:37:10.047

3

Perl 6,  45  41 bytes

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

Test it

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

Test it

Expanded:

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

Posted 2017-11-18T20:05:21.537

Reputation: 12 713

3

C# (.NET Core), 177 164 + 18 bytes

Saved 13 bytes thanks to @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);}

Try it online!

Ian H.

Posted 2017-11-18T20:05:21.537

Reputation: 2 431

You can change s.Length<2 to n<10. Also, you can remove the ternary operator and just return f(y) at the end, as the case is handled by the if in the next step of the recursion. – raznagul – 2017-11-21T13:04:58.910

3

Retina, 67 bytes

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

Try it online! Link includes the test cases fast enough not to hammer Dennis's server. Explanation:

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

For two digit numbers, this duplicates the number with a ; separator, prefixing a 1 to the duplicate. For one digit numbers, this prefixes 1; to the number.

O`\G\d

Sort the digits of the duplicate. (For one digit numbers, this has no effect.)

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

Find the first occurrence of the largest digit, and delete it, and also the other digits in the duplicate, and the extra 1 that was added earlier. (For one digit numbers, the match fails so this does nothing.)

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

Multiply the number by the digit. For one digit numbers, this results in the original number, and the loop terminates. Otherwise, the program loops until a single digit is reached.

Neil

Posted 2017-11-18T20:05:21.537

Reputation: 95 035

3

Java 8, 126 104 bytes

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

-22 bytes thanks to @OlivierGrégoire.

Explanation:

Try it here.

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

Posted 2017-11-18T20:05:21.537

Reputation: 67 575

111 bytes – Olivier Grégoire – 2017-11-22T14:10:19.193

1104 bytes (same as above, but iterative instead of recursive, also: n>9 and revert conditions instead of n<10). – Olivier Grégoire – 2017-11-22T14:14:22.530

2

Jq 1.5, 86 bytes

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

Expanded

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
)

Try it online!

jq170727

Posted 2017-11-18T20:05:21.537

Reputation: 411

2

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

Try it online!

PrincePolka

Posted 2017-11-18T20:05:21.537

Reputation: 653

2

Perl 5, 41 + 1 (-p) = 42 bytes

$m=(sort/./g)[-1];s/$m//;($_*=$m)>9&&redo

Try it online!

Xcali

Posted 2017-11-18T20:05:21.537

Reputation: 7 671

Fails on input of 9. :( but tinkered a little and managed to get 41 bytes with a fix: Try it online!

– Dom Hastings – 2017-11-20T13:57:36.463

2

Lua, 137 108 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

Thanks to Jonathan S for golfing off 29 bytes.

Try it online!

MCAdventure10

Posted 2017-11-18T20:05:21.537

Reputation: 103

1108 bytes – Jonathan S. – 2017-11-19T12:28:43.027

Thanks. That looks worthy of an answer of its own - will link to a post you make for it, otherwise will edit & credit. – MCAdventure10 – 2017-11-19T12:34:43.330

Just edit it in. It's still your code, I haven't written it from scratch. – Jonathan S. – 2017-11-19T12:46:21.613

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

Try it online!

I hate lazy evaluation, so much. Any tips are welcome!

Zacharý

Posted 2017-11-18T20:05:21.537

Reputation: 5 710

2

Lua, 154 Bytes

I should have some ways to golf this down, I'm experimenting right now.

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)

Try it online!

Explanations

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

Posted 2017-11-18T20:05:21.537

Reputation: 2 857

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

Try it online!

Ooof. PowerShell arrays are immutable, so we need to use the lengthy [Collections.ArrayList] casting here so we can call .remove() later.

Takes input $args, converts it to a string, then a char-array, then an ArrayList. Stores that into $a. Then we while loop until we're at or below 9. Each iteration, we're calling .remove on the largest element of $a (done by sort and taking the last element [-1]), storing the largest element into $b at the same time. This happens to work because the ASCII values sort in the same fashion as the literal digits.

Next, we recompute $a, again as an char-array (and ArrayList implicitly), by casting our $b (which is currently a char) to a string, then an int with +, and multiplying that to $a -joined into a string (implicitly cast to int). This satisfies the "multiply by D" portion of the challenge.

Finally, once we're out of the loop, we put $a onto the pipeline and output is implicit.

AdmBorkBork

Posted 2017-11-18T20:05:21.537

Reputation: 41 581

2

Pip, 22 21 bytes

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

Takes input as a command-line argument. Verify all test cases: Try it online!

Explanation

Ungolfed, with comments:

                 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

In the golfed version, the loop body is condensed into a single expression:

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

Posted 2017-11-18T20:05:21.537

Reputation: 21 213

2

Java 8: 115 bytes


-10 bytes thanks to Jo King

Unfortunately you can't call a lambda function recursively, so an extra 11 bytes is needed for the method header. I am aware there is a shorter Java answer that loops instead, but I decided to come up with this on my own.

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

Try it online

Benjamin Urquhart

Posted 2017-11-18T20:05:21.537

Reputation: 1 262

You can move the -48 from the map to the end of the m definition. Try it online! You also have some extra whitespace in your TIO link

– Jo King – 2019-03-08T00:28:57.847

@JoKing thanks. – Benjamin Urquhart – 2019-03-08T00:43:11.403

1

J, 40 bytes

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

Try it online!

explanation

(      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

Jonah

Posted 2017-11-18T20:05:21.537

Reputation: 8 729

1I learnt about the triple box selection from you today, thank you! – Galen Ivanov – 2017-11-19T08:33:51.340

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

Try it online!

Wasted too much on all the type casting.

root

Posted 2017-11-18T20:05:21.537

Reputation: 241

1

Kotlin, 109 bytes

fun f(n:Int):Int{return if(n>9){val m=(""+n).max()!!;f((""+n).replaceFirst(""+m,"").toInt()*(m-'0'))}else n}

jingx

Posted 2017-11-18T20:05:21.537

Reputation: 111

1

Bash, 80 bytes

Uses packages Core Utilities (for sort and tail) and grep.

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

How does it work?

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

Posted 2017-11-18T20:05:21.537

Reputation: 2 477

1

PHP, 82 77+1 bytes

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

Run as pipe with -nR or try it online.

Titus

Posted 2017-11-18T20:05:21.537

Reputation: 13 814

1

dc, 98 85 bytes

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

Many thanks to this answer for the idea of utilizing ~ in the extraction of digits from a number, resulting in two saved bytes over the original version of the code.

This was a rather though one to complete in dc with its nonexistent string manipulation capabilities.

Try it online!

R. Kap

Posted 2017-11-18T20:05:21.537

Reputation: 4 730

1

APL NARS 42 40 36 chars

{⍵≤9:⍵⋄∇h⌷v×10⊥v[(⍳⍴v)∼h←1⌷⍒v←⍎¨⍕⍵]}

some test, I copied the trick ⍎¨⍕ from Adam solution

g←{⍵≤9:⍵⋄∇h⌷v×10⊥v[(⍳⍴v)∼h←1⌷⍒v←⍎¨⍕⍵]}

  g¨9 27 757 1234 26364 432969 1234584 91273716
9 4 5 8 8 0 8 6

{⍵≤9:⍵   if ⍵≤9 return ⍵
 ∇h⌷v×10⊥v[(⍳⍴v)∼h←1⌷⍒v←⍎¨⍕⍵]
                      v←⍎¨⍕⍵] convert ⍵ in the list of integer digits (not chars) in v
                 h←1⌷⍒v       puts in h the index of the first element max that appear in v
           v[(⍳⍴v)∼h           gets from v only the indices for digits different from h
        10⊥                   convert that modify v[]sub array to a number in base 10
 ∇h⌷v×            multiply it with v[h], and recall the same function for this number
}

RosLuP

Posted 2017-11-18T20:05:21.537

Reputation: 3 036