Trouver la somme de toutes les représentations de base possibles


20

L'objectif de ce défi est d'écrire un programme pour convertir une chaîne entrée de ce qui peut être supposé ne contenir que des lettres et des chiffres provenant d'autant de bases entre 2 et 36 que possible, et trouver la somme de base 10 des résultats.

La chaîne d'entrée sera convertie à toutes les bases dans lesquelles le nombre sera défini en fonction de l'alphabet standard pour les bases pouvant aller jusqu'à 36: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ. Par exemple, l'entrée 2Tne serait valide que dans les bases 30 et supérieures. Le programme convertirait 2T des bases 30 à 36 en décimales et additionnerait les résultats.

Vous pouvez supposer que la chaîne d'entrée ne contient que des lettres et des chiffres. Votre programme peut utiliser des majuscules ou des minuscules; il peut, mais n'a pas besoin, prendre en charge les deux.


Cas de test

Exemple d'entrée: 2T

Tableau des bases possibles

Base   Value
30     89
31     91
32     93
33     95
34     97
35     99
36     101

Sortie: 665

Exemple d'entrée: 1012

Tableau des bases possibles:

Base   Value
3      32
4      70
5      132
6      224
7      352
8      522
9      740
10     1012
11     1344
12     1742
13     2212
14     2760
15     3392
16     4114
17     4932
18     5852
19     6880
20     8022
21     9284
22     10672
23     12192
24     13850
25     15652
26     17604
27     19712
28     21982
29     24420
30     27032
31     29824
32     32802
33     35972
34     39340
35     42912
36     46694

Production: 444278

Exemple d'entrée: HELLOworld

Tableau des bases possibles

Base   Value
33     809608041709942
34     1058326557132355
35     1372783151310948
36     1767707668033969

Production: 5008425418187214

Une entrée de 0serait lue comme 0dans toutes les bases entre 2 et 36 inclus. La base 1 n'existe pas.


C'est le golf de code. Des règles standard s'appliquent. Le code le plus court en octets gagne.


5
Les buildins pour la conversion de base sont-ils autorisés?
lirtosiast

2
Cas de test important:0
Martin Ender

Dang it, j'allais poster un défi très similaire.
DanTheMan

3
@ MartinBüttner Pourquoi 0un test élémentaire important? 0est 0dans chaque base, et il n'y a rien de tel que la base 1.
Arcturus

3
@Eridan, car certaines langues peuvent essayer de convertir cela à partir de la base 1 et échouer.
Martin Ender

Réponses:


12

Python 3, 72 71 69 octets

Merci à FryAmTheEggman d'avoir enregistré un octet!

Merci à DSM pour avoir économisé 2 octets!

N=x=0
y=input()
while N<36:
 N+=1
 try:x+=int(y,N)
 except:0
print(x)

@ThomasKwa qui ajoutera un zéro, ce qui ne fonctionnera pas pour les entrées purement numériques car cela fonctionne comme vérifier si c'est la base 10 (ce qui rendra certains résultats trop grands)
Kevin W.

@FryAmTheEggman Merci! Je l'ai ajusté
Adnan

Je viens de vérifier pour vous. Le try exceptvous laissera faire range(37). Deux octets!
Sherlock9

@ Sherlock9 Cela ne fonctionnera pas pour les entrées purement numériques, celles-ci seront interprétées comme des nombres de base 10.
Adnan

Oh, bon sang. @Adnan
Sherlock9

10

Pyth, 20 19 11 octets

sm.xizd0S36

Vola ouvertement l'idée d'Adnan dans sa réponse Python.

Essayez-le ici


@orlp Vous pouvez supprimer le Scharbon
Bleu

Nan. Testez 1012.
orlp

4

Pure Bash (pas d'utilitaires), 38

En supposant que les conversions de base intégrées sont autorisées:

for((b=36;s+=$b#$1;b--));{ :;}
echo $s

Cela générera une erreur dans STDERR. Je suppose que c'est OK selon cette méta-réponse .

Sortie de test:

$ for t in 0 2T 1012 HELLOworld; do ./basesum.sh $t; done 2> /dev/null
0
665
444278
5008425418187214
$ 

3

Mathematica, 57 octets

#~Sum~{x,Max@CoefficientList[#,x]+1,36}&@FromDigits[#,x]&

Vous pouvez utiliser le formulaire infix pour le FromDigits.
LegionMammal978

3

Sérieusement, 65 octets

,û;╗rk`"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"íu`MSd:37:@x`╜¿`MΣ.

Contient non imprimable, hexdump:

2c963bbb726b6022303132333435363738394142434445464748494a4b4c4d4e4f505152535455565758595a22a175604d53643a33373a407860bda8604de42e7f

Malheureusement, je n'ai pas un bon moyen de filtrer à partir d'une liste basée sur les types. Note à soi: ajoute ça.

Prend l'entrée comme "2T"

Essayez-le en ligne (vous devrez saisir manuellement la saisie)

Explication:

,û    get input and convert to uppercase
;╗    make a copy and save to register 0
rk    explode string into list
`"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"íu`M  map the function over the list:
    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"íu    get the character's index in the string and add one to get a value in [1,36]
Sd    get maximum element (maximum base aka max_base) from list by sorting and popping the last element off and pushing it to the stack
:37:@x  push range(max_base,37)
`╜¿`M  map the function over the list:
    ╜¿    convert value in register 0 to an int, interpreting it as a base-n int (n is value from list)
Σ.    sum and print
0x7f  quit

Peut-être que sérieusement devrait avoir une commande qui produit l'alphabet et / ou les chiffres 0-9?
Arcturus

@Eridan Cela devrait sérieusement - obtenir cet index coûte la moitié des octets.
Mego

2

Matlab, 98 octets

function y=f(s)
[~,m]=max(bsxfun(@eq,s,[48:57 65:90]'));y=0;for n=max(m):36
y=y+base2dec(s,n);
end

2

Octave, 75 73 octets

function v=u(a) m([48:57 65:90])=0:35;v=sum(polyval(t=m(a),max(t)+1:36));

Explication:

function v=u(a) 
   m([48:57 65:90])=0:35; %// create a map: '0'-'9' = 0-9
                          %//               'A'-'Z' = 10-35
   t=m(a);                %// convert string to mapped values
   b=max(t)+1;            %// find minimum base
   p=polyval(t,b:36);     %// calculate polynomial for each base (vectorized)
   v=sum(p);              %// and return the sum of the resulting vector

polyvala un avantage sur le base2decfait qu'il est vectorisé, donc aucune forboucle n'est requise.

Seuls «0» .. «9» et les majuscules «A» .. «Z» sont pris en charge en entrée.


Utilisation très intelligente de polyvalvectoriser!
Luis Mendo

1

Japt , 26 octets

1+U¬r@XwYn36}0)o37 £UnX} x

Essayez-le en ligne!

Non golfé et explication

1+U¬ r@   XwYn36}0)o37 £    UnX} x
1+Uq rXYZ{XwYn36}0)o37 mXYZ{UnX} x

           // Implicit: U = input string
Uq rXYZ{   // Split U into chars, and reduce each item Y and previous value X by:
XwYn36     //  Choosing the larger of X and parseInt(Y,36),
}0         // starting at 0.
1+   )o37  // Add 1 and create a range from this number to 36.
mXYZ{UnX}  // Map each item X in this range to parseInt(U,X)
x          // and sum.
           // Implicit: output last expression

1

Pyth, 16 octets

V36 .x=+ZizhN ;Z

Essayez-le en ligne

Explication:

                 # Implicit: Z = 0, z = input
V36              # For N in range 36
    .x           # Try except
      =+Z        # Z = Z + izhN
         izhN    # Convert z from base N+1 to decimal
              ;  # Infinite ), for closing the for loop
               Z # Print Z

1

CJam, 28 27 octets

Merci à Reto Koradi pour avoir économisé 1 octet.

C'est un peu horrible ...

qA,s'[,65>+f#_:e>)37,>\fb:+

Nécessite des lettres majuscules.

Testez-le ici.

CJam n'a pas de conversion de base-36 intégrée à partir de chaînes, nous devons donc écrire les chaînes nous-mêmes. J'ai essayé toutes sortes de manigances divmod, mais cela semble être le plus court pour construire une chaîne de 36 chiffres et trouver juste l'index de chaque caractère dans cette chaîne.


q{'0-_9>7*-}%est tout aussi court.
Peter Taylor

@PeterTaylor Oh, c'est vrai ...
Martin Ender

1

Fonction C, 93 (sortie entière 32 bits uniquement)

En supposant que son OK pour que la sortie monte jusqu'à INT_MAX, alors nous pouvons le faire:

i,n,x;f(char *s){char *e;for(i=36,x=0;n=strtol(s,&e,i--),!*e&&i;)x+=*e?0:n;printf("%d\n",x);}

Le dernier cas de test implique que ce n'est probablement pas suffisant. Si c'est le cas, alors avec des entiers 64 bits, nous avons:

Fonction C, 122

#include<stdlib.h>
f(char *s){long long i=36,n,x=0;char *e;for(;n=strtoll(s,&e,i--),!*e&&i;)x+=*e?0:n;printf("%lld\n",x);}

Malheureusement, le #include <stdlib.h>est requis donc le type de retour strtoll()est correct. Nous devons utiliser long longpour gérer le HELLOworldboîtier de test. Sinon, cela pourrait être un peu plus court.

Pilote de test:

#include<stdlib.h>
f(char *s){long long i=36,n,x=0;char *e;for(;n=strtoll(s,&e,i--),!*e&&i;)x+=*e?0:n;printf("%lld\n",x);}

int main (int argc, char **argv)
{
    f("0");
    f("2T");
    f("1012");
    f("HELLOworld");
}

Sortie de test:

$ ./basesum
0
665
444278
5008425418187214
$ 

En C, pouvez-vous supprimer l'espace #include <stdlib.h>comme vous le pouvez en C ++?
Alex A.

@AlexA. Oui - je ne le savais pas - merci!
Digital Trauma

0

Python 3, 142 octets

Adnan m'a bien battu avec leur solution, mais je voulais ajouter ma propre tentative.

def f(s):
 t=0
 for x in range(37):
  n=0
  for i in s:
   try:m=int(i)
   except:m=ord(i)-55
   if x<=m:n=0;break
   n=n*x+m
  t+=n
 return t

Cette fonction ne gère que les entrées en majuscules. Ajoutez .upper()à for i in s, et il gérera les majuscules et les minuscules.


0

Scala 2.11, 93 octets

Il est exécuté sur la console scala.

val i=readLine
var s=0
for(j<-2 to 36)try{s=s+Integer.parseInt(i,j)}catch{case _:Exception=>}

0

Haskell, 97 octets

i c|'_'<c=fromEnum c-87|1<2=read[c]
f s=sum$map((`foldl1`map i s).((+).).(*))[1+i(maximum s)..36]

Ne prend en charge que les caractères minuscules. Exemple d'utilisation:

f "2t"           -> 665
f "helloworld"   -> 5008425418187214

C'est tellement énorme, car je dois implémenter moi-même la conversion de char en ASCII et la base. Les fonctions prédéfinies correspondantes se trouvent dans des modules qui nécessitent des importations encore plus coûteuses.

Comment ça marche: iconvertit un caractère cen sa valeur numérique (par exemple i 't'-> 29). fcalcule la valeur de la chaîne d'entrée pour chaque base possible et la somme. Une version non ponctuelle de la boucle interne est map (\base -> foldl1 (\value digit -> value*base + digit) (map i s)) [ ...bases... ].


0

JavaScript (ES6), 86 octets

s=>eval(`p=parseInt;b=2;[...s].map(d=>(v=p(d,36))>b?b=v:0);for(r=0;++b<37;)r+=p(s,b)`)

Explication

s=>
  eval(`                     // use eval to enable for loop without return keyword or {}
    p=parseInt;
    b=2;                     // b = minimum base of s
    [...s].map(d=>           // iterate through each digit d
      (v=p(d,36))            // get it's base-36 value
        >b?b=v:0             // set b to the max value
    );
    for(r=0;++b<37;)         // r = sum of all base values
      r+=p(s,b)              // add each base value from b to 36 to r
  `)                         // implicit: return r

Tester


&&b=venregistre 1 octet de plus ?b=v:0.
Neil

@Neil L'avez-vous testé? Je suis à peu près sûr que ce serait une main gauche invalide.
user81655

Désolé, je l'ai confondu avec un cas similaire dans un autre golf.
Neil

0

Perl 6 , 35 octets

{[+] map {+(":$^a"~"<$_>")||0},^37}

usage:

# store it somewhere
my &code = {[+] map {+(":$^a"~"<$_>")||0},^37}

say code 'HELLOworld' # 5008425418187214

say map &code, <2T 1012>
# (665 444278)

say code 'qwertyuiopasdfghjklzxcvbnm1234567890'
# 79495849566202185148466281109757186006261081372450955140

0

Ceylan, 100 96 octets

Integer b(String s)=>sum(((any(s*.letter)then 11else 2)..36).map((r)=>parseInteger(s,r)else 0));

J'ai d'abord eu cette version plus simple ne prenant que 69 octets:

Integer b(String s)=>sum((2..36).map((r)=>parseInteger(s,r)else 0));

Mais cela échoue avec le premier cas de test, retournant à la 2000000000665place de 665. ( La raison en est que le Tin 2Test analysé comme Tera, c'est-à-dire multiplie le 2 par 10 ^ 12, lorsque le radix est 10. ) Par conséquent, nous devons attraper ce cas séparément. Merci à Neil d' avoir suggéré une autre façon de faire qui a permis d'économiser 4 octets.

Formaté:

// Find sum of all possible base representations.
//
// Question:  /codegolf//q/65748/2338
// My Answer: /codegolf//a/65836/2338

Integer b(String s) =>
// take the sum of ...
        sum(
    // span from 2 to 36. (Though
    // if there are letters in there, we start at 11,
    // because the other ones can't be valid.
    // Also, parseInteger(s, 10) behaves a bit strange in Ceylon.)
    ((any(s*.letter) then 11 else 2) .. 36)
    // map each r of them to ...
        .map((r) =>
            // try parsing s as a number using base r
            parseInteger(s, r)
            // if that didn't succeed, use 0.
                    else 0
    )
);

Pouvez-vous peut-être raccourcir le code en partant de la base 11 si la chaîne contient une lettre, évitant ainsi d'avoir à utiliser la base 10 en cas particulier?
Neil
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.