Dans quelle base se trouve ce numéro?


31

Voici un beau défi facile:

Étant donné une chaîne qui représente un nombre dans une base inconnue, déterminez la base la plus basse possible dans laquelle ce nombre pourrait être. La chaîne ne contiendra que 0-9, a-z. Si vous le souhaitez, vous pouvez choisir de prendre des majuscules au lieu de minuscules, mais veuillez le préciser. Vous devez sortir cette base la plus basse possible en décimal.

Voici un exemple plus concret. Si la chaîne d'entrée était "01234", il est impossible que ce nombre soit en binaire, car 2, 3 et 4 ne sont pas tous définis en binaire. De même, ce nombre ne peut pas être en base 3 ou en base 4. Par conséquent, ce nombre doit être en base-5 ou une base supérieure, vous devez donc sortir «5».

Votre code doit fonctionner pour toute base comprise entre la base 1 (unaire, tous les «0») et la base 36 («0-9» et «a-z»).

Vous pouvez prendre des entrées et fournir des sorties dans n'importe quel format raisonnable. Les fonctions intégrées de conversion de base sont autorisées. Comme d'habitude, les échappatoires standard s'appliquent et la réponse la plus courte en octets est gagnante!

Test IO:

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

8
Puis-je sortir en base 36?
Leaky Nun

9
@LeakyNun Geez, j'espère que non.
Dennis

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

3
@RohanJhunjhunwala Si c'est votre langue équivalente la plus proche d'une chaîne, je ne vois pas pourquoi.
DJMcMayhem

3
Habituellement, les unaires sont tous des 1, et les zéros non significatifs ne sont standard pour aucun système numérique basé sur la position.
Stop Harming Monica

Réponses:


16

Gelée , 4 octets

ṀØBi

Nécessite des majuscules. Essayez-le en ligne! ou vérifier tous les cas de test .

Comment ça marche

ṀØ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
C'est en fait 7 octets, pas 4. Les 2 premiers caractères sont multi-octets.
Nicomak

14
@Nicomak Cette réponse est encodée dans la page de code Jelly , où tous ces caractères sont encodés en 1 octet chacun.
Loovjo

26

Python, 27 22 octets

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

Cela nécessite que l'entrée soit un bytestring (Python 3) ou un bytearray (Python 2 et 3).

Merci à @AleksiTorhamo d'avoir joué au golf sur 5 octets!

Testez-le sur Ideone .

Comment ça marche

On commence par prendre le maximum de la chaîne. Si les points de code des lettres sont supérieurs aux points de code des chiffres, ce caractère maximal est également le chiffre de base maximal de 36.

Les points de code «0» - «9» sont 48 - 57 , nous devons donc soustraire 48 de leurs points de code pour calculer les chiffres correspondants, ou 47 pour calculer la base la plus basse possible. De même, les points de code des lettres «a» - «z» sont 97 - 122 . Puisque «a» représente le chiffre avec la valeur 10 , nous devons soustraire 87 de leurs points de code pour calculer les chiffres correspondants, ou 86 pour calculer la base la plus basse possible. Une façon d'y parvenir est la suivante.

La différence entre 97 et 58 ( ':' , le caractère après '9' ) est de 39 , donc prendre les points de code modulo 39 peut réaliser la soustraction. Puisque 48% 39 = 9 et que le résultat souhaité pour le caractère '0' est 1 , nous soustrayons d'abord 8 avant de prendre le résultat modulo 39 . La soustraction en premier est nécessaire car sinon '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

Si vous le faites en Python 3 et prenez l'entrée comme une chaîne d'octets, vous pouvez supprimer le ord()et gagner de 3 octets. :)
Aleksi Torhamo

Bonne idée! Permettez-moi de demander au PO.
Dennis

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

20

Python, 25 octets

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

Définit un lambda qui prend la chaîne x. Recherche le plus grand chiffre de la chaîne (trié avec des lettres au-dessus des chiffres, par défaut de python), et convertit en base 36. Ajoute 1, car 8n'est pas en base 8.


11

Haskell, 34 octets

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

Utilise l' mod(ord(c)-8,39)idée de Dennis.

41 octets

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

45 octets:

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

Sorties comme Just 3.


6

Cheddar , 34 29 21 octets

8 octets enregistrés grâce à Dennis !!!

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

Utilise des lettres minuscules

Essayez-le en ligne

Explication

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


12
@DJMcMayhem .___. je ne savais même pas que ma propre langue pouvait le faire
Downgoat

Et au (-)&8lieu de n->n-8?
Conor O'Brien

@ ConorO'Brien> _> _> _> Je n'y suis pas encore arrivé. J'avais juste l' intention de le faire, puis ce défi a été affiché. Se f&nlie bassement nau premier argument de la fonction.
Downgoat

@Downgoat Oh. > _>
Conor O'Brien

6

05AB1E , 6 octets

{¤36ö>

Prend des lettres en majuscules.

Explication

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

Essayez-le en ligne


Pardonnez ma naïveté avec 05AB1E, mais voulez-vous dire convertir de la base 36 (en base 10)?
Keeta

@Keeta Vous avez bien sûr raison. Ma faute.
Emigna



4

JavaScript (ES6), 41 37 octets

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

Edit: 4 octets enregistrés grâce à @ edc65.


utiliser pop()pour enregistrer 4
edc65

@ edc65 Je n'arrive pas à croire que ce ne soit pas sous les astuces JavaScript.
Neil

3

Haskell, 55 40 octets

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

Merci @Dennis pour son approche. (prenez ça, @xnor;))


Je pense que vous pouvez supprimer f=pour 38 octets car fne prend pas d'arguments explicites.
Cyoce

3

Perl 6: 18 octets

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

Définit un lambda qui prend un seul argument de chaîne et renvoie un entier. Il divise la chaîne en caractères, trouve la "plus haute", la convertit en base 36, ajoute 1.

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

Celui-ci utilise l'approche modulo de Dennis. Même longueur.


2

Rétine , 28 octets

O`.
.\B

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

Essayez-le en ligne! (La première ligne active une suite de tests séparée par saut de ligne.)

Explication

O`.

Cela trie les caractères de l'entrée.

.\B

Cela supprime tous les caractères sauf le dernier, donc les deux premières étapes trouvent le caractère maximum.

{2`
$`
}T01`dl`_o

Ce sont deux étapes qui forment une boucle. Le premier duplique le premier caractère et le second le "décrémente" (en remplaçant par exemple xpar w, aavec 9et 1avec 0). Cette dernière étape rencontre un zéro comme premier caractère, elle le supprime à la place. Il s'agit d'une technique standard pour générer une plage de caractères, étant donné l'extrémité supérieure. Par conséquent, cela génère tous les «chiffres» du 0chiffre maximum.

.

Enfin, nous comptons simplement le nombre de chiffres, ce qui nous donne la base.


2

R, 99 89 85 octets

Regardez! Moins de 100 octets!
Regardez! 10 octets de moins!
Regardez! 4 octets de moins!

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.

Comme souvent, cette réponse utilise la ifelsefonction:ifelse(Condition, WhatToDoIfTrue, WhatToDoElse)


J'adore ta version; cependant, le traitement des lettres et des chiffres séparément crée ces octets supplémentaires embêtants. Veuillez jeter un œil à ma solution qui utilise une méthode différente.
Andreï Kostyrka

Votre réponse est en effet intéressante. J'utiliserai la scanméthode your pour jouer au golf quelques octets;)
Frédéric

1

PHP, 51 38 octets

(De Dennis) ^^

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

Autre proposition sans l'astuce de Dennis

<?=($a=max(str_split($argv[1])))<a?$a+1:ord($a)-86;
  • Prend l'entrée comme argument $ argv [1];
  • Prendre des caractères max (en utilisant ASCII)
  • S'il s'agit d'un nombre (inférieur à <'a' valeur ascii), alors sortez le numéro + 1
  • Sinon, la valeur ascii de sortie -86 (97 pour 'a' dans ascii, -11 pour 'a' est le 11e chiffre de base)

C'est dommage que PHP ait des noms de fonctions aussi verbeux: <?=base_convert(max(str_split($argv[1])),36,10)+1c'est une solution élégante, mais à 49 octets!

@YiminRong que vous pouvez utiliser intval()au lieu de base_convert()ce qui réduit à 38 octets <?=intval(max(str_split($argn)),36)+1;tio: tio.run/##K8go@P/…
640 Ko



1

Java 7, 67 61 octets

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

(m-8)%39c'est grâce à la réponse étonnante de @Dennis .

Non testé et code de test:

Essayez ici.

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

Sortie:

1
7
16
9
5
25
36

2
Au lieu de Math.max()vous pouvez utiliserm = m>c?m:c
RobAu

@RobAu Ah bien sûr, merci. J'ai complètement oublié cela. Parfois, j'oublie les choses les plus simples de codegolfing en Java qui sont même mentionnées plusieurs fois dans les conseils pour le codegolfing en Java . Merci pour le rappel.
Kevin Cruijssen

Si vous passez à Java 8, vous pouvez remplacer toute cette fonction par un lambda qui fait un seulreduce
BlueRaja - Danny Pflughoeft

@ BlueRaja-DannyPflughoeft Je sais, c'est pourquoi je l'ai spécifiquement mentionné comme Java 7. N'hésitez pas à publier un lambda Java 8 comme réponse distincte.
Kevin Cruijssen

@ BlueRaja-DannyPflughoeft Je me demande si cela finirait avec moins d'octets ..
RobAu

1

C89, 55 53 52 50 octets

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

-8%39 sans vergogne volé à Dennis

Tester

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

Sortie

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

Enregistré 2 octets grâce à Toby Speight

Enregistré 2 octets grâce à Kevin Cruijssen


Vous pouvez enregistrer 2 octets avec la déclaration non prototype: f(char*s,int b)devient f(s,b)char*s;.
Toby Speight

Vous pouvez économiser 3 octets en supprimant les parenthèses et l'espace inutiles: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 octets

Cette réponse suppose que l'entrée est en ASCII (ou identique en chiffres et lettres, par exemple ISO-8859 ou UTF-8):

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

Nous parcourons simplement la chaîne, en nous souvenant de la plus grande valeur vue, puis utilisons la conversion modulo-39 bien connue de base- {11..36}.

Programme de test

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

Résultats de test

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

Ne pourriez-vous pas supprimer le m = 0? Si m apparaît au niveau supérieur du fichier, son extern qui implique statique qui implique qu'il est initialisé à zéro.
Batman

@Batman - oui, mais seulement si vous n'appelez pas f()plus d'une fois. Je sais que presque tout est un jeu équitable dans le golf, mais mes instincts professionnels le considèrent comme trop fragile!
Toby Speight

Après réflexion, je pourrais en faire une exigence externe de réinitialisation mentre les appels vers f(). Ensuite, mon programme de test pourrait encore fonctionner.
Toby Speight

@Batman: sur Code Golf Meta , l'opinion majoritaire sur la question " Les soumissions de fonctions doivent-elles être réutilisables? " Semble s'opposer à l'autorisation de fonctions à usage unique. Je vais donc m'en tenir à ce que j'ai. Merci quand même pour la suggestion.
Toby Speight

1

Mathematica, 34 32 octets

2 octets économisés grâce à Martin Ender

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

J'ai décidé que la méthode différente méritait une nouvelle réponse.

méthode volée inspirée par la solution de Dennis


2
Utilisez une notation de préfixe: Max@Mod[ToCharacterCode@#-8,39]&(il en va de même pour votre autre réponse)
Martin Ender

2
En outre, vous devez ajouter &à la fin pour indiquer une fonction anonyme.
LegionMammal978

Vous en avez oublié une @dans vos deux réponses ( ToCharacterCode@#et Characters@#).
Martin Ender

1

Mathematica, 34 32 octets

économisé 2 octets grâce à Martin Ender

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

Définit une fonction pure qui prend une chaîne en entrée.

Divise l'entrée en caractères, les convertit en base de 36 chiffres et renvoie le maximum +1.


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

1

C # REPL, 17 octets

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

Je viens de porter la réponse de @ Dennis à C #.


1

CJam, 10 octets

Merci à Martin Ender de m'avoir sauvé quelques octets!

Utilise la formule de Dennis

q:e>8-i39%

Essayez-le en ligne

CJam, 18 16 btyes

Solution alternative:

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

Essayez-le en ligne

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 octets

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

Exécutez-le comme:

$ scala whatbase.scala 0123456789abcdefghijklmnopqrstuvwxyz


1

R, 62 54 octets

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

Mise à jour: rasé de 8 octets en raison de la redondance de na.rm=Tsous l'hypothèse de validité d'entrée.

Une amélioration de 39% de la taille par rapport à la réponse de Frédéric . En plus de cela, il s'exécute un peu plus vite: 0,86 seconde pour 100 000 réplications contre 1,09 seconde pour la réponse concurrente. Le mien est donc à la fois plus petit et plus efficace.


0

Dyalog APL , 10 octets

Invite à saisir des majuscules.

⌈/⍞⍳⍨⎕D,⎕A

⌈/ maximum

caractères d'entrée

⍳⍨ 1-indexé dans

⎕D, tous les chiffres suivis de

⎕A tous les personnages

TryAPL en ligne!


0

BASH 70

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

Les lettres d'entrée sont en minuscules.


0

JavaScript, 57 50 48 octets

7 octets enregistrés grâce à @ kamaroso97 2 octets enregistrés grâce à @Neil

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

Réponse originale:

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

Vous pouvez supprimer 7 octets avec n=>Math.max(...n.split``.map(a=>parseInt(a,36)+1)).
kamoroso94

@ kamoroso94 Je ne savais pas qu'il Math.maxexistait. Merci de m'en avoir parlé!
DanTheMan

[...s]est plus court que s.split``.
Neil

0

Perl, 30 27 octets

Inclut +1 pour -p

Exécuter avec l'entrée sur STDIN, par exemple

base.pl <<< codegolf

base.pl:

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

0

LiveScript, 32 octets

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

Un portage de cette réponse dans ma langue préférée qui se compile en JavaScript. Si l' base~numberopérateur travaillait avec des variables, je pourrais écrire ->1+36~(it/'')sort!pop!(23 octets), mais cela entre en conflit avec l'opérateur de liaison de fonction: /

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.