La base migliore è 10 ... Raggiungiamola!


40

Ingresso:

Un numero intero positivo n costituito da cifre nell'intervallo 0-9 .

Sfida:

Se d è la cifra più alta nell'intero, supponiamo che la base del numero sia d + 1 . Ad esempio, se il numero intero è 1256 , supponiamo che sia in base-7 , se è 10110, allora devi assumere che è base-2 (binario), e se è 159 allora è decimale.

Ora, procedi come segue fino a quando: 1: raggiungi un numero intero di base 10 o 2: raggiungi un numero intero a una cifra.

  1. Convertire il numero intero da base- (d + 1) a base-10
  2. Trova la base di questo nuovo numero intero (di nuovo, base- (d + 1) dove d è la cifra più alta nel nuovo numero)
  3. Vai al passaggio 1 .

Esempi:

Supponiamo che l'input sia n = 413574 . La cifra più alta d = 7 , quindi questa è base-8 (ottale). Convertire questo in decimale e ottenere 137084 . La cifra più alta d = 8 , quindi questa è base-9 . Converti questo in decimale e ottieni 83911 . La cifra più alta è 9 , quindi questo è un numero decimale e ci fermiamo. L'output deve essere 83911 .

Supponiamo che l'ingresso sia n = 13552 . La cifra più alta è d = 5 , quindi questa è base-6 . Converti questo in decimale e ottieni 2156 . La cifra più alta d = 6 , quindi questa è base-7 . Converti questo in decimale e ottieni 776 . La cifra più alta è d = 7 , quindi questa è base-8 . Converti questo in decimale e ottieni 510 . La cifra più alta è d = 5, quindi questa è base-6 . Converti questo in decimale e ottieni 186 . La cifra più alta è 8 , quindi questa è base-9 . Converti questo in decimale e ottieni 159. La cifra più alta è 9 , quindi questo è un numero decimale e ci fermiamo. L'output deve essere 159 .

Supponiamo che l'ingresso sia n = 17 . Questo ci darà 15 , quindi 11 , quindi 3 , che emetteremo poiché è una singola cifra.


Casi test:

5
5

17
3

999
999

87654321  (base-9 -> 42374116 in decimal -> base-7 -> 90419978 in decimal) 
9041998

41253  (5505 -> 1265 -> 488 -> 404 -> 104 -> 29)
29

Gli appunti:

  • Regole standard relative a I / O, scappatoie, ecc. È possibile prendere l'input come stringa
  • Le spiegazioni sono incoraggiate
  • È possibile utilizzare i comandi di conversione di base incorporati
    • Le soluzioni che non utilizzano le funzioni di conversione base incorporate del linguaggio (se esistono) sono benvenute, anche se finiscono per essere molto più lunghe dell'approccio ovvio che utilizza le funzioni integrate.

Apparentemente, questo è OEIS A091047 .


2
Apparentemente amo le matrici , quindi ho pensato di fare una sfida di conversione di base .
Stewie Griffin,

34
"La base migliore è 10" ... "10" è scritto in quale base?
Olivier Grégoire,

5
@ OlivierGrégoire Questa è la cosa intelligente ... Qualunque sia la base con cui finiamo, sarà comunque una dichiarazione valida!
Stewie Griffin,

@StewieGriffin Ma come lo leggi? "10" ha un nome diverso in ogni base.
user11153,

10
Bene, questo dipende dalla base ... o come Meghan direbbe "è tutto su quella base, 'Su quella base, nessun problema" ;-)
Stewie Griffin

Risposte:


20

Mathematica, 56 byte

#//.x_/;(b=Max[d=IntegerDigits@x]+1)<11:>d~FromDigits~b&

Provalo online! (Usando la matematica.)

Ho pensato di dare un'occhiata a come appare la sequenza:

enter image description here

Ed ecco un grafico del numero di passaggi necessari per trovare il risultato:

enter image description here

(Fare clic per versioni più grandi. Vedere la cronologia delle revisioni per i grafici solo fino a n = 1000. )

Sembra una miscela molto interessante di struttura su larga scala e caos su scala fine. Mi chiedo che succede con le lacune più ampie intorno a 30.000 e 60.000.


4
@StewieGriffin dovrebbe essere sul lato sinistro. Le piccole lacune ci sono, perché i numeri che portano a un multiplo di una potenza di 10 contengono a 9, quindi sono già nella base 10. Ma per 30k e 60k sembra che i numeri con un 8 o addirittura 7 (dovrebbero check) al posto di quel 9 diventa sempre base 10 dopo al massimo un passaggio.
Martin Ender,

@StewieGriffin Per essere precisi, tutti i numeri nell'intervallo [28051, 28888] sono base 9 e si traducono in numeri del modulo 19xxx, praticamente raddoppiando tale spazio.
cmaster

Ah, capito ... :) Per la cronaca: sapevo perché c'erano delle lacune sul lato sinistro dei poteri degli anni 10 ... Erano strane solo le doppie dimensioni (perché 30/60 e non 20 / 40/50). Vedo ora che quei numeri nell'intervallo 28xxx -> 19xxx, ma 38xxx -> 26xxx, non 29xxx.
Stewie Griffin,

10

Java 8, 172 166 163 152 151 140 138 116 114 99 byte

s->{for(Integer b=0;b<10&s.length()>1;s=""+b.valueOf(s,b=s.chars().max().getAsInt()-47));return s;}

Prende l'input come a String.

-64 byte grazie a @ OlivierGrégoire . E qui ho pensato che il mio 172 iniziale non fosse troppo male ..;)

Provalo qui.

Spiegazione:

s->{                    // Method with String as parameter and return-type
  for(Integer b=0;b<10  //  Loop as long as the largest digit + 1 is not 10
      &s.length()>1;    //  and as long as `s` contains more than 1 digit
    s=""+               //   Replace `s` with the String representation of:
         b.valueOf(s,   //    `s` as a Base-`b` integer
          b=s.chars().max().getAsInt()-47)
                        //     where `b` is the largest digit in the String + 1
  );                    //  End of loop
  return s;             //  Return result-String
}                       // End of method

1
Prometti di mantenere la calma? : p Ok ... andiamo: s->{for(Integer b=0;b<10&s.length()>1;)s=""+b.valueOf(s,b=s.chars().max().getAsInt()-47);return s;}. Inoltre ho eliminato la maggior parte dei miei commenti poiché sono totalmente irrilevanti ora ( bè la base, la tua a; ed sè il numero su cui stiamo lavorando).
Olivier Grégoire,

1
Ho provato a ricursificare questo per eliminare alcuni byte con: Integer b;return(b=s.chars().max().getAsInt()-47)>9|s.length()<2?s:c(""+b.valueOf(s,b));(88), ma sono nuovo di zecca per il golf del codice. Questo è un frammento, giusto? C'è un modo per dichiararlo come metodo senza la necessità di aggiungere public String c(String s)?
Lord Farquaad,

1
@LordFarquaad Non hai bisogno del public , ma temo che dovrai davvero usarlo String c(String s){}per le chiamate ricorsive, anche in Java 8. Quando crei un lambda usando java.util.function.Function<String, String> c=s->{Integer b;return(b=s.chars().max().getAsInt()-47)>9|s.length()<2?s:c‌.apply​(""+b.valueOf(s,b));}o usando l'interfaccia, otterrai interface N{String c(String s);}N n = s->{Integer b;return(b=s.chars().max().getAsInt()-47)>9|s.length()<2?s:n.c‌​(""+b.valueOf(s,b));};un " auto-riferimento nell'inizializzatore errore "in entrambi i casi. Ma comunque un approccio molto carino!
Kevin Cruijssen,

Ah, immagino di averlo annullato alcuni byte allora. Ma grazie per l'aiuto! Lo terrò a mente andando avanti.
Lord Farquaad,

8

Pyth, 9 byte

ui`GhseS`

Suite di test

Spiegazione:

ui`GhseS`
ui`GhseS`GQ    Implicit variable introduction
u         Q    Repeatedly apply the following function until the value repeats,
               starting with Q, the input.
        `G     Convert the working value to a string.
      eS       Take its maximum.
     s         Convert to an integer.
    h          Add one.
 i`G           Convert the working value to that base

È un po 'strano il modo in cui hai usato un lambda a due variabili per finire usando una variabile ... e non ha generato errori. Oh, le due variabili sono Qe Q, capisco.
Erik the Outgolfer,

@EriktheOutgolfer Non esattamente. usenza il suo terzo input viene applicato fino alla ripetizione, mentre con un terzo input viene applicato un numero fisso di volte. ulambda ha Ge H, ma non è necessario utilizzarlo H.
isaacg,

In realtà la sostituzione Gcon Havrebbe avuto lo stesso risultato ... tra la variabile implicita è G?
Erik the Outgolfer,

@EriktheOutgolfer La variabile implicita è G, sì. Hconta da 0 a ogni iterazione, quindi è completamente diverso. Non sono davvero sicuro di cosa tu stia parlando. Ecco un programma di esempio per mostrarti cosa sta succedendo: pyth.herokuapp.com/…
isaacg,

6

JavaScript (ES6), 63 57 54 53 byte

f=a=>a>9&(b=Math.max(...a+""))<9?f(parseInt(a,b+1)):a

Risparmiato 8 byte grazie a Shaggy e Dom Hastings

f=a=>a>9&(b=Math.max(...a+""))<9?f(parseInt(a,b+1)):a;

console.log(f("413574"))


Battimi. Penso che potresti risparmiare qualche byte con +a>9||b<9e invertire il ternario.
Shaggy,

1
@Shaggy edit: Sono stupido
Tom,

1
Non essere così duro con te stesso Tom! Non sei stupido ,,, ma sicuramente non sei intelligente come @Shaggy!
Stewie Griffin,

1
Alternativa per 55 bytef=n=>n>9&&(k=Math.max(...n+"")+1)<10?f(parseInt(n,k)):n
Dom Hastings,

@DomHastings Grazie per i miglioramenti! :)
Tom,

5

Python 3 , 91 78 76 75 73 byte

@Emigna rasata di 5 byte. @FelipeNardiBatista ha salvato 1 byte. @ RomanGräf ha salvato 2 byte

i=input()
while'9'>max(i)and~-len(i):i=str(int(i,int(max(i))+1))
print(i)

Provalo online!


Spiegazione

i=input()                                  - takes input and assigns it to a variable i
while '9'>max(i)and~-len(i):               - repeatedly checks if the number is still base-9 or lower and has a length greater than 1
    i=str(...)                             - assigns i to the string representation of ...
          int(i,int(max(i))+1)             - converts the current number to the real base 10 and loops back again
print(i)                                   - prints the mutated i

5

05AB1E , 10 5 byte

5 byte salvati grazie a Magic Octopus Urn

F§Z>ö

Dato che questo rallenta molto rapidamente per input di grandi dimensioni, lascio qui la vecchia versione molto più veloce per i test. L'algoritmo è lo stesso, solo il numero di iterazioni differisce.

[©Z>öD®Q#§

Provalo online!

Spiegazione

[             # start a loop
 ©            # store a copy of the current value in the register
  Z>          # get the maximum (digit) and increment
    ö         # convert the current value to base-10 from this base
     D        # duplicate
      ®Q#     # break loop if the new value is the same as the stored value
         §    # convert to string (to prevent Z from taking the maximum int on the stack)

Inoltre, non puoi semplicemente usare тFZ>ö§? Visto che il numero di iterazioni ( come visto qui ) sembra altopiano? Se vuoi diventare tecnico, la velocità con cui aumentano le iterazioni è probabilmente logaritmica ... Quindi potresti semplicemente usare qualcosa di simile: DFZ>ö§e dichiarare che non funzionerà per grandi n. O forse anche: T.n>FZ>ö§per calcolare direttamente il numero di iterazioni come log_10(n).
Magic Octopus Urn,

@MagicOctopusUrn: Sì, ora che me lo dici, dato che la sequenza sembra decisamente più lenta di quella lineare, F§Z>ödovrebbe fare il trucco.
Emigna,

Penso che puoi rimuovere il file §.
Erik the Outgolfer,

@EriktheOutgolfer: Purtroppo no. Se rimuoviamo il §, Zprenderà il numero più alto nella pila invece della cifra più alta nel numero in cima alla pila.
Emigna,


3

APL (Dyalog) , 20 16 byte

Prende e restituisce una stringa

((⍕⊢⊥⍨1+⌈/)⍎¨)⍣≡

(... )⍣≡ applica la seguente funzione fino a quando due termini consecutivi sono identici:

⍎¨ esegue ogni carattere (trasforma la stringa in un elenco di numeri)

(... ) applica la seguente funzione tacita a quella:

  ⌈/ trova il massimo dell'argomento

  1+ Aggiungi uno

  ⊢⊥⍨ valutare l'argomento in quella base

   format (stringify, in preparazione per un'altra applicazione della funzione esterna)

Provalo online!



3

Mathematica, 52 byte

FromDigits[s=IntegerDigits@#,Max@s+1]&~FixedPoint~#&

Funzione pura che accetta come input un numero intero non negativo e restituisce un numero intero non negativo. Utilizza la stessa meccanica FromDigits[s=IntegerDigits@#,Max@s+1]di base della risposta di Jenny_mathy , ma sfrutta FixedPointper eseguire l'iterazione.


3

Perl 6 , 49 byte

{($_,{.Str.parse-base(1+.comb.max)}...*==*).tail}

Provalo

Allargato:

{
  (

    $_,                 # seed the sequence with the input

    {
      .Str
      .parse-base(      # parse in base:
        1 + .comb.max   # largest digit + 1
      )
    }

    ...                 # keep generating values until

    * == *              # two of them match (should only be in base 10)

  ).tail                # get the last value from the sequence
}


2

Pip , 17 byte

Wa>9>YMXaaFB:1+ya

Accetta input come argomento della riga di comando. Provalo online!

Spiegazione

È stato divertente - ho dovuto estrarre gli operatori di confronto concatenati.

Vogliamo fare un ciclo fino a quando il numero è una singola cifra O contiene un 9. Equivalentemente, vogliamo fare un ciclo mentre il numero è composto da più cifre E non contiene un 9. Equivalentemente, un ciclo mentre il numero è maggiore di 9 E la cifra massima è meno di 9: a>9>MXa.

Wa>9>YMXaaFB:1+ya
                   a is 1st cmdline arg (implicit)
     YMXa          Yank a's maximum digit into the y variable
Wa>9>              While a is greater than 9 and 9 is greater than a's max digit:
         aFB:1+y    Convert a from base 1+y to decimal and assign back to a
                a  At the end of the program, print a

2

Python 2 , 60 59 56 53 byte

Salvato 4 byte grazie a Felipe Nardi Batista
Salvato 3 byte grazie a ovs

f=lambda x,y=0:x*(x==y)or f(`int(x,int(max(x))+1)`,x)

Provalo online!

Utilizzando un lambda ricorsivo, confrontando il risultato della conversione di base con l'iterazione precedente.


perché non usare x==y and x or ...come xnon sarà mai 0(base 1). o anche(x==y)*x or ...
Felipe Nardi Batista,

@FelipeNardiBatista: grazie! Ho provato x and x==y or ...che non ha funzionato, ma non sono troppo abile con questi trucchi, quindi non mi rendevo conto di poterlo invertire :)
Emigna,

@ovs: hai ragione. Grazie!
Emigna,

@FelipeNardiBatista "Input: un numero intero positivo n costituito da cifre nell'intervallo 0-9." 0 è ancora un input valido e ora il codice lo rifiuta.
Albero il

@Mast: Fortunatamente per noi, 0 non è un numero intero positivo, quindi non verrà fornito come input.
Emigna,

2

C #, 257 244 243 244 233 222 byte

using System.Linq;z=m=>{int b=int.Parse(m.OrderBy(s=>int.Parse(s+"")).Last()+""),n=0,p=0;if(b<9&m.Length>1){for(int i=m.Length-1;i>=0;i--)n+=int.Parse(m[i]+"")*(int)System.Math.Pow(b+1,p++);return z(n+"");}else return m;};

Well, C# always takes a lot of bytes but this is just ridiculous. None of the built-ins can handle an arbitrary base, so I had to calculate the conversion myself. Ungolfed:

using System.Linq;
z = m => {
int b = int.Parse(m.OrderBy(s => int.Parse(s + "")).Last()+""), n = 0, p = 0; //Get the max digit in the string
if (b < 9 & m.Length > 1) //if conditions not satisfied, process and recurse
{
    for (int i = m.Length - 1; i >= 0; i--)
        n += int.Parse(m[i] + "") * (int)System.Math.Pow(b+1, p++); //convert each base-b+1 representation to base-10
    return z(n + ""); //recurse
}
else return m; };

1

Mathematica, 92 bytes

f[x_]:=FromDigits[s=IntegerDigits@x,d=Max@s+1];(z=f@#;While[d!=10&&Length@s>1,h=f@z;z=h];z)&

1

Javascript (ES6) with 0 arrow function, 74 bytes

function f(a){a>9&&b=Math.max(...a)<9&&f(parseInt(a,b+1));alert(a)}f('11')

3
Welcome to PPCG! :) This is probably a very nice answer, but I can't tell without an explanation. I (and probably others) never upvote answers that don't contain explanations.
Stewie Griffin

1
Why are you calling f('11') after the function? Unless I'm missing something that only looks to be usage not actually part of the submission. If so, you should take it out of the code section and put it in your explanation (when you add one) and update your byte count to 67.
PunPun1000

1

K4, 19 bytes

Solution:

{(1+|/x)/:x:10\:x}/

Examples:

q)\
  {(1+|/x)/:x:10\:x}/413574
83911
  {(1+|/x)/:x:10\:x}/13552
159
  {(1+|/x)/:x:10\:x}/17
3
  {(1+|/x)/:x:10\:x}/41253
29    

Explanation:

Use /: built-in to convert base.

{(1+|/x)/:x:10\:x}/ / the solution
{                }/ / converge lambda, repeat until same result returned
            10\:x   / convert input x to base 10 (.:'$x would do the same)
          x:        / store in variable x
 (     )/:          / convert to base given by the result of the brackets
    |/x             / max (|) over (/) input, ie return largest
  1+                / add 1 to this

1

Kotlin, 97 bytes

fun String.f():String=if(length==1||contains("9"))this else "${toInt(map{it-'0'}.max()!!+1)}".f()

Beautified

fun String.f(): String = if (length == 1 || contains("9")) this else "${toInt(map { it - '0' }.max()!! + 1)}".f()

Test

fun String.f():String=if(length==1||contains("9"))this else "${toInt(map{it-'0'}.max()!!+1)}".f()
val tests = listOf(
        5 to 5,
        17 to 3,
        999 to 999,
        87654321 to 9041998,
        41253 to 29
)

fun main(args: Array<String>) {
    tests.forEach { (input, output) ->
        val answer = input.toString().f()
        if (answer != output.toString()) {
            throw AssertionError()
        }
    }
}

TIO

TryItOnline




0

C, 159 157 bytes

#include <stdlib.h>
char b[99];i=0;m=-1;c(n){do{m=-1;sprintf(b,"%d",n);i=0;while(b[i]){m=max(b[i]-48,m);i++;}n=strtol(b,0,++m);}while(b[1]&&m<10);return n;}

0

Scala, 119 bytes

if(x.max==57|x.length==1)x else{val l=x.length-1
f((0 to l).map(k=>(((x(k)-48)*math.pow(x.max-47,l-k))) toInt).sum+"")}

Try it online!

Scala, 119 bytes

if(x.max==57|x.length==1)x else f((0 to x.length-1).map(k=>(((x(k)-48)*math.pow(x.max-47,x.length-1-k))) toInt).sum+"")

Try it online!

Both methods work the same way, but in the first one I put x.length-1 in a variable, and in the second one I don't.

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.