¿En qué base está este número?

31

Aquí hay un buen desafío fácil:

Dada una cadena que representa un número en una base desconocida, determine la base más baja posible en la que pueda estar ese número. La cadena solo contendrá 0-9, a-z. Si lo desea, puede optar por letras mayúsculas en lugar de minúsculas, pero especifíquelo. Debe generar esta base más baja posible en decimal.

Aquí hay un ejemplo más concreto. Si la cadena de entrada era "01234", es imposible que este número esté en binario, ya que 2, 3 y 4 están todos indefinidos en binario. Del mismo modo, este número no puede estar en la base 3 o en la base 4. Por lo tanto, este número debe estar en la base 5 o en una base más alta, por lo que debe generar '5'.

Su código debe funcionar para cualquier base entre la base 1 (unario, todos '0') y la base 36 ('0-9' y 'a-z').

Puede tomar entrada y proporcionar salida en cualquier formato razonable. Las conversiones de conversión de base están permitidas. Como de costumbre, se aplican las lagunas estándar, ¡y la respuesta más corta en bytes es la ganadora!

Prueba IO:

#Input          #Output
00000       --> 1
123456      --> 7
ff          --> 16
4815162342  --> 9
42          --> 5
codegolf    --> 25
0123456789abcdefghijklmnopqrstuvwxyz    --> 36
DJMcMayhem
fuente
8
¿Puedo emitir en base 36?
Leaky Nun
99
@LeakyNun Geez, espero que no.
Dennis
44
@LeakyNunYou must output this lowest possible base in decimal.
DJMcMayhem
3
@RohanJhunjhunwala Si ese es su idioma equivalente más cercano a una cadena, no veo por qué no.
DJMcMayhem
3
Por lo general, unario es todo 1 y los ceros iniciales no son estándar para ningún sistema numérico basado en la posición.
Deja de dañar a Monica el

Respuestas:

16

Jalea , 4 bytes

ṀØBi

Requiere mayúscula. Pruébalo en línea! o verificar todos los casos de prueba .

Cómo funciona

ṀØ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.
Dennis
fuente
1
En realidad son 7 bytes, no 4. Los primeros 2 caracteres son de varios bytes.
Nicomak
14
@Nicomak Esta respuesta está codificada en la página de códigos Jelly , donde todos estos caracteres están codificados como 1 byte cada uno.
Loovjo
26

Python, 27 22 bytes

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

Esto requiere que la entrada sea una cadena de bytes (Python 3) o un bytearray (Python 2 y 3).

¡Gracias a @AleksiTorhamo por jugar golf 5 bytes!

Pruébalo en Ideone .

Cómo funciona

Comenzamos tomando el máximo de la cuerda. Los puntos de código de las letras son más altos que los puntos de código de los dígitos, este carácter máximo es también la base máxima de 36 dígitos.

El punto de código de '0' - '9' es 48 - 57 , por lo que debemos restar 48 de sus puntos de código para calcular los dígitos correspondientes, o 47 para calcular la base más baja posible. Del mismo modo, los puntos de código de las letras 'a' - 'z' son 97-122 . Como 'a' representa el dígito con el valor 10 , debemos restar 87 de sus puntos de código para calcular los dígitos correspondientes, o 86 para calcular la base más baja posible. Una forma de lograr esto es la siguiente.

La diferencia entre 97 y 58 ( ':' , el carácter después de '9' ) es 39 , por lo que tomar los puntos de código del módulo 39 puede lograr la resta. Como 48% 39 = 9 , y el resultado deseado para el carácter '0' es 1 , primero restamos 8 antes de tomar el módulo de resultado 39 . Restar primero es necesario ya que de lo contrario '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
Dennis
fuente
Si lo convierte en Python 3 y toma la entrada como una cadena de bytes, puede soltar ord()y ganar en 3 bytes. :)
Aleksi Torhamo
¡Buena idea! Déjame preguntarle al OP.
Dennis
3
@AleksiTorhamo NOOOOOOOOOOOO yu do dis
Rɪᴋᴇʀ
20

Python, 25 bytes

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

Define una lambda que toma la cadena x. Encuentra el dígito más grande en la cadena (ordenado con letras por encima de los dígitos, por defecto de Python), y convierte a la base 36. Agrega 1, porque 8no está en la base 8.

Rɪᴋᴇʀ
fuente
11

Haskell, 34 bytes

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

Utiliza la mod(ord(c)-8,39)idea de Dennis.

41 bytes

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

45 bytes:

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

Salidas como Just 3.

xnor
fuente
6

Cheddar , 34 29 21 bytes

Guardado 8 bytes gracias a Dennis !!!

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

Utiliza letras minúsculas

Pruébalo en línea

Explicación

s -> (      // Input is `s`
  s.bytes    // Returns array of char codes
   .max      // Get maximum item in array
) % 39      // Modulus 39
Downgoat
fuente
1
O simplemente podría poner citas alrededor de la entrada
DJMcMayhem
12
@DJMcMayhem .___. ni siquiera sabía que mi propio idioma podría hacer eso
Downgoat
¿Qué tal en (-)&8lugar de n->n-8?
Conor O'Brien el
@ ConorO'Brien> _> _> _> Todavía no he llegado a eso. Estaba simplemente la intención de hacerlo y luego este desafío de publicación. Se f&nune bajo nal primer argumento de la función.
Downgoat
@Downgoat Oh. > _>
Conor O'Brien el
6

05AB1E , 6 bytes

{¤36ö>

Toma letras en mayúsculas.

Explicación

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

Pruébalo en línea

Emigna
fuente
Perdona mi ingenuidad con 05AB1E, pero ¿te refieres a convertir DE base 36 (a base 10)?
Keeta el
@Keeta Por supuesto que tienes razón. Mi error.
Emigna
5

Julia, 22 bytes

!s=(maximum(s)-'')%39

Hay un carácter BS (0x08) entre las comillas. Pruébalo en línea!

Dennis
fuente
lo que hace el -''hacer?
Downgoat
Resta 8 del punto de código y devuelve un entero.
Dennis
4

JavaScript (ES6), 41 37 bytes

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

Editar: Guardado 4 bytes gracias a @ edc65.

Neil
fuente
utilizar pop()para guardar 4
edc65
@ edc65 No puedo creer que no esté bajo los consejos de JavaScript.
Neil
3

Haskell, 55 40 bytes

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

Gracias @ Dennis por su enfoque. (toma eso, @xnor;))

ThreeFx
fuente
Creo que puede eliminar f=por 38 bytes ya fque no toma argumentos explícitos.
Cyoce
3

Perl 6: 18 bytes

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

Define una lambda que toma un argumento de cadena única y devuelve un entero. Divide la cadena en caracteres, encuentra la "más alta", la convierte en base 36 y agrega 1.

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

Éste usa el enfoque de módulo de Dennis. Mismo largo.

smls
fuente
2

Retina , 28 bytes

O`.
.\B

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

Pruébalo en línea! (La primera línea habilita un conjunto de pruebas separado por salto de línea).

Explicación

O`.

Esto ordena los caracteres de la entrada.

.\B

Esto elimina todos los caracteres excepto el último, por lo que las dos primeras etapas encuentran el carácter máximo.

{2`
$`
}T01`dl`_o

Estas son dos etapas que forman un bucle. El primero duplica el primer carácter y el segundo "decrementos" uno que (en sustitución de por ejemplo xcon w, acon 9y 1con 0). La última etapa encuentra un cero como primer personaje, lo elimina en su lugar. Esta es una técnica estándar para generar un rango de caracteres, dado el extremo superior. Por lo tanto, esto genera todos los "dígitos" desde 0el dígito máximo.

.

Finalmente, simplemente contamos el número de dígitos, lo que nos da la base.

Martin Ender
fuente
2

R, 99 89 85 bytes

Mira ! ¡Menos de 100 bytes!
Mira ! 10 bytes de descuento!
Mira ! ¡4 bytes de descuento!

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

Sin golf:

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.

Como a menudo, esta respuesta hace uso de la ifelsefunción:ifelse(Condition, WhatToDoIfTrue, WhatToDoElse)

Frédéric
fuente
Amo tu versión; sin embargo, tratar letras y números por separado crea esos molestos bytes adicionales. Eche un vistazo a mi solución que usa un método diferente.
Andreï Kostyrka
Su respuesta es realmente interesante. Usaré su scanmétodo para jugar al golf algunos bytes;)
Frédéric
1

PHP, 51 38 bytes

(De Dennis) ^^

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

Otra propuesta sin el truco de Dennis

<?=($a=max(str_split($argv[1])))<a?$a+1:ord($a)-86;
  • Toma la entrada como argumento $ argv [1];
  • Tomar valores de caracteres máximos (usando ASCII)
  • Si es un número (inferior a <'a' valor ascii), entonces el número de salida + 1
  • De lo contrario, el valor ASCII de salida -86 (97 para 'a' en ascii, -11 para 'a' es el undécimo dígito base)
Cripto
fuente
Es una lástima que PHP tenga nombres de funciones tan detallados: <?=base_convert(max(str_split($argv[1])),36,10)+1es una solución elegante, ¡pero con 49 bytes!
@YiminRong que puede usar en intval()lugar de lo base_convert()que se acorta a 38 bytes <?=intval(max(str_split($argn)),36)+1;tio: tio.run/##K8go@P/…
640KB
1

Octava, 20 bytes

@(a)mod(max(a)-8,39)
alephalpha
fuente
1

Java 7, 67 61 bytes

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

(m-8)%39es gracias a la asombrosa respuesta de @Dennis .

Ungolfed y código de prueba:

Pruébalo aquí.

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

Salida:

1
7
16
9
5
25
36
Kevin Cruijssen
fuente
2
En lugar de Math.max()que pueda usarm = m>c?m:c
RobAu
@RobAu Ah, por supuesto, gracias. Lo olvidé por completo. A veces olvido las cosas de codegolfing más fáciles en Java que incluso se mencionan varias veces en la publicación Consejos para Codegolfing en Java . Gracias por el recordatorio.
Kevin Cruijssen
Si cambia a Java 8, puede reemplazar toda esta función con una lambda que hace una solareduce
BlueRaja - Danny Pflughoeft
@ BlueRaja-DannyPflughoeft Lo sé, por eso lo mencioné específicamente como Java 7. Siéntase libre de publicar un Java 8 lambda como respuesta separada.
Kevin Cruijssen
@ BlueRaja-DannyPflughoeft Me pregunto si eso terminaría con menos bytes ...
RobAu
1

C89, 55 53 52 50 bytes

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

-8%39 robado descaradamente de Dennis

Prueba

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

Salida

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

Guardado 2 bytes gracias a Toby Speight

Guardado 2 bytes gracias a Kevin Cruijssen

YSC
fuente
Puede guardar 2 bytes con la declaración no prototipo: se f(char*s,int b)convierte f(s,b)char*s;.
Toby Speight
Puede ahorrar 3 bytes eliminando el paréntesis y el espacio innecesarios: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 bytes

Esta respuesta supone que la entrada está en ASCII (o idéntica en los números y letras, por ejemplo, ISO-8859 o UTF-8):

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

Simplemente iteramos a lo largo de la cadena, recordando el valor más grande visto, luego usamos la conocida conversión de módulo 39 de base- {11..36}.

Programa de prueba

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

Resultados de la prueba

00000 -> 1
123456 -> 7
ff -> 16
4815162342 -> 9
42 -> 5
codegolf -> 25
0123456789abcdefghijklmnopqrstuvwxyz -> 36
Toby Speight
fuente
¿No podrías eliminar el m = 0? Si m aparece en el nivel superior del archivo, es externo, lo que implica estática, lo que implica que se inicializa a cero.
Batman
@ Batman: sí, pero solo si no llamará f()más de una vez. Sé que casi todo es juego limpio en el golf, ¡pero mis instintos profesionales lo consideran demasiado frágil!
Toby Speight
Pensándolo mejor, podría convertirlo en un requisito externo para restablecer mentre llamadas a f(). Entonces mi programa de prueba aún podría funcionar.
Toby Speight
@ Batman: en Code Golf Meta , la opinión mayoritaria sobre la pregunta " ¿Las presentaciones de funciones tienen que ser reutilizables? " Parece estar en contra de permitir funciones de un solo uso. Así que me quedaré con lo que tengo. Gracias por la sugerencia de todos modos.
Toby Speight
1

Mathematica, 34 32 bytes

2 bytes guardados gracias a Martin Ender

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

Decidí que el método diferente merecía una nueva respuesta.

método robado inspirado en la solución de Dennis

DanTheMan
fuente
2
Use alguna notación de prefijo: Max@Mod[ToCharacterCode@#-8,39]&(lo mismo ocurre con su otra respuesta)
Martin Ender
2
Además, debe agregar &al final para indicar una función anónima.
LegionMammal978
Olvidó una @en sus dos respuestas ( ToCharacterCode@#y Characters@#).
Martin Ender
1

Mathematica, 34 32 bytes

ahorró 2 bytes gracias a Martin Ender

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

Define una función pura que toma una cadena como entrada.

Divide la entrada en caracteres, los convierte en números base 36 y devuelve el máximo +1

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

C # REPL, 17 bytes

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

Acabo de portar la respuesta de @ Dennis a C #.

stannius
fuente
1

CJam, 10 bytes

¡Gracias a Martin Ender por salvarme unos pocos bytes!

Utiliza la fórmula de Dennis

q:e>8-i39%

Pruébalo en línea

CJam, 18 16 btyes

Solución alternativa:

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

Pruébalo en línea

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
Gato de negocios
fuente
1

Scala, 25 bytes

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

Ejecútalo como:

$ scala whatbase.scala 0123456789abcdefghijklmnopqrstuvwxyz

AmazingDreams
fuente
1

R, 62 54 bytes

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

Sin golf:

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"
                                                )

Actualización: se recortaron 8 bytes debido a la redundancia de na.rm=Tbajo el supuesto de validez de entrada.

Una mejora del 39% en el tamaño en comparación con la respuesta de Frédéric . Además de eso, funciona un poquito más rápido: 0.86 segundos para 100000 repeticiones versus 1.09 segundos para la respuesta competitiva. Entonces el mío es más pequeño y más eficiente.

Andreï Kostyrka
fuente
0

Dyalog APL , 10 bytes

Solicita entrada en mayúsculas.

⌈/⍞⍳⍨⎕D,⎕A

⌈/ máximo

caracteres de entrada

⍳⍨ 1 indexado en

⎕D, todos los dígitos seguidos de

⎕A Todos los personajes

TryAPL en línea!

Adán
fuente
0

BASH 70

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

Las letras de entrada son minúsculas.

Riley
fuente
0

JavaScript, 57 50 48 bytes

7 bytes guardados gracias a @ kamaroso97 2 bytes guardados gracias a @Neil

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

Respuesta original:

n=>n.split``.map(a=>parseInt(a,36)).sort((a,b)=>b-a)[0]+1
DanTheMan
fuente
Puede eliminar 7 bytes con n=>Math.max(...n.split``.map(a=>parseInt(a,36)+1)).
kamoroso94
@ kamoroso94 No me di cuenta de que Math.maxexistía. ¡Gracias por decirme al respecto!
DanTheMan el
[...s]es más corto que s.split``.
Neil
0

Perl, 30 27 bytes

Incluye +1 para -p

Ejecutar con la entrada en STDIN, p. Ej.

base.pl <<< codegolf

base.pl:

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

LiveScript, 32 bytes

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

Un puerto de esta respuesta en mi idioma favorito que compila a JavaScript. Si el base~numberoperador trabajara con variables, podría escribir ->1+36~(it/'')sort!pop!(23 bytes), pero entra en conflicto con la función de operador de enlace: /

Gustavo Rodrigues
fuente