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.