Зменшіть число на його найбільшу цифру


33

Завдання:

Враховуючи ціле число в системі десяткових чисел, зменшіть його до однієї десяткової цифри наступним чином:

  1. Перетворіть число в список десяткових цифр.
  2. Знайдіть найбільшу цифру, D
  3. Видаліть D зі списку. Якщо зустрічається більше одного явища D, виберіть перше зліва (у найбільш значущому положенні), всі інші повинні залишатися неушкодженими.
  4. Перетворіть отриманий список у десяткове число та помножте його на D.
  5. Якщо число більше 9 (має більше 1 десяткової цифри), повторіть всю процедуру, вводячи в неї результат. Зупиніться, коли отримаєте одноцифровий результат.
  6. Показати результат.

Приклад:

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.

Ми продовжуємо, повторюючи процедуру 14184 тощо, і проходимо наступні проміжні результати, нарешті досягаючи 8:

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

Тож результат за 26364 - 8.

Введення: Ціле число / рядок, що представляє ціле число

Вихід: Однозначна цифра, результат зменшення, застосованого до числа.

Тестові приклади:

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

Це , тому найкоротші відповіді в байтах на кожній мові виграють.


3
Що це якщо число більше 10 або має більше 1 десяткової цифри . Число 10 має більше 1 десяткової цифри, але воно не більше десяти.
Адам

@ Adám Чи слід тоді кодувати логіку 10 -> 10?
Ян Х.

1
@ Adám Ви праві, я повинен був написати "більше 9". Я збираюся редагувати опис. Спасибі!
Гален Іванов

Хтось вивчав гістограму цієї функції для досить великих регіонів? Здається, це багато нулів; Я також отримав багато восьми років під час складання тестових випадків.
Гален Іванов

2
Також випадкове число, що ділиться на 4, має 3/5 ймовірність того, що добуток двох останніх цифр ділиться на 8.
Ørjan Johansen

Відповіді:



11

JavaScript (ES6), 49 байт

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

Приймає введення як рядкове представлення цілого числа, як f("26364").

Випробування



6

Pyth , 16 байт

.WtH`*s.-ZKeSZsK

Приймає введення як рядка. Спробуйте тут! (Альтернатива: .WtH`*s.-ZeSZseS)

Піт , 18 байт

.WgHT*s.-`ZKeS`ZsK

Вводиться як ціле число. Спробуйте тут!

Як це працює

16-байт

.WtH` * s.-ZKeSZsK ~ Повна програма.

.W ~ Функціональний час. У той час як A (значення) є правдою, значення = B (значення).
                 ~ Кінцеве значення повертається.
  tH ~ A, умова: Чи значення [1:] truthy? Чи довжина ≥ 2?
    `* с.-ZKeSZsK ~ B, сетер.
       .- ~ Віднімання сумками, що використовується для вилучення найвищої цифри, з ...
         Z ~ Поточне значення Z і ...
          KeSZ ~ Найвища цифра Z (як струна). Також призначає змінну K.
      s ~ Віднесено до цілого числа.
     * ~ Помножено на ...
              sK ~ Найвища цифра.
    `~ Перетворити на рядок.

18-байт

.WgHT * s.-`ZKeS`ZsK ~ Повна програма.

.W ~ Функціональний час. У той час як A (значення) є правдою, значення = B (значення).
                   ~ Кінцеве значення повертається.
  gHT ~ A, умова: це значення (H) ≥ 10?
     * s.-`ZKeS`ZsK ~ B, сетер.
       .- ~ Субстракційна сумка (використовується для видалення першого виникнення).
         `Z ~ Строкове представлення Z.
           KeS`Z ~ І найвищий (лексикографічно) символ Z (найвища цифра).
                     Він також призначає його змінній під назвою K.
      s ~ Передати цілому числу.
     * ~ Помножити на ...
                sK ~ K відлитий до int.

Бути так близько до Jelly при такому типі виклику дуже добре для Pyth IMO :-)


6

Лушпиння , 14 13 12 байт

Дякую Zgarb за збереження 1 байта.

Ω≤9oṠS*od-▲d

Спробуйте в Інтернеті!

Пояснення:

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

12 байт з деякою перестановкою.
Згарб

@ Zgarb Спасибі, я шукав щось подібне.
H.PWiz

6

R , 99 95 байт

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)

Спробуйте в Інтернеті!

Рекурсивна функція. Додавання f(number)у колонтитул може використовуватися для перевірки інших значень number. Безпосередня реалізація d- це перелік цифр і 10^(n:2-2)%*%d[-M]обчислює число з вилученою найбільшою цифрою.


5

Python 2 , 72 байти

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

Спробуйте в Інтернеті!


1
... Я налагоджував тупу помилку в цьому . Дарн, я ніндзя.
повністюлюдсько

Я отримую помилку на вході 9
RoryT

Це, здається, не вдалося для тестового випадку 432969. "ValueError: недійсний літерал для int () з базою 10: ''"
James Webster

@JamesWebster слід виправити зараз.
FlipTack

1
@recursive Ні, оскільки тоді, якби nбуло 0, тоді n*(n<=9)все одно оцінюватимуться до помилкового значення 0, змушуючи рекурсію продовжуватись і спричиняючи помилку, тоді як рядок '0'є величиною трикутника, і тому рекурсія зупиняється.
FlipTack


4

Желе , 15 байт

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

Спробуйте в Інтернеті! або побачити набір тестів .

Як?

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)


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!


Welcome to PPCG! You can remove a space.
Erik the Outgolfer

@EriktheOutgolfer Thank you, missed that one.
Timmeh

1
@totallyhuman Thank you, down to 137 after some refactoring.
Timmeh

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

I think you need to include using System.Linq; (18 bytes) into the bytecount.
Ian H.

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


Shouldn't >10 be >9?
Erik the Outgolfer

@EriktheOutgolfer Probably, but OP is actually unclear (self-contradictory) about that.
Adám

That's true, but >9 would save a byte.
Erik the Outgolfer

@EriktheOutgolfer Updated.
Adám

@Adám ∇ instead of ⍣= for -1 byte: {⍵>9:∇(⌈/ ... ⋄⍵}
ngn

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
}

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.


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!


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

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


1
104 bytes (same as above, but iterative instead of recursive, also: n>9 and revert conditions instead of 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))

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!



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!



Thanks. That looks worthy of an answer of its own - will link to a post you make for it, otherwise will edit & credit.
MCAdventure10

Just edit it in. It's still your code, I haven't written it from scratch.
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);}

Try it online!

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


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

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.


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


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


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

@JoKing thanks.
Benjamin Urquhart

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

1
I learnt about the triple box selection from you today, thank you!
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

Try it online!

Wasted too much on all the type casting.



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!


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`
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.