introduction
Nous avons eu quelques défis de conversion de base ici dans le passé, mais pas beaucoup conçus pour s'attaquer aux nombres de longueur arbitraire (c'est-à-dire, les nombres suffisamment longs pour dépasser le type de données entier), et parmi ceux-ci, la plupart se sentaient un peu compliqué. Je suis curieux de voir comment un changement de code de base comme celui-ci peut se produire.
Défi
Écrivez un programme ou une fonction dans la langue de votre choix qui peut convertir une chaîne d'une base en chaîne d'une autre base. L'entrée doit être le nombre à convertir (chaîne), de la base (numéro base-10), à la base (numéro base-10) et le jeu de caractères (chaîne). La sortie doit être le nombre converti (chaîne).
Voici quelques détails et règles supplémentaires:
- Le nombre à convertir sera un entier non négatif (car
-
et.
peut être dans le jeu de caractères). Il en sera de même pour la sortie. - Les zéros non significatifs (le premier caractère du jeu de caractères) doivent être tronqués. Si le résultat est zéro, un seul chiffre zéro doit rester.
- La plage de base minimale prise en charge est comprise entre 2 et 95, composée des caractères ascii imprimables.
- L'entrée du nombre à convertir, le jeu de caractères et la sortie doivent tous être du type de données chaîne. Les bases doivent être du type de données entier de base 10 (ou des nombres entiers flottants).
- La longueur de la chaîne de numéro d'entrée peut être très grande. Il est difficile de quantifier un minimum raisonnable, mais attendez-vous à ce qu'il soit capable de gérer au moins 1000 caractères et de compléter 100 caractères en moins de 10 secondes sur une machine décente (très généreux pour ce genre de problème, mais je ne veux pas vitesse pour être au centre).
- Vous ne pouvez pas utiliser les fonctions intégrées de changement de base.
- L'entrée du jeu de caractères peut être dans n'importe quel arrangement, pas seulement le 0-9a-z typique, etc.
- Supposons que seule une entrée valide sera utilisée. Ne vous inquiétez pas de la gestion des erreurs.
Le gagnant sera déterminé par le code le plus court qui remplit les critères. Ils seront sélectionnés dans au moins 7 jours sur 10, ou si / quand il y a eu suffisamment de soumissions. En cas d'égalité, le code qui s'exécute le plus vite sera le vainqueur. Si elle est suffisamment proche en vitesse / performances, la réponse qui est venue plus tôt l'emporte.
Exemples
Voici quelques exemples d'entrée et de sortie que votre code devrait être capable de gérer:
F("1010101", 2, 10, "0123456789")
> 85
F("0001010101", 2, 10, "0123456789")
> 85
F("85", 10, 2, "0123456789")
> 1010101
F("1010101", 10, 2, "0123456789")
> 11110110100110110101
F("bababab", 2, 10, "abcdefghij")
> if
F("10", 3, 2, "0123456789")
> 11
F("<('.'<)(v'.'v)(>'.'>)(^'.'^)", 31, 2, "~!@#$%^v&*()_+-=`[]{}|';:,./<>? ")
> !!~~~~~~~!!!~!~~!!!!!!!!!~~!!~!!!!!!~~!~!~!!!~!~!~!!~~!!!~!~~!!~!!~~!~!!~~!!~!~!!!~~~~!!!!!!!!!!!!~!!~!~!~~~~!~~~~!~~~~~!~~!!~~~!~!~!!!~!~~
F("~~~~~~~~~~", 31, 2, "~!@#$%^v&*()_+-=`[]{}|';:,./<>? ")
> ~
F("9876543210123456789", 10, 36, "0123456789abcdefghijklmnopqrstuvwxyz")
> 231ceddo6msr9
F("ALLYOURBASEAREBELONGTOUS", 62, 10, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
> 6173180047113843154028210391227718305282902
F("howmuchwoodcouldawoodchuckchuckifawoodchuckcouldchuckwood", 36, 95, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~`!@#$%^&*()_-+=[{]}\\|;:'\",<.>/? ")
> o3K9e(r_lgal0$;?w0[`<$n~</SUk(r#9W@."0&}_2?[n
F("1100111100011010101010101011001111011010101101001111101000000001010010100101111110000010001001111100000001011000000001001101110101", 2, 95, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~`!@#$%^&*()_-+=[{]}\\|;:'\",<.>/? ")
> this is much shorter
You cannot use built in change-of-base functions to convert the entire input string/number at once
? Plus précisément, pourrais-je utiliser un intégré pour convertir l'entrée en une base intermédiaire? Puis-je ensuite utiliser un intégré pour convertir en la base cible? Souhaitez-vous quelque choseconvert input with canonical form for given base; convert to base 10; convert to target base; convert back to specified character set with string replacement
?Réponses:
CJam, 34 octets
Le format d'entrée est
input_N alphabet input_B output_B
chacun sur une ligne distincte.Exécutez tous les cas de test.
Explication
Cela fonctionne pour le même nombre d'octets:
La seule différence est que nous construisons une chaîne au lieu de collecter tout sur la pile et de l'inverser.
la source
Python 2 ,
11511410610594 bytesSuggestions de golf bienvenues. Essayez-le en ligne!
Edit: -9 octets grâce à mbomb007. -2 octets grâce à FlipTack.
Non golfé:
la source
while z:s=d[z%t]+s;z/=t
enregistre 9 octets.z=0
ets=''
dans la déclaration de fonction pour enregistrer les octets.print
au lieu dereturn
est autorisée par défaut .Sérieusement, 50 octets
Vidage hexadécimal:
Je suis fier de celui-ci malgré sa longueur. Pourquoi? Parce que cela a parfaitement fonctionné au deuxième essai. Je l'ai écrit et débogué en 10 minutes. Le débogage d'un programme Serious représente généralement une heure de travail.
Explication:
la source
C (fonction) avec bibliothèque GMP , 260
Cela s'est avéré plus long que je ne l'avais espéré, mais le voici quand même. Le
mpz_*
truc mange vraiment beaucoup d'octets. J'ai essayé#define M(x) mpz_##x
, mais cela a donné un gain net de 10 octets.La fonction
F()
est le point d'entrée. Il convertit la chaîne d'entrée en unempz_t
multiplication successive par lafrom
base et l'ajout de l'index du chiffre donné dans la liste des chiffres.La fonction
O()
est une fonction de sortie récursive. Chaque divmod de récursion lempz_t
par leto
base. Parce que cela donne les chiffres de sortie dans l'ordre inverse, la récursivité permet effectivement aux chiffres d'être stockés sur la pile et de sortir dans le bon ordre.Pilote de test:
Ajout de nouvelles lignes et de retraits pour plus de lisibilité.
la source
JavaScript (ES6), 140 octets
Contrairement au code de @ Mwr247 (qui utilise l'arithmétique base-f pour diviser s par t à chaque fois, en collectant chaque reste au fur et à mesure), j'utilise l'arithmétique base-t pour multiplier la réponse par f à chaque fois, en ajoutant chaque chiffre de s au fur et à mesure.
Non golfé:
la source
Ruby,
11311210598979587 octetsJ'ai en quelque sorte posté ma réponse Python (en quelque sorte), alors voici une réponse Ruby. Sept octets supplémentaires grâce à Manatwork , un autre octet grâce à Martin Büttner et 8 octets supplémentaires grâce à cia_rana .
Non golfé:
la source
s=d[z%t]+s;z/=t
au lieu dez,m=z.divmod t;s=d[m]+s
?APL, 10 octets
Il s'agit d'un opérateur APL. Dans APL,
⍵
et⍺
sont utilisés pour transmettre des valeurs, tandis que⍵⍵
et⍺⍺
sont généralement utilisés pour transmettre des fonctions. J'en abuse ici pour avoir 3 arguments.⍺⍺
est l'argument gauche,⍵⍵
l'argument droit "intérieur" et⍵
l'argument droit "extérieur".Fondamentalement:
⍺(⍺⍺{...}⍵⍵)⍵
Ensuite, tout ce qui est nécessaire est
⍳
de trouver les positions de la chaîne d'entrée dans la table "from", puis d'utiliser[]
pour indexer dans la table "to" avec ces positions.Exemple:
la source
JavaScript (ES6), 175 octets
Je pensais que cela faisait assez longtemps maintenant que je pouvais soumettre celui que j'avais fait pour créer les exemples. Je peux essayer de jouer au golf un peu mieux plus tard.
la source
Japt, 9 octets
Essayez-le
la source