Réduire un nombre par son plus grand chiffre

33

Tâche:

Étant donné un nombre entier dans le système de nombres décimaux, réduisez-le en un seul chiffre décimal, comme suit:

  1. Convertissez le nombre en liste de chiffres décimaux.
  2. Trouver le plus grand chiffre, D
  3. Supprimer D de la liste. S'il y a plus d'une occurrence de D, choisissez la première de gauche (position la plus significative), toutes les autres doivent rester intactes.
  4. Convertissez la liste obtenue en un nombre décimal et multipliez-la par D.
  5. Si le nombre est supérieur à 9 (comporte plus d'un chiffre décimal), répétez toute la procédure en y introduisant le résultat. Arrêtez-vous lorsque vous obtenez un résultat à un chiffre.
  6. Afficher le résultat.

Exemple:

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.

Nous continuons en répétant la procédure pour 14184 et ainsi de suite et nous passons aux résultats intermédiaires suivants, pour atteindre finalement 8:

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

Le résultat pour 26364 est donc 8.

Entrée: Un entier / une chaîne représentant un entier

Sortie: Un seul chiffre, résultat de la réduction appliquée au nombre.

Cas de test:

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

C'est du , donc les réponses les plus courtes en octets dans chaque langue sont gagnantes.

Galen Ivanov
la source
3
De quoi s'agit-il si le nombre est supérieur à 10 ou s'il comporte plus d'un chiffre décimal ? Le nombre 10 a plus d'un chiffre décimal, mais il n'est pas plus grand que dix.
Adám
@ Adám En codant la logique, devrait alors 10 -> 10 ?
Ian H.
1
@ Adám Vous avez raison, j'aurais dû écrire "plus grand que 9". Je vais éditer la description. Merci!
Galen Ivanov
Quelqu'un a-t-il examiné l'histogramme de cette fonction pour des régions suffisamment grandes? Il semble y avoir beaucoup de zéros; J'ai également eu beaucoup de 8 en composant les cas de test.
Galen Ivanov
2
De plus, un nombre aléatoire divisible par 4 a 3/5 de probabilité que le produit des deux derniers chiffres soit divisible par 8.
Ørjan Johansen

Réponses:

18

05AB1E , 6 octets

Code:

[Dg#à*

Utilise le codage 05AB1E . Essayez-le en ligne!

Explication

[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
la source
11

JavaScript (ES6), 49 octets

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

Prend l'entrée comme une chaîne représentant un entier, comme f("26364").

Cas de test

Justin Mariner
la source
6

Pyth , 16 octets

.WtH`*s.-ZKeSZsK

Prend l'entrée en tant que chaîne. Essayez-le ici! (Variante: .WtH`*s.-ZeSZseS)

Pyth , 18 octets

.WgHT*s.-`ZKeS`ZsK

Prend l'entrée sous forme d'entier. Essayez-le ici!

Comment ça marche

16 octets

.WtH` * s.-ZKeSZsK ~ Programme complet.

.W ~ fonctionnel tout. Alors que A (valeur) est la vérité, valeur = B (valeur).
                 ~ La valeur finale est renvoyée.
  tH ~ A, condition: la valeur [1:] est-elle la vérité? La longueur est ≥ 2?
    `* s.-ZKeSZsK ~ B, passeur.
       .- ~ Soustraction par poche, utilisée pour supprimer le chiffre le plus élevé, avec ...
         Z ~ La valeur actuelle Z, et ...
          KeSZ ~ Le chiffre le plus élevé de Z (sous forme de chaîne). Assigne également à une variable K.
      s ~ converti en un entier.
     * ~ Multiplié par ...
              sK ~ Le chiffre le plus élevé.
    `~ Convertir en chaîne.

18 byter

.WgHT * s.-`ZKeS`ZsK ~ Programme complet.

.W ~ fonctionnel tout. Alors que A (valeur) est la vérité, valeur = B (valeur).
                   ~ La valeur finale est renvoyée.
  GTH ~ A, condition: la valeur (H) est-elle égale ou supérieure à 10?
     * s.-`ZKeS`ZsK ~ B, passeur.
       .- ~ Soustraction dans le sac (utilisé pour éliminer la première occurrence).
         `Z ~ La représentation sous forme de chaîne de Z.
           KeS`Z ~ Et le caractère le plus élevé (lexicographiquement) de Z (chiffre le plus élevé).
                     Il l'assigne également à une variable appelée K.
      s ~ Cast en entier.
     * ~ Multiplier par ...
                sK ~ K jeté à int.

Être aussi proche de Jelly à ce type de défi est très bon pour Pyth IMO :-)

M. Xcoder
la source
6

Husk , 14 13 12 octets

Merci Zgarb d'avoir économisé 1 octet.

Ω≤9oṠS*od-▲d

Essayez-le en ligne!

Explication:

Ω≤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
la source
12 octets avec quelques réarrangements.
Zgarb
@Zgarb Merci, je cherchais quelque chose comme ça.
H.PWiz
6

R , 99 95 octets

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)

Essayez-le en ligne!

Une fonction récursive. L'ajout f(number)dans le pied de page peut être utilisé pour tester d'autres valeurs de number. La mise en œuvre directe dest la liste des chiffres et 10^(n:2-2)%*%d[-M]calcule le nombre avec le plus grand chiffre supprimé.

Giuseppe
la source
5

Python 2 , 72 octets

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

Essayez-le en ligne!

FlipTack
la source
1
... Je déboguais une stupide erreur en cela . Zut, je suis ninja.
totalement humain
Je reçois une erreur sur l'entrée 9
RoryT
Cela semble échouer pour le cas de test 432969. "ValueError: Littéral invalide pour int () avec base 10: ''"
James Webster
@JamesWebster devrait être corrigé maintenant.
FlipTack
1
@recursive Non, alors que si n0 était alors n*(n<=9)considéré comme une valeur de fausseté, 0, ce qui rendait la récursion continue et provoquait une erreur, alors que la chaîne '0'était une valeur de vérité et que la récursivité était donc stoppée.
FlipTack
4

Ruby , 59 octets

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

Essayez-le en ligne!

Fonction lambda récursive appelée comme f[26364].

Justin Mariner
la source
4

Gelée , 15 octets

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

Essayez-le en ligne! ou voir la suite de tests .

Comment?

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
la source
4

Haskell , 70 67 66 octets

Sauvegardé 3 4 octets grâce à nimi!

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

Essayez-le en ligne!

H.PWiz
la source
Une récursion explicite est plus courte que until. Essayez-le en ligne! .
nimi
un octet pour enregistrer: ...span=<<(>).maximum....
nimi
Ooh ... Nice :)
H.PWiz
4

C # (.NET Core) , 126 octets

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

Essayez-le en ligne!

Timmeh
la source
Bienvenue chez PPCG! Vous pouvez supprimer un espace .
Erik the Outgolfer
@EriktheOutgolfer Merci, raté celui-là.
Timmeh
1
@totallyhuman Merci, jusqu'à 137 après un peu de refactoring.
Timmeh
Vous pouvez passer if(n<10)return n;...return F(...);à une seule déclaration avec ternaire, si, comme ceci: 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 octets )
Kevin Cruijssen
Je pense que vous devez inclure using System.Linq;(18 octets) dans le décompte.
Ian H.
4

APL (Dyalog) , 36 35 33 octets

-1 en raison de la mise à jour des spécifications OP. -2 grâce à ngn.

Fonction de préfixe tacite anonyme. Prend un entier comme argument.

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

Essayez-le en ligne!

{}Une fonction où est l'argument:

⍵>9: si l'argument est supérieur à 9, alors:

  ⍕⍵ formate (stringify) l'argument

  ⍎¨ exécuter (évaluer) chacun (cela nous donne les chiffres sous forme de nombres)

  () Applique la fonction tacite suivante sur ceux

   ⌈/ le plus grand chiffre

   × fois

   10⊥ le décodage en base 10 de (recueille les chiffres)

    tous les chiffres

   ⌷⍨¨ indexé par chacun des

   ⍳∘≢ les i ndices du nombre de chiffres

    diffère de

   ⊢⍳⌈/ le plus grand chiffre i ndex dans la liste complète des chiffres

   recurse (c'est-à-dire appeler soi-même) sur cette

 autre

   renvoyer l'argument non modifié

Adam
la source
Ne devrait pas >10être >9?
Erik l'Outgolfer
@EriktheOutgolfer Probablement, mais OP n'est pas clair (contradictoire) à ce sujet.
Adám
C'est vrai, mais >9économiserais un octet.
Erik the Outgolfer
@EriktheOutgolfer Mis à jour.
Adám
@ Adám ∇ au lieu de ⍣ = pour -1 octet: {⍵> 9: (/ ... ⋄⍵}
ngn
3

Perl 6 ,  45  41 octets

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

Essaye-le

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

Essaye-le

Étendu:

{  # 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
la source
3

Retina , 67 octets

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

Essayez-le en ligne! Link inclut les cas de test assez rapidement pour ne pas écraser le serveur de Dennis. Explication:

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

Pour les nombres à deux chiffres, cela duplique le nombre avec un ;séparateur, en préfixant 1 au duplicata. Pour les numéros à un chiffre, ce préfixe correspond 1;au numéro.

O`\G\d

Triez les chiffres du duplicata. (Pour les chiffres à un chiffre, cela n'a aucun effet.)

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

Recherchez la première occurrence du chiffre le plus grand et supprimez-la, ainsi que les autres chiffres de la copie et le numéro supplémentaire 1 ajouté précédemment. (Pour les nombres à un chiffre, la correspondance échoue, cela ne fait rien.)

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

Multipliez le nombre par le chiffre. Pour les nombres à un chiffre, cela donne le numéro d'origine et la boucle se termine. Sinon, le programme est mis en boucle jusqu'à ce qu'un chiffre soit atteint.

Neil
la source
3

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

Sauvegardé 13 octets grâce à @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);}

Essayez-le en ligne!

Ian H.
la source
Vous pouvez changer s.Length<2pour n<10. En outre, vous pouvez supprimer l'opérateur ternaire et juste return f(y)à la fin, car le cas est traité par l' ifétape suivante de la récursivité.
Raznagul
3

Java 8, 126 104 octets

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

-22 octets grâce à @ OlivierGrégoire .

Explication:

Essayez ici.

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
la source
111 octets
Olivier Grégoire Le
1
104 octets (comme ci-dessus, mais itératif au lieu de récursif, aussi: n>9et conditions de retour au lieu de n<10).
Olivier Grégoire
2

Jq 1.5 , 86 octets

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

Étendu

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
)

Essayez-le en ligne!

jq170727
la source
2

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

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

Essayez-le en ligne!

Xcali
la source
Échec sur l'entrée de 9. :( mais bricolé un peu et a réussi à obtenir 41 octets avec un correctif: essayez-le en ligne!
Dom Hastings
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
la source
1
108 bytes
Jonathan S.
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!

Zacharý
la source
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
la source
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
la source
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
la source
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
la source
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
la source
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
Jonah
la source
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.

root
la source
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
la source
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
la source
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
la source