Reduzieren Sie eine Zahl um die größte Ziffer


33

Aufgabe:

Reduzieren Sie eine Ganzzahl im Dezimalzahlensystem wie folgt auf eine einzelne Dezimalstelle:

  1. Konvertieren Sie die Zahl in eine Liste mit Dezimalstellen.
  2. Suchen Sie die größte Ziffer, D
  3. Entfernen Sie D aus der Liste. Wenn es mehr als ein Vorkommen von D gibt, wählen Sie das erste von links (an der höchstwertigen Position), alle anderen sollten intakt bleiben.
  4. Wandle die resultierende Liste in eine Dezimalzahl um und multipliziere sie mit D.
  5. Wenn die Zahl größer als 9 ist (mehr als eine Dezimalstelle hat), wiederholen Sie den gesamten Vorgang und tragen Sie das Ergebnis ein. Stoppen Sie, wenn Sie ein einstelliges Ergebnis erhalten.
  6. Zeigen Sie das Ergebnis an.

Beispiel:

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.

Wir wiederholen den Vorgang für 14184 und so weiter und gehen die folgenden Zwischenergebnisse durch und erreichen schließlich 8:

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

Das Ergebnis für 26364 ist also 8.

Eingabe: Eine Ganzzahl / ein String, der eine Ganzzahl darstellt

Ausgabe: Eine einzelne Ziffer, das Ergebnis der Reduzierung, die auf die Zahl angewendet wird.

Testfälle:

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

Dies ist , daher gewinnen die kürzesten Antworten in Bytes in jeder Sprache.


3
Was ist das? Wenn die Zahl größer als 10 ist oder mehr als 1 Dezimalstelle hat . Die Zahl 10 hat mehr als eine Dezimalstelle, ist jedoch nicht größer als zehn.
Adám,

@Adám Durch die Codierung von Logiken sollte das dann gehen 10 -> 10?
Ian H.

1
@Adam Du hast recht, ich hätte "größer als 9" schreiben sollen. Ich werde die Beschreibung bearbeiten. Vielen Dank!
Galen Ivanov

Hat jemand das Histogramm dieser Funktion für ausreichend große Regionen untersucht? Es scheint viele Nullen zu haben; Beim Verfassen der Testfälle habe ich auch viele Achtel bekommen.
Galen Ivanov

2
Eine durch 4 teilbare Zufallszahl hat eine Wahrscheinlichkeit von 3/5, dass das Produkt der letzten beiden Ziffern durch 8 teilbar ist.
Ørjan Johansen,

Antworten:


18

05AB1E , 6 Bytes

Code:

[Dg#à*

Verwendet die 05AB1E- Codierung. Probieren Sie es online!

Erläuterung

[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 Byte

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

Nimmt die Eingabe als Zeichenfolgendarstellung einer Ganzzahl wie f("26364").

Testfälle



6

Pyth , 16 Bytes

.WtH`*s.-ZKeSZsK

Übernimmt die Eingabe als String. Probieren Sie es hier aus! (Alternative: .WtH`*s.-ZeSZseS)

Pyth , 18 Bytes

.WgHT*s.-`ZKeS`ZsK

Übernimmt die Eingabe als Ganzzahl. Probieren Sie es hier aus!

Wie es funktioniert

16 Byte

.WtH` * s.-ZKeSZsK ~ Volles Programm.

.W ~ Funktioniert während. Während A (Wert) wahr ist, ist Wert = B (Wert).
                 ~ Der Endwert wird zurückgegeben.
  tH ~ A, Bedingung: Ist der Wert [1:] wahr? Ist die Länge ≥ 2?
    `* s.-ZKeSZsK ~ B, Setter.
       .- ~ Bagwise Subtraktion, verwendet zum Entfernen der höchsten Ziffer, mit ...
         Z ~ Der aktuelle Wert Z und ...
          KeSZ ~ Die höchste Ziffer von Z (als String). Weist auch eine Variable K zu.
      s ~ In eine Ganzzahl umgewandelt.
     * ~ Multipliziert mit ...
              sK ~ Die höchste Ziffer.
    `~ In einen String konvertieren.

18-byter

.WgHT * s.-`ZKeS`ZsK ~ Volles Programm.

.W ~ Funktioniert während. Während A (Wert) wahr ist, ist Wert = B (Wert).
                   ~ Der Endwert wird zurückgegeben.
  gHT ~ A, Bedingung: Ist der Wert (H) ≥ 10?
     * s.-`ZKeS`ZsK ~ B, Setter.
       - ~ Bagwise Subtraktion (zum Entfernen des ersten Auftretens).
         `Z ~ Die Zeichenfolgendarstellung von Z.
           KeS`Z ~ Und das höchste (lexikografisch) Zeichen von Z (höchste Ziffer).
                     Es weist es auch einer Variablen mit dem Namen K zu.
      s ~ In Ganzzahl umwandeln.
     * ~ Multiplizieren mit ...
                sK ~ K gegossen auf int.

Sein so nah an Jelly bei dieser Art von Herausforderung IMO für Pyth sehr gut ist :-)


6

Schale , 14 13 12 Bytes

Danke Zgarb für das Speichern von 1 Byte.

Ω≤9oṠS*od-▲d

Probieren Sie es online!

Erläuterung:

Ω≤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 Bytes mit einigen Neuanordnungen.
Zgarb 18.11.17

@Zgarb Danke, ich habe so etwas gesucht.
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)

Probieren Sie es online!

Eine rekursive Funktion. Das Hinzufügen f(number)in der Fußzeile kann zum Testen auf andere Werte von verwendet werden number. Einfache Implementierung, dist die Liste der Ziffern und 10^(n:2-2)%*%d[-M]berechnet die Zahl, bei der die größte Ziffer entfernt wurde.


5

Python 2 , 72 Bytes

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

Probieren Sie es online!


1
... Ich habe einen blöden Fehler in dieser Sache behoben . Verdammt, ich habe Ninja.
Totalhuman

Ich
erhalte

Dies scheint für den Testfall zu scheitern 432969. "ValueError: ungültiges Literal für int () mit Basis 10: ''"
James Webster

@JamesWebster sollte jetzt behoben sein.
FlipTack 20.11.17

1
@recursive Nein, wenn ndann 0 n*(n<=9)wäre, würde dies immer noch einen falschen Wert ergeben, 0, wodurch die Rekursion fortgesetzt und ein Fehler verursacht wird, wohingegen die Zeichenfolge '0'ein wahrer Wert ist und daher die Rekursion angehalten wird.
FlipTack


4

Gelee , 15 Bytes

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

Probieren Sie es online! oder sehen Sie sich die Testsuite an .

Wie?

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 Byte

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

Probieren Sie es online!


Willkommen bei PPCG! Sie können ein Leerzeichen entfernen .
Erik der Outgolfer 20.11.17

@EriktheOutgolfer Danke, ich habe das verpasst.
Timmeh

1
@totallyhuman Vielen Dank, bis 137 nach einigen Umgestaltungen.
Timmeh 20.11.17

Sie können if(n<10)return n;...return F(...);mit ternary-if wie 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));}
folgt

Ich denke, Sie müssen using System.Linq;(18 Bytes) in den bytecount aufnehmen.
Ian H.

4

APL (Dyalog) , 36 35 33 Bytes

-1 aufgrund aktualisierter OP-Spezifikationen. -2 danke an ngn.

Anonyme implizite Präfixfunktion. Übernimmt eine Ganzzahl als Argument.

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

Probieren Sie es online!

{}Eine Funktion, wo das Argument ist:

⍵>9: Wenn das Argument größer als 9 ist, gilt Folgendes:

  ⍕⍵ Formatieren (Stringifizieren) Sie das Argument

  ⍎¨ jedes ausführen (auswerten) (dies bringt uns die Ziffern als Zahlen)

  () Wenden auf diese die folgende implizite Funktion an

   ⌈/ die größte Ziffer

   × mal

   10⊥ die Base-10-Dekodierung von (sammelt Ziffern)

    alle ziffern

   ⌷⍨¨ indiziert von jedem von

   ⍳∘≢ die i ndices der Anzahl der Stellen

    unterscheidet sich von

   ⊢⍳⌈/ die größte Ziffer der i ndex in der gesamten Liste der Stellen

   darauf zurückgreifen (dh sich selbst nennen)

 sonst

   Gibt das Argument unverändert zurück


Sollte nicht >10sein >9?
Erik der Outgolfer 18.11.17

@EriktheOutgolfer Wahrscheinlich, aber OP ist darüber eigentlich unklar (widersprüchlich).
Adám

Das stimmt, >9würde aber ein Byte sparen.
Erik der Outgolfer 18.11.17

@EriktheOutgolfer Aktualisiert.
Adám

@ Adám ∇ anstelle von ⍣ = für -1 Byte: {⍵> 9: ∇ (⌈ / ... ⋄⍵}
ngn

3

Perl 6 ,  45  41 Bytes

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

Probier es aus

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

Probier es aus

Erweitert:

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

Probieren Sie es online! Link enthält die Testfälle schnell genug, um Dennis 'Server nicht zu überraschen. Erläuterung:

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

Bei zweistelligen Nummern wird die Nummer mit einem ;Trennzeichen dupliziert, wobei dem Duplikat eine 1 vorangestellt wird. Bei einstelligen Nummern wird diese 1;Nummer vorangestellt .

O`\G\d

Sortieren Sie die Ziffern des Duplikats. (Bei einstelligen Zahlen hat dies keine Auswirkung.)

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

Suchen Sie das erste Vorkommen der größten Ziffer und löschen Sie sie sowie die anderen Ziffern im Duplikat und die zusätzliche 1, die zuvor hinzugefügt wurde. (Bei einstelligen Zahlen schlägt die Übereinstimmung fehl, sodass dies nichts bewirkt.)

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

Multiplizieren Sie die Zahl mit der Ziffer. Für einstellige Nummern ergibt dies die ursprüngliche Nummer, und die Schleife wird beendet. Andernfalls wird das Programm solange wiederholt, bis eine einzelne Ziffer erreicht ist.


3

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

13 Bytes gespart dank @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);}

Probieren Sie es online!


Sie können ändern , s.Length<2zu n<10. Sie können auch den ternären Operator entfernen und erst return f(y)am Ende, wie der Fall ifim nächsten Schritt der Rekursion behandelt wird.
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 dank @ OlivierGrégoire .

Erläuterung:

Probieren Sie es hier aus.

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 (wie oben, aber iterativ statt rekursiv, auch:n>9 und Bedingungen zurücksetzen statt 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))

Erweitert

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
)

Probieren Sie es 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

Vielen Dank an Jonathan S für die 29 Bytes.

Probieren Sie es online!



Vielen Dank. Das sieht einer eigenen Antwort würdig aus - verlinkt auf einen Beitrag, den Sie dafür verfassen, andernfalls wird es bearbeitet und gutgeschrieben.
MCAdventure10

Bearbeiten Sie es einfach in. Es ist immer noch Ihr Code, ich habe ihn nicht von Grund auf neu geschrieben.
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);}

Probieren Sie es online!

Ich hasse faul Auswertung, so sehr. Irgendwelche Tipps sind willkommen!


2

Lua, 154 Bytes

Ich sollte ein paar Möglichkeiten haben, dies herunter zu spielen. Ich experimentiere gerade.

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)

Probieren Sie es online!

Erklärungen

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 Byte

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

Probieren Sie es online!

Ooof. PowerShell-Arrays sind unveränderlich, daher müssen wir [Collections.ArrayList]hier das langwierige Casting verwenden, damit wir es .remove()später aufrufen können .

Übernimmt die Eingabe $args, konvertiert sie in einen String, dann ein char-array und dann ein ArrayList. Speichert das in $a. Dann whileschleifen wir , bis wir an oder unter sind 9. Bei jeder Iteration rufen wir .removedas größte Element von $a(erledigt von sortund nimmt das letzte Element [-1]) auf und speichern das größte Element in$b . Dies funktioniert, weil die ASCII-Werte auf dieselbe Weise wie die Literalziffern sortiert werden.

Als nächstes berechnen wir $awieder als char-array (und ArrayListimplizit), indem wir unser $b(welches momentan a ist char) in einen String, dann in ein int mit +, umwandeln und dieses mit multiplizieren$a -join ed in eine Zeichenfolge (implizit in int umwandeln). Dies erfüllt den "Multiplizieren mit D" -Teil der Herausforderung.

Sobald wir die Schleife verlassen haben, stellen wir uns $aauf die Pipeline und die Ausgabe ist implizit.


2

Pip , 22 21 Bytes

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

Übernimmt Eingaben als Befehlszeilenargument. Überprüfen Sie alle Testfälle: Probieren Sie es online!

Erläuterung

Ungolfed, mit Kommentaren:

                 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 der Golfversion wird der Loop-Body zu einem einzigen Ausdruck zusammengefasst:

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 dank Jo King

Leider kann man eine Lambda-Funktion nicht rekursiv aufrufen, so dass zusätzliche 11 Bytes für den Methodenkopf benötigt werden. Mir ist bewusst, dass es eine kürzere Java-Antwort gibt, die sich stattdessen in einer Schleife befindet, aber ich habe mich dazu entschlossen, diese selbst zu entwickeln.

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

Probieren Sie es online aus


Sie können das Symbol -48von der Karte an das Ende der mDefinition verschieben. Probieren Sie es online! Sie haben auch einige zusätzliche Leerzeichen in Ihrem TIO-Link
Jo King

Vielen Dank.
Benjamin Urquhart

1

J, 40 Bytes

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

Probieren Sie es online!

Erläuterung

(      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
Ich habe heute von Ihnen über die Triple-Box-Auswahl erfahren, danke!
Galen Ivanov

1

PowerShell , 230 Byte

$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

Probieren Sie es online!

Zu viel Zeit mit dem Typ Casting verschwendet.



1

Gleichstrom , 98-85 Bytes

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

Vielen Dank an diese Antwort für die Idee, ~beim Extrahieren von Ziffern aus einer Zahl zwei gespeicherte Bytes gegenüber der Originalversion des Codes zu verwenden.

Dies war eine ziemlich schwierige Aufgabe, die dcmit ihren nicht vorhandenen Manipulationsmöglichkeiten für Zeichenfolgen abgeschlossen werden musste.

Probieren Sie es online!


1

Bash, 80 Bytes

Verwendet die Pakete Core Utilities (für sortund tail) und grep.

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

Wie funktioniert es?

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`
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.