In quale base si trova questo numero?


31

Ecco una bella sfida facile:

Data una stringa che rappresenta un numero in una base sconosciuta, determinare la base più bassa possibile in cui quel numero potrebbe trovarsi. La stringa conterrà solo 0-9, a-z. Se lo desideri, puoi scegliere di prendere lettere maiuscole anziché minuscole, ma specifica questo. È necessario generare questa base più bassa possibile in decimale.

Ecco un esempio più concreto. Se la stringa di input era "01234", è impossibile che questo numero sia in binario, poiché 2, 3 e 4 non sono tutti definiti in binario. Allo stesso modo, questo numero non può essere nella base 3, o nella base 4. Pertanto, questo numero deve essere nella base-5, o in una base più alta, quindi si dovrebbe produrre '5'.

Il codice deve funzionare per qualsiasi base tra base 1 (unaria, tutti gli '0') e base 36 ('0-9' e 'a-z').

È possibile accettare input e fornire output in qualsiasi formato ragionevole. Sono ammessi i built-in di conversione di base. Come al solito, si applicano scappatoie standard e la risposta più breve in byte è il vincitore!

Test IO:

#Input          #Output
00000       --> 1
123456      --> 7
ff          --> 16
4815162342  --> 9
42          --> 5
codegolf    --> 25
0123456789abcdefghijklmnopqrstuvwxyz    --> 36

8
Posso effettuare l'output nella base 36?
Leaky Nun,

9
@LeakyNun Geez, spero di no.
Dennis,

4
@LeakyNunYou must output this lowest possible base in decimal.
DJMcMayhem

3
@RohanJhunjhunwala Se questa è la tua lingua più vicina all'equivalente di una stringa, non vedo perché no.
DJMcMayhem

3
Di solito unario è tutto 1 e gli zeri iniziali non sono standard per nessun sistema numerico basato sulla posizione.
Smetti di fare del male a Monica il

Risposte:


16

Gelatina , 4 byte

ṀØBi

Richiede lettere maiuscole. Provalo online! o verifica tutti i casi di test .

Come funziona

ṀØBi  Main link. Arguments: s (string)

Ṁ     Yield the maximum of s.
 ØB   Yield "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".
   i  Find the 1-based index of the maximum in that string.

1
In realtà sono 7 byte, non 4. I primi 2 caratteri sono multi-byte.
Nicomak,

14
@Nicomak Questa risposta è codificata nella tabella codici Jelly , dove tutti questi caratteri sono codificati come 1 byte ciascuno.
Loovjo,

26

Python, 27 22 byte

lambda s:(max(s)-8)%39

Ciò richiede che l'input sia un bytestring (Python 3) o un bytearray (Python 2 e 3).

Grazie a @AleksiTorhamo per giocare a golf con 5 byte!

Provalo su Ideone .

Come funziona

Iniziamo prendendo il massimo della stringa. Questo i punti di codice delle lettere sono più alti dei punti di codice delle cifre, questo carattere massimo è anche la base massima di 36 cifre.

Il punto di codice "0" - "9" è 48 - 57 , quindi dobbiamo sottrarre 48 dai loro punti di codice per calcolare le cifre corrispondenti, o 47 per calcolare la base più bassa possibile. Allo stesso modo, i punti di codice delle lettere 'a' - 'z' sono 97 - 122 . Poiché "a" rappresenta la cifra con valore 10 , dobbiamo sottrarre 87 dai loro punti di codice per calcolare le cifre corrispondenti o 86 per calcolare la base più bassa possibile. Un modo per raggiungere questo obiettivo è il seguente.

La differenza tra 97 e 58 ( ':' , il carattere dopo '9' ) è 39 , quindi prendere i punti di codice modulo 39 può ottenere la sottrazione. Poiché il 48% 39 = 9 e il risultato desiderato per il carattere '0' è 1 , sottraggiamo prima 8 prima di prendere il risultato modulo 39 . Prima è necessario sottrarre poiché altrimenti 'u'% 39 = 117% 39 = 0 .

c    n    n-8    (n-8)%39
0    48    40     1
1    49    41     2
2    50    42     3
3    51    43     4
4    52    44     5
5    53    45     6
6    54    46     7
7    55    47     8
8    56    48     9
9    57    49    10
a    97    89    11
b    98    90    12
c    99    91    13
d   100    92    14
e   101    93    15
f   102    94    16
g   103    95    17
h   104    96    18
i   105    97    19
j   106    98    20
k   107    99    21
l   108   100    22
m   109   101    23
n   110   102    24
o   111   103    25
p   112   104    26
q   113   105    27
r   114   106    28
s   115   107    29
t   116   108    30
u   117   109    31
v   118   110    32
w   119   111    33
x   120   112    34
y   121   113    35
z   122   114    36

Se lo rendi Python 3 e prendi l'input come stringa di byte, puoi rilasciare ord()e vincere di 3 byte. :)
Aleksi Torhamo,

Bella idea! Lasciami chiedere all'OP.
Dennis,

3
@AleksiTorhamo NOOOOOOOOOOOO yu do dis
Rɪᴋᴇʀ

20

Python, 25 byte

lambda x:int(max(x),36)+1

Definisce un lambda che accetta la stringa x. Trova la cifra più grande nella stringa (ordinata con lettere sopra le cifre, per impostazione predefinita di Python) e converte in base 36. Aggiunge 1, perché 8non è in base 8.


11

Haskell, 34 byte

f s=length['\t'..maximum s]`mod`39

Usa il mod(ord(c)-8,39) idea di Dennis.

41 byte

g '0'=1
g 'W'=1
g x=1+g(pred x)
g.maximum

45 byte:

(`elemIndex`(['/'..'9']++['a'..'z'])).maximum

Uscite come Just 3.


6

Cheddar , 34 29 21 byte

Risparmiato 8 byte grazie a Dennis !!!

s->(s.bytes.max-8)%39

Usa lettere minuscole

Provalo online

Spiegazione

s -> (      // Input is `s`
  s.bytes    // Returns array of char codes
   .max      // Get maximum item in array
) % 39      // Modulus 39


12
@DJMcMayhem .___. non sapevo nemmeno che la mia lingua potesse farlo
Downgoat,

Che ne dici (-)&8invece di n->n-8?
Conor O'Brien,

@ ConorO'Brien> _> _> _> Non ci sono ancora arrivato. Avevo solo intenzione di farlo e poi questa sfida è stata pubblicata. Si f&nlega bassamente nal primo argomento della funzione.
Downgoat,

@Downgoat Oh. > _>
Conor O'Brien,

6

05AB1E , 6 byte

{¤36ö>

Prende le lettere in maiuscolo.

Spiegazione

{       # sort
 ¤      # take last
  36ö   # convert from base 36 to base 10
     >  # increment

Provalo online


Perdona la mia ingenuità con 05AB1E, ma intendi convertire DA base 36 (a base 10)?
Keeta,

@Keeta Naturalmente hai ragione. Colpa mia.
Emigna,



4

JavaScript (ES6), 41 37 byte

s=>parseInt([...s].sort().pop(),36)+1

Modifica: salvato 4 byte grazie a @ edc65.


utilizzare pop()per salvare 4
edc65,

@ edc65 Non riesco a credere che non rientri nei suggerimenti JavaScript.
Neil,

3

Haskell, 55 40 byte

f=(\y->mod(y-8)39).Data.Char.ord.maximum

Grazie @Dennis per il suo approccio. (prendilo, @xnor;))


Penso che puoi rimuovere f=per 38 byte poiché fnon accetta argomenti espliciti.
Cyoce,

3

Perl 6: 18 byte

{:36(.comb.max)+1}

Definisce un lambda che accetta un singolo argomento stringa e restituisce un numero intero. Divide la stringa in caratteri, trova la "più alta", la converte in base 36, aggiunge 1.

{(.ords.max-8)%39}

Questo utilizza l'approccio modulo di Dennis. Stessa lunghezza.


2

Retina , 28 byte

O`.
.\B

{2`
$`
}T01`dl`_o
.

Provalo online! (La prima riga abilita una suite di test separata da avanzamento riga.)

Spiegazione

O`.

Questo ordina i caratteri dell'input.

.\B

Questo rimuove tutti i personaggi tranne l'ultimo, quindi le prime due fasi trovano il massimo personaggio.

{2`
$`
}T01`dl`_o

Queste sono due fasi che formano un ciclo. Il primo duplica il primo carattere e il secondo lo "decrementa" (sostituendo ad esempio xcon w, acon 9e 1con 0). Quest'ultimo stadio incontra uno zero come primo personaggio, invece lo rimuove. Questa è una tecnica standard per generare un intervallo di caratteri, data l'estremità superiore. Quindi, questo genera tutte le "cifre" dalla 0cifra massima.

.

Infine, contiamo semplicemente il numero di cifre, che ci fornisce la base.


2

R, 99 89 85 byte

Guarda ! Meno di 100 byte!
Guarda ! 10 byte di sconto!
Guarda ! 4 byte di sconto!

ifelse((m=max(strsplit(scan(,''),"")[[1]]))%in%(l=letters),match(m,l)+10,strtoi(m)+1)

Ungolfed:

l=letters                  #R's built-in vector of lowercase letters

n=scan(what=characters())  #Takes an input from STDIN and convert it to characters

m=max(strsplit(n,"")[[1]]) #Splits the input and takes to max. 
                           #`letters` are considered > to numbers (i.e. a>1)


ifelse(m%in%l,match(m,l)+10,strtoi(m)+1) #If the max is in `letters`,
                                             #outputs the matching position of `m`in `letters` + 10 (because of [0-9]). 
                                             #Else, outputs `m` (as a number) + 1.

Come spesso, questa risposta utilizza la ifelsefunzione:ifelse(Condition, WhatToDoIfTrue, WhatToDoElse)


Adoro la tua versione; tuttavia, il trattamento separato di lettere e numeri crea quei fastidiosi byte extra. Dai un'occhiata alla mia soluzione che utilizza un metodo diverso.
Andreï Kostyrka,

La tua risposta è davvero interessante. Userò il tuo scanmetodo per giocare a golf con alcuni byte;)
Frédéric il

1

PHP, 51 38 byte

(Da Dennis) ^^

<?=(ord(max(str_split($argv[1])))-8)%39;

Altra proposta senza il trucco di Dennis

<?=($a=max(str_split($argv[1])))<a?$a+1:ord($a)-86;
  • Accetta input come argomento $ argv [1];
  • Prendi i valori di carattere massimo (usando ASCII)
  • Se si tratta di un numero (inferiore a <'a' valore ASCII), emettere il numero + 1
  • Altrimenti output ascii valore -86 (97 per 'a' in ascii, -11 per 'a' è 11a cifra base)

Peccato che PHP abbia nomi di funzioni così prolissi: <?=base_convert(max(str_split($argv[1])),36,10)+1è una soluzione elegante, ma a 49 byte!

@YiminRong è possibile utilizzare intval()al posto di base_convert()che accorcia fino a 38 byte <?=intval(max(str_split($argn)),36)+1;Tio: tio.run/##K8go@P/...
640KB



1

Java 7, 67 61 byte

int c(char[]i){int m=0;for(int c:i)m=m>c?m:c;return(m-8)%39;}

(m-8)%39è grazie alla straordinaria risposta di @Dennis .

Codice non testato e test:

Provalo qui.

class Main{
  static int c(char[] i){
    int m = 0;
    for(int c : i){
      m = m > c
           ? m
           : c;
    }
    return (m-8) % 39;
  }

  public static void main(String[] a){
    System.out.println(c("00000".toCharArray()));
    System.out.println(c("123456".toCharArray()));
    System.out.println(c("ff".toCharArray()));
    System.out.println(c("4815162342".toCharArray()));
    System.out.println(c("42".toCharArray()));
    System.out.println(c("codegolf".toCharArray()));
    System.out.println(c("0123456789abcdefghijklmnopqrstuvwxyz".toCharArray()));
  }
}

Produzione:

1
7
16
9
5
25
36

2
Invece di Math.max()te puoi usarem = m>c?m:c
RobAu il

@RobAu Ah certo, grazie. Dimenticato completamente. A volte dimentico le cose più facili da codegolfing in Java che sono anche menzionate più volte nel post Tips for Codegolfing in Java . Grazie per il promemoria.
Kevin Cruijssen,

Se passi a Java 8 puoi sostituire l'intera funzione con una lambda che fa un singoloreduce
BlueRaja - Danny Pflughoeft

@ BlueRaja-DannyPflughoeft Lo so, motivo per cui l'ho menzionato specificamente come Java 7. Sentiti libero di pubblicare un lambda Java 8 come risposta separata.
Kevin Cruijssen,

@ BlueRaja-DannyPflughoeft Mi chiedo se questo finirebbe con meno byte ..
RobAu

1

C89, 55 53 52 50 byte

f(s,b)char*s;{return*s?f(s+1,*s>b?*s:b):(b-8)%39;}

-8%39 spudoratamente rubato a Dennis

Test

test(const char* input)
{
    printf("%36s -> %u\n", input, f((char*)input,0));
}

main()
{
    test("00000");
    test("123456");
    test("ff");
    test("4815162342");
    test("42");
    test("codegolf");
    test("0123456789abcdefghijklmnopqrstuvwxyz");
}

Produzione

                               00000 -> 1
                              123456 -> 7
                                  ff -> 16
                          4815162342 -> 9
                                  42 -> 5
                            codegolf -> 25
0123456789abcdefghijklmnopqrstuvwxyz -> 36

Salvato 2 byte grazie a Toby Speight

Salvato 2 byte grazie a Kevin Cruijssen


È possibile salvare 2 byte con la dichiarazione non prototipo: f(char*s,int b)diventa f(s,b)char*s;.
Toby Speight,

È possibile salvare 3 byte rimuovendo la parentesi e lo spazio non necessari:f(s,b)char*s;{return*s?f(s+1,*s>b?*s:b):(b-8)%39;}
Kevin Cruijssen,

@KevinCruijssen thx
YSC

1

C, 55 byte

Questa risposta presuppone che l'ingresso sia in ASCII (o identico nei numeri e nelle lettere, ad esempio ISO-8859 o UTF-8):

m;f(char*s){for(m=0;*s;++s)m=m>*s?m:*s;return(m-8)%39;}

We simply iterate along the string, remembering the largest value seen, then use the well-known modulo-39 conversion from base-{11..36}.

Test program

int printf(char*,...);
int main(int c,char **v){while(*++v)printf("%s -> ",*v),printf("%d\n",f(*v));}

Test results

00000 -> 1
123456 -> 7
ff -> 16
4815162342 -> 9
42 -> 5
codegolf -> 25
0123456789abcdefghijklmnopqrstuvwxyz -> 36

Couldn't you remove the m=0? If m appears at the top level of the file, its extern which implies static which implies it is initialized to zero.
Batman

@Batman - yes, but only if you won't call f() more than once. I know that almost anything's fair game in golf, but my professional instincts regard that as too fragile!
Toby Speight

On further thought, I could make it an external requirement to reset m between calls to f(). Then my test program could still work.
Toby Speight

@Batman: on Code Golf Meta, the majority opinion on the question "Do function submissions have to be reusable?" seems to be against allowing single-use functions. So I'll stick with what I have. Thanks for the suggestion, anyway.
Toby Speight

1

Mathematica, 34 32 bytes

2 bytes saved thanks to Martin Ender

Max@Mod[ToCharacterCode@#-8,39]&

I decided the different method deserved a new answer.

method stolen inspired by Dennis' solution


2
Use some prefix notation: Max@Mod[ToCharacterCode@#-8,39]& (same goes for your other answer)
Martin Ender

2
Also, you need to add & to the end to indicate an anonymous function.
LegionMammal978

You forgot one @ in both of your answers (ToCharacterCode@# and Characters@#).
Martin Ender

1

Mathematica, 34 32 bytes

saved 2 bytes thanks to Martin Ender

Max@BaseForm[Characters@#,36]+1&

Defines a pure function that takes a string as input.

Splits the input into characters, converts them to base 36 numbers, and returns the maximum +1.


Max@BaseForm[Characters@#,36]+1&
alephalpha

1

C# REPL, 17 bytes

x=>(x.Max()-8)%39

Just ported @Dennis's answer to C#.


1

CJam, 10 bytes

Thanks to Martin Ender for saving me a few bytes!

Uses Dennis's formula

q:e>8-i39%

Try it online

CJam, 18 16 btyes

Alternative solution:

A,s'{,97>+q:e>#)

Try it online

A,s'{,97>+       e# Push the string "0123456789abcdefghijklmnopqrstuvwxyz"
          q      e# Get the input
           :e>   e# Find the highest character in the input
              #  e# Find the index of that character in the string
               ) e# Increment

1

Scala, 25 bytes

print((args(0).max-8)%39)

Run it like:

$ scala whatbase.scala 0123456789abcdefghijklmnopqrstuvwxyz


1

R, 62 54 bytes

max(match(strsplit(scan(,''),"")[[1]],c(0:9,letters)))

Ungolfed:

max(
  match( # 2: Finds the respective positions of these characters
    strsplit(scan(,''),"")[[1]], # 1: Breaks the input into characters
                                c(0:9,letters)) # 3: In the vector "0123...yz"
                                                )

Update: shaved off 8 bytes due to the redundancy of na.rm=T under the assumption of input validity.

A 39% improvement in size compared to Frédéric's answer. Besides that, it runs a wee bit faster: 0.86 seconds for 100000 replications versus 1.09 seconds for the competing answer. So the one of mine is both smaller and more efficient.


0

Dyalog APL, 10 bytes

Prompts for uppercase input.

⌈/⍞⍳⍨⎕D,⎕A

⌈/ maximum

characters of input

⍳⍨ 1-indexed into

⎕D, all digits followed by

⎕A all characters

TryAPL online!


0

BASH 70

grep -o .|sort -r|head -c1|od -An -tuC|sed s/$/-86/|bc|sed s/-/39-/|bc

Input letters are lowercase.


0

JavaScript, 57 50 48 bytes

7 bytes saved thnks to @kamaroso97 2 bytes saved thanks to @Neil

n=>Math.max(...[...n].map(a=>parseInt(a,36))+1)

Original answer:

n=>n.split``.map(a=>parseInt(a,36)).sort((a,b)=>b-a)[0]+1

You can knock off 7 bytes with n=>Math.max(...n.split``.map(a=>parseInt(a,36)+1)).
kamoroso94

@kamoroso94 I didn't realize Math.max existed. Thanks for telling me about it!
DanTheMan

[...s] is shorter than s.split``.
Neil

0

Perl, 30 27 bytes

Includes +1 for -p

Run with the input on STDIN, e.g.

base.pl <<< codegolf

base.pl:

#!/usr/bin/perl -p
\@F[unpack"W*"];$_=@F%39-9

0

LiveScript, 32 bytes

->1+parseInt (it/'')sort!pop!,36

A port of this answer in my favorite language that compile to JavaScript. If base~number operator worked with variables I could write ->1+36~(it/'')sort!pop! (23 bytes), but it conflicts with the function bind operator :/

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.