Ridurre un numero della sua cifra più grande


33

Compito:

Dato un numero intero nel sistema di numeri decimali, ridurlo a una singola cifra decimale come segue:

  1. Convertire il numero in un elenco di cifre decimali.
  2. Trova la cifra più grande, D
  3. Rimuovi D dall'elenco. Se c'è più di un'occorrenza di D, scegli la prima da sinistra (nella posizione più significativa), tutte le altre dovrebbero rimanere intatte.
  4. Converti l'elenco risultante in un numero decimale e moltiplicalo per D.
  5. Se il numero è maggiore di 9 (ha più di 1 cifra decimale), ripetere l'intera procedura, inserendo il risultato al suo interno. Interrompi quando ottieni un risultato a una cifra.
  6. Visualizza il risultato.

Esempio:

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.

Continuiamo ripetendo la procedura per 14184 e così via e passiamo attraverso i seguenti risultati intermedi, raggiungendo infine 8:

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

Quindi il risultato per 26364 è 8.

Input: un numero intero / una stringa che rappresenta un numero intero

Output: una singola cifra, il risultato della riduzione applicata al numero.

Casi test:

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

Questo è , quindi vincono le risposte più brevi in ​​byte in ogni lingua.


3
Che cos'è Se il numero è maggiore di 10 o ha più di 1 cifra decimale . Il numero 10 ha più di 1 cifra decimale, ma non è più grande di dieci.
Adám,

@ Adám Codificando le logiche, allora dovrebbe 10 -> 10?
Ian H.

1
@Adám Hai ragione, avrei dovuto scrivere "più grande di 9". Ho intenzione di modificare la descrizione. Grazie!
Galen Ivanov,

Qualcuno ha esaminato l'istogramma di questa funzione per regioni sufficientemente grandi? Sembra avere molti zero; Ho anche ottenuto molti 8 mentre componevo i casi di test.
Galen Ivanov,

2
Inoltre, un numero casuale divisibile per 4 ha una probabilità 3/5 che il prodotto delle ultime due cifre sia divisibile per 8.
Ørjan Johansen

Risposte:


18

05AB1E , 6 byte

Codice:

[Dg#à*

Utilizza la codifica 05AB1E . Provalo online!

Spiegazione

[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

Prende l'input come rappresentazione di stringa di un numero intero, come f("26364") .

Casi test



6

Pyth , 16 byte

.WtH`*s.-ZKeSZsK

Accetta input come stringa. Provalo qui! (Alternativa: .WtH`*s.-ZeSZseS)

Pyth , 18 byte

.WgHT*s.-`ZKeS`ZsK

Accetta l'input come numero intero. Provalo qui!

Come funziona

16-byter

.WtH` * s.-ZKeSZsK ~ Programma completo.

.W ~ Funzionale mentre. Mentre A (valore) è vero, valore = B (valore).
                 ~ Viene restituito il valore finale.
  tH ~ A, condizione: il valore [1:] è vero? La lunghezza è ≥ 2?
    `* s.-ZKeSZsK ~ B, setter.
       .- ~ Sottrazione bagwise, utilizzata per rimuovere la cifra più alta, con ...
         Z ~ Il valore corrente Z e ...
          KeSZ ~ La cifra più alta di Z (come stringa). Assegna anche a una variabile K.
      s ~ Trasmesso a un numero intero.
     * ~ Moltiplicato per ...
              sK ~ La cifra più alta.
    `~ Converti in una stringa.

18-byter

.WgHT * s.-`ZKeS`ZsK ~ Programma completo.

.W ~ Funzionale mentre. Mentre A (valore) è vero, valore = B (valore).
                   ~ Viene restituito il valore finale.
  gHT ~ A, condizione: è un valore (H) ≥ 10?
     * s.-`ZKeS`ZsK ~ B, setter.
       .- ~ Sottrazione bagwise (utilizzata per rimuovere la prima occorrenza).
         `Z ~ La rappresentazione in formato stringa di Z.
           KeS`Z ~ E il carattere più alto (lessicograficamente) di Z (cifra più alta).
                     Inoltre lo assegna a una variabile chiamata K.
      s ~ Trasmetti a numero intero.
     * ~ Moltiplica per ...
                sK ~ K espressi in int.

Essere così vicini a Jelly in questo tipo di sfida è molto positivo per Pyth IMO :-)


6

Buccia , 14 13 12 byte

Grazie Zgarb per aver salvato 1 byte.

Ω≤9oṠS*od-▲d

Provalo online!

Spiegazione:

Ω≤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 byte con alcuni riordini.
Zgarb,

@Zgarb Grazie, stavo cercando qualcosa del genere.
H.Piz,

6

R , 99 95 byte

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)

Provalo online!

Una funzione ricorsiva. L'aggiunta f(number)nel piè di pagina può essere utilizzata per verificare altri valori di number. L'implementazione semplice, dè l'elenco delle cifre e 10^(n:2-2)%*%d[-M]calcola il numero con la cifra più grande rimossa.


5

Python 2 , 72 byte

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

Provalo online!


1
... Stavo eseguendo il debug di un errore stupido in questo . Accidenti, ho ottenuto il ninja.
totalmente umano il

Ricevo un errore sull'input 9
RoryT

Questo sembra fallire nel caso di test 432969. "ValueError: valore letterale non valido per int () con base 10: ''"
James Webster,

@JamesWebster dovrebbe essere risolto ora.
FlipTack,

1
@recursive No, come se allora nfosse 0 allora n*(n<=9)valuterebbe ancora un valore falso, 0, facendo continuare la ricorsione e causando un errore, mentre la stringa '0'è un valore veritiero e quindi la ricorsione viene interrotta.
FlipTack


4

Gelatina , 15 byte

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

Provalo online! o vedi la suite di test .

Come?

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

Provalo online!


Benvenuti in PPCG! Puoi rimuovere uno spazio .
Erik the Outgolfer,

@EriktheOutgolfer Grazie, mi sei perso.
Timmeh,

1
@totallyhuman Grazie, fino a 137 dopo alcuni refactoring.
Timmeh,

È possibile passare if(n<10)return n;...return F(...);a un singolo ritorno con ternary-if, in questo modo: 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 byte )
Kevin Cruijssen,

Penso che devi includere using System.Linq;(18 byte) nel byte.
Ian H.

4

APL (Dyalog) , 36 35 33 byte

-1 a causa di specifiche OP aggiornate. -2 grazie a ngn.

Funzione prefisso tacito anonimo. Prende intero come argomento.

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

Provalo online!

{... }una funzione in cui è l'argomento:

⍵>9: se l'argomento è maggiore di 9, quindi:

  ⍕⍵ formatta (stringi) l'argomento

  ⍎¨ esegui (valuta) ciascuno (questo ci fornisce le cifre come numeri)

  (... ) applica la seguente funzione tacita su quelle

   ⌈/ la cifra più grande

   × volte

   10⊥ la decodifica base-10 di (raccoglie cifre)

    tutte le cifre

   ⌷⍨¨ indicizzato da ciascuno di

   ⍳∘≢ i i ndices del numero di cifre

    si differenzia da

   ⊢⍳⌈/ la cifra più grande I NDICE in tutta la lista di cifre

   ricorrere (cioè chiamare sé) su questo

 altro

   restituisce l'argomento non modificato


Non dovrebbe >10essere >9?
Erik the Outgolfer,

@EriktheOutgolfer Probabilmente, ma OP in realtà non è chiaro (contraddittorio) a riguardo.
Adám,

È vero, ma >9salverebbe un byte.
Erik the Outgolfer,

@EriktheOutgolfer Aggiornato.
Adám,

@Adám ∇ invece di ⍣ = per -1 byte: {⍵> 9: ∇ (⌈ / ... ⋄⍵}
ngn

3

Perl 6 ,  45  41 byte

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

Provalo

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

Provalo

Allargato:

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

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

Provalo online! Link include i casi di test abbastanza velocemente da non martellare il server di Dennis. Spiegazione:

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

Per i numeri a due cifre, questo duplica il numero con un ;separatore, con il prefisso 1 sul duplicato. Per numeri di una cifra, questo prefisso 1;il numero.

O`\G\d

Ordina le cifre del duplicato. (Per i numeri di una cifra, questo non ha alcun effetto.)

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

Trova la prima occorrenza della cifra più grande ed eliminala, e anche le altre cifre nel duplicato e l'ulteriore 1 aggiunto in precedenza. (Per i numeri a una cifra, la corrispondenza ha esito negativo, quindi non fa nulla.)

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

Moltiplica il numero per la cifra. Per i numeri di una cifra, questo si traduce nel numero originale e il ciclo termina. Altrimenti, il programma scorre fino a raggiungere una singola cifra.


3

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

13 byte salvati grazie a @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);}

Provalo online!


Puoi cambiare s.Length<2in n<10. Inoltre, è possibile rimuovere l'operatore ternario e solo return f(y)alla fine, poiché il caso viene gestito dal ifpassaggio successivo della ricorsione.
raznagul,

3

Java 8, 126 104 byte

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

-22 byte grazie a @ OlivierGrégoire .

Spiegazione:

Provalo qui.

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 byte (come sopra, ma iterativo anziché ricorsivo, anche: n>9e ripristina le condizioni anziché n<10).
Olivier Grégoire,

2

Jq 1,5 , 86 byte

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

allargato

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
)

Provalo online!



2

Lua, 137 108 byte

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

Grazie a Jonathan S per il golf off 29 byte.

Provalo online!



Grazie. Sembra degno di una risposta propria - si collegherà a un post che pubblichi per esso, altrimenti modificherà e accrediterà.
MCAdventure10

Modificalo e basta. È ancora il tuo codice, non l'ho scritto da zero.
Jonathan S.

2

D , 188 186 185 byte

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

Provalo online!

Odio la valutazione pigra, così tanto. Tutti i suggerimenti sono benvenuti!


2

Lua, 154 byte

Dovrei avere dei modi per giocare a golf, sto sperimentando proprio ora.

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)

Provalo online!

spiegazioni

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

Provalo online!

Ooof. Gli array di PowerShell sono immutabili, quindi è necessario utilizzare il lungo [Collections.ArrayList]casting qui per poter chiamare in .remove()seguito.

Prende l'input $args, lo converte in una stringa, quindi in un chararray, quindi in ArrayList. Memorizza quello in $a. Quindi eseguiamo il whileloop fino a quando non siamo a o sotto 9. Ad ogni iterazione, stiamo invocando .removel'elemento più grande di $a(eseguito sorte prendendo l'ultimo elemento [-1]), memorizzando l'elemento più grande in$b . Questo sembra funzionare perché i valori ASCII si ordinano allo stesso modo delle cifre letterali.

Successivamente, ricalcoliamo $a, sempre come un chararray (e ArrayListimplicitamente), lanciando il nostro $b(che è attualmente a char) su una stringa, quindi un int con +e moltiplicandolo per$a -join ed in una stringa (implicitamente cast in int). Questo soddisfa la parte "moltiplica per D" della sfida.

Alla fine, una volta usciti dal circuito, ci $aimmettiamo nella pipeline e l'output è implicito.


2

Pip , 22 21 byte

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

Accetta input come argomento della riga di comando. Verifica tutti i casi di test: provalo online!

Spiegazione

Ungolfed, con commenti:

                 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

Nella versione golfata, il corpo del loop è condensato in una singola espressione:

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 byte


-10 byte grazie a Jo King

Sfortunatamente non è possibile chiamare ricorsivamente una funzione lambda, quindi sono necessari altri 11 byte per l'intestazione del metodo. Sono consapevole che esiste una risposta Java più breve che si snoda invece, ma ho deciso di trovare questo da solo.

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

Provalo online


Puoi spostare la -48dalla mappa alla fine della mdefinizione. Provalo online! Hai anche degli spazi bianchi extra nel tuo link TIO
Jo King

@JoKing grazie.
Benjamin Urquhart

1

J, 40 byte

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

Provalo online!

spiegazione

(      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
Oggi ho imparato da te la selezione della scatola tripla, grazie!
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

Provalo online!

Sprecato troppo in tutti i tipi di casting.


1

PHP, 82 77 + 1 byte

for($n=$argn;$n>9;)$n=join("",explode($d=max(str_split($n)),$n,2))*$d;echo$n;

Esegui come pipe -nRo provalo online .


1

dc , 98 85 byte

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

Mille grazie a questa risposta per l'idea di utilizzare ~nell'estrazione di cifre da un numero, risultando in due byte salvati rispetto alla versione originale del codice.

Era piuttosto completo da completare dccon le sue inesistenti capacità di manipolazione delle stringhe.

Provalo online!


1

Bash, 80 byte

Utilizza i pacchetti Core Utilities (per sorte tail) e grep.

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

Come funziona?

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`
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.