Zmniejsz liczbę o największą cyfrę


33

Zadanie:

Biorąc pod uwagę liczbę całkowitą w systemie liczb dziesiętnych, zmniejsz ją do jednej cyfry dziesiętnej w następujący sposób:

  1. Konwertuj liczbę na listę cyfr dziesiętnych.
  2. Znajdź największą cyfrę, D
  3. Usuń D z listy. Jeśli występuje więcej niż jedno wystąpienie D, wybierz pierwsze od lewej (w najbardziej znaczącej pozycji), wszystkie pozostałe powinny pozostać nienaruszone.
  4. Konwertuj wynikową listę na liczbę dziesiętną i pomnóż ją przez D.
  5. Jeśli liczba jest większa niż 9 (ma więcej niż 1 cyfrę dziesiętną), powtórz całą procedurę, wprowadzając do niej wynik. Zatrzymaj się, gdy otrzymasz wynik jednocyfrowy.
  6. Wyświetl wynik.

Przykład:

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.

Kontynuujemy, powtarzając procedurę dla 14184 i tak dalej, i przechodzimy przez następujące wyniki pośrednie, ostatecznie osiągając 8:

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

Tak więc wynik dla 26364 wynosi 8.

Dane wejściowe: liczba całkowita / ciąg znaków reprezentujący liczbę całkowitą

Wyjście: Pojedyncza cyfra, wynik zmniejszenia zastosowanego do liczby.

Przypadki testowe:

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

To jest , więc wygrywają najkrótsze odpowiedzi w bajtach w każdym języku.


3
Co to jest, jeśli liczba jest większa niż 10 lub ma więcej niż 1 cyfrę dziesiętną . Liczba 10 ma więcej niż 1 cyfrę dziesiętną, ale nie jest większa niż dziesięć.
Adám

@ Adám Czy zatem kodowanie logiki powinno 10 -> 10?
Ian H.,

1
@ Adám Masz rację, powinienem był napisać „większy niż 9”. Zamierzam edytować opis. Dzięki!
Galen Iwanow

Czy ktoś sprawdził histogram tej funkcji dla wystarczająco dużych regionów? Wydaje się, że ma wiele zer; Dostałem także wiele ósemek podczas komponowania przypadków testowych.
Galen Iwanow

2
Również liczba losowa podzielna przez 4 ma 3/5 prawdopodobieństwa, że ​​iloczyn dwóch ostatnich cyfr będzie podzielny przez 8
Ørjan Johansen

Odpowiedzi:


18

05AB1E , 6 bajtów

Kod:

[Dg#à*

Wykorzystuje kodowanie 05AB1E . Wypróbuj online!

Wyjaśnienie

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

11

JavaScript (ES6), 49 bajtów

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

Pobiera dane wejściowe jako ciąg znaków reprezentujący liczbę całkowitą, np f("26364").

Przypadki testowe



6

Pyth , 16 bajtów

.WtH`*s.-ZKeSZsK

Pobiera dane wejściowe jako ciąg. Wypróbuj tutaj! (Alternatywnie: .WtH`*s.-ZeSZseS)

Pyth , 18 bajtów

.WgHT*s.-`ZKeS`ZsK

Pobiera dane wejściowe jako liczbę całkowitą. Wypróbuj tutaj!

Jak to działa

16 bajtów

.WtH` * s.-ZKeSZsK ~ Pełny program.

.W ~ Funkcjonalne podczas. Podczas gdy A (wartość) jest prawdziwa, wartość = B (wartość).
                 ~ Ostateczna wartość jest zwracana.
  tH ~ A, warunek: Czy wartość [1:] jest prawdziwa? Czy długość ≥ 2?
    `* s.-ZKeSZsK ~ B, seter.
       .- ~ Odejmowanie według kolejności, używane do usuwania najwyższej cyfry, z ...
         Z ~ Aktualna wartość Z i ...
          KeSZ ~ Najwyższa cyfra Z (jako ciąg znaków). Przypisuje również do zmiennej K.
      s ~ Rzucono na liczbę całkowitą.
     * ~ Pomnożone przez ...
              sK ~ Najwyższa cyfra.
    `~ Konwertuj na ciąg.

18-bajtowy

.WgHT * s.-`ZKeS`ZsK ~ Pełny program.

.W ~ Funkcjonalne podczas. Podczas gdy A (wartość) jest prawdziwa, wartość = B (wartość).
                   ~ Ostateczna wartość jest zwracana.
  gHT ~ A, warunek: czy wartość (H) ≥ 10?
     * s.-`ZKeS`ZsK ~ B, seter.
       .- ~ Odejmowanie zgodnie z wytycznymi (używane do usunięcia pierwszego wystąpienia).
         `Z ~ Ciąg znaków reprezentujący Z.
           KeS`Z ~ I najwyższy (leksykograficznie) znak Z (najwyższa cyfra).
                     Przypisuje ją również do zmiennej o nazwie K.
      s ~ Cast to integer.
     * ~ Pomnóż przez ...
                sK ~ K casted na int.

Bycie tak blisko Galaretki przy tego rodzaju wyzwaniach jest bardzo dobre dla Pyth IMO :-)


6

Łuska , 14 13 12 bajtów

Dzięki Zgarb za uratowanie 1 bajtu.

Ω≤9oṠS*od-▲d

Wypróbuj online!

Wyjaśnienie:

Ω≤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 bajtów z pewną rearanżacją.
Zgarb,

@Zgarb Dzięki, szukałem czegoś takiego.
H.PWiz

6

R , 99 95 bajtów

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)

Wypróbuj online!

Funkcja rekurencyjna. Dodanie f(number)stopki może służyć do testowania innych wartości number. Prosta implementacja, dto lista cyfr i 10^(n:2-2)%*%d[-M]oblicza liczbę z usuniętą największą cyfrą.


5

Python 2 , 72 bajty

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

Wypróbuj online!


1
... debugowałem w tym głupi błąd . Cholera, mam ninja.
całkowicie ludzki,

Dostaję błąd na wejściu 9
RoryT

Wydaje się, że nie udaje się to w przypadku testu 432969. „ValueError: niepoprawny literał dla int () z bazą 10: ''”
James Webster,

@JamesWebster powinien zostać teraz naprawiony.
FlipTack,

1
@recursive Nie, tak jakby to nbyło 0, wówczas n*(n<=9)nadal przyjmowałoby wartość falsy, 0, co powoduje, że rekurencja jest kontynuowana i powoduje błąd, podczas gdy ciąg znaków '0'jest wartością zgodną z prawdą i dlatego rekurencja zostaje zatrzymana.
FlipTack


4

Galaretka , 15 bajtów

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

Wypróbuj online! lub zobacz zestaw testowy .

W jaki sposób?

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 bajtów

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

Wypróbuj online!


Witamy w PPCG! Możesz usunąć spację .
Erik the Outgolfer,

@EriktheOutgolfer Dziękuję, tęskniłem za tym.
Timmeh,

1
@ totalniehuman Dziękuję, aż do 137 po pewnym refaktoryzacji.
Timmeh,

Możesz zmienić if(n<10)return n;...return F(...);na pojedynczy zwrot z trójskładnikiem, jeśli: 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 bajtów )
Kevin Cruijssen

Myślę, że musisz dołączyć using System.Linq;(18 bajtów) do bajtu.
Ian H.

4

APL (Dyalog) , 36 35 33 bajtów

-1 z powodu zaktualizowanych specyfikacji OP. -2 dzięki ngn.

Anonimowa ukryta funkcja prefiksu. Jako argument przyjmuje liczbę całkowitą.

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

Wypróbuj online!

{}Funkcja gdzie jest argument:

⍵>9: jeśli argument jest większy niż 9, to:

  ⍕⍵ sformatuj (wykreśl) argument

  ⍎¨ wykonaj (oceń) każdy (to daje nam cyfry jako liczby)

  () Zastosuj następującą ukrytą funkcję na tych

   ⌈/ największa cyfra

   × czasy

   10⊥ dekodowanie base-10 (zbiera cyfry)

    wszystkie cyfry

   ⌷⍨¨ indeksowane według każdego z

   ⍳∘≢ że I ndices od liczby cyfr

    różni się od

   ⊢⍳⌈/ Największą cyfrowy kod i ndex w całej listy cyfr

   powrócić (tj. wezwać siebie) w tej sprawie

 jeszcze

   zwraca argument niezmodyfikowany


Nie powinno >10być >9?
Erik the Outgolfer,

@EriktheOutgolfer Prawdopodobnie, ale OP jest w rzeczywistości niejasny (wewnętrznie sprzeczny) w tej sprawie.
Adám,

To prawda, ale >9zaoszczędziłoby bajt.
Erik the Outgolfer,

@EriktheOutgolfer Zaktualizowano.
Adám,

@ Adám ∇ zamiast ⍣ = dla -1 bajtów: {⍵> 9: ∇ (⌈ / ... ⋄⍵}
ngn

3

Perl 6 ,  45  41 bajtów

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

Sprawdź to

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

Sprawdź to

Rozszerzony:

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

Siatkówka , 67 bajtów

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

Wypróbuj online! Link zawiera przypadki testowe wystarczająco szybko, aby nie hamować serwera Dennisa. Wyjaśnienie:

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

W przypadku liczb dwucyfrowych powielają one liczbę za pomocą ;separatora, poprzedzając cyfrę 1 w duplikacie. W przypadku liczb jednocyfrowych jest to przedrostek 1;liczby.

O`\G\d

Posortuj cyfry duplikatu. (W przypadku liczb jednocyfrowych nie ma to wpływu.)

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

Znajdź pierwsze wystąpienie największej cyfry i usuń ją, a także pozostałe cyfry w duplikacie oraz dodatkową 1, która została dodana wcześniej. (W przypadku liczb jednocyfrowych dopasowanie nie powiedzie się, więc to nic nie robi.)

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

Pomnóż liczbę przez cyfrę. W przypadku liczb jednocyfrowych powoduje to powstanie oryginalnego numeru i pętla kończy się. W przeciwnym razie program zapętla się, aż zostanie osiągnięta jedna cyfra.


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

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.


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`
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.