Convertisseur binaire en décimal
Pour autant que je puisse voir, nous n'avons pas de défi de conversion binaire en décimal simple.
Écrivez un programme ou une fonction qui prend un entier binaire positif et génère sa valeur décimale.
Vous n'êtes pas autorisé à utiliser les fonctions de conversion de base intégrées. Les fonctions de nombre entier à décimal (par exemple, une fonction qui se transforme 101010
en [1, 0, 1, 0, 1, 0]
ou "101010"
) sont exemptées de cette règle et donc autorisées.
Règles:
- Le code doit prendre en charge les nombres binaires jusqu'à la valeur numérique la plus élevée prise en charge par votre langue (par défaut)
- Vous pouvez choisir d'avoir des zéros non significatifs dans la représentation binaire
- La sortie décimale peut ne pas avoir de zéros non significatifs.
- Les formats d'entrée et de sortie sont facultatifs, mais il ne peut pas y avoir de séparateurs entre les chiffres.
(1,0,1,0,1,0,1,0)
n'est pas un format d'entrée valide, mais les deux10101010
et le(["10101010"])
sont.- Vous devez prendre l'entrée dans le sens "normal". ne l'
1110
est14
pas7
.
- Vous devez prendre l'entrée dans le sens "normal". ne l'
Cas de test:
1
1
10
2
101010
42
1101111111010101100101110111001110001000110100110011100000111
2016120520371234567
Ce défi est lié à quelques autres défis, par exemple ceci , ceci et cela .
code-golf
base-conversion
binary
Stewie Griffin
la source
la source
-1
(32 1's
et64 1's
)round(x)==x
vous allez bien :)2.000
est une sortie acceptée pour10
.Réponses:
Gelée , 5 octets
Essayez-le en ligne!
Explication
Le casting
D
est une monade (fonction unique argument): chiffres, en tournant1234
dans[1, 2, 3, 4]
.Ḥ
est une monade qui double son argument unique.+
est une dyade (fonction à deux arguments) qui ajoute ses arguments gauche et droit.De là, cela devient un peu délicat.
Voici ce qui se passe au moment de l'analyse
D
,,Ḥ
et+
sont lus. La chaîne ressemble[D, Ḥ, +]
.Les deux caractères suivants sont des quicks , qui agissent comme des opérateurs de suffixe au moment de l'analyse sur les liens (fonctions) que nous avons lus jusqu'à présent.
Quand
¥
est lu, les deux derniers liens sont sautés et remplacés par un lien qui agit comme la dyade formée en les composant. Alors maintenant, la chaîne ressemble[D, dyad(Ḥ+)]
.Quand
/
est lu, le dernier lien (qui devrait être une dyade) est sauté et remplacé par une monade qui se replie en utilisant cette dyade (intuitivement:f/
prend une liste, y remplace les virgulesf
et évalue le résultat.)La chaîne finale ressemble à
[D, fold(dyad(Ḥ+))]
deux monades.Voici ce qui se passe au moment de l'exécution
L'entrée (un nombre) est implicitement lue dans la valeur de travail (disons,
101010
).D
est exécuté, en remplaçant la valeur de travail par ses chiffres ([1,0,1,0,1,0]
).fold(dyad(Ḥ+))
est exécuté, en remplaçant la valeur de travail par1∗0∗1∗0∗1∗0
, où∗
est la dyadeḤ+
.Alors qu'est-ce que cela
x∗y
évalue?Dans une définition dyadique, la valeur de travail est d' abord la gauche argument
x
.Ḥ
, la double monade, double cette valeur. La valeur de travail est maintenant2x
.+
, la dyade plus , n'a pas d'argument correct, c'est donc un crochet : un modèle syntaxique spécial dans lequel le bon argument de cette dyade est injecté+
. Cela donne2x + y
la valeur de travail finale, qui est retournée.Donc, l'expression entière s'évalue à:
la source
Python 2,
49373130 octetsMaintenant, cela prendra un nombre binaire dans une représentation décimale, car Python peut gérer des entiers arbitrairement grands.
merci à xnor pour avoir sauvé un octet :)
La façon la plus simple de voir comment cela fonctionne est de voir une formule de base pour convertir le binaire en décimal:
Il s'agit d'une méthode de conversion «standard». Vous pouvez développer la troisième ligne comme suit:
Et c'est essentiellement ce que fait la méthode récursive que j'ai faite.
Solutions alternatives que j'avais:
la source
n%5
oun%2
au lieu den%10
.05AB1E , 6 octets
Code:
Pour l'explantion, prenons l'exemple 101010 . Nous commençons par le chiffre 1 (qui est représenté par le premier chiffre). Après cela, nous avons deux cas:
Donc, pour le cas 101010 , ce qui suit est calculé:
Explication du code:
Utilise le codage CP-1252 . Essayez-le en ligne!
la source
Haskell,
16111 + 57 = 168 octets+57 octets pour les drapeaux de compilation
-XOverloadedStrings
,-XOverlappingInstances
et-XFlexibleInstances
.Le défi a un format d'E / S lourd , car il dépend fortement de la façon dont les types de données sont exprimés dans le code source. Ma première version (16 octets), à savoir
prend une liste d'entiers, par exemple
[1,0,1,0,1,0]
et a été déclaré invalide parce que des listes Haskell littérales se trouvent,
entre les éléments. Les listes en soi ne sont pas interdites. Dans ma nouvelle version, j'utilise la même fonction, désormais nomméef
, mais je surcharge "Citer les séquences de caractères fermées". La fonction prend toujours une liste d'entiers comme vous pouvez le voir dans l'annotation de type[Int] -> Int
, mais les listes avec des entiers à un chiffre peuvent maintenant être écrites comme"1234"
, par exemplequi évalue à
42
. Malchanceux Haskell, car le format de liste natif ne correspond pas aux règles du défi. Btw,f [1,0,1,0,1,0]
fonctionne toujours.la source
(1,0,1,0,1,0,1,0)
n'est pas un format d'entrée valide, mais les deux10101010
et le(["10101010"])
sont." en outre, un commentaire suggère que le tableau de caractères est acceptable si c'est ainsi qu'une entrée de chaîne est interprétée.10101010
,"10101010"
ou quelque chose de similaire et de le faire fonctionner, la soumission est valide. Vous pouvez l'appeler une chaîne, une liste, un entier ou autre. La saisie[1][0][1][0]
ou[1,0,1,0]
n'est pas correcte. Fondamentalement, il devrait être possible de frapper un tas de uns et de zéros dans une rangée quelque part. Est-ce clair?Rétine, 15 octets
Convertit du binaire en unaire, puis unaire en décimal.
Essayez-le en ligne
la source
PHP, 44 octets
J'aurais juré avoir déjà vu cette question. Enfin bon.
Lit le nombre de gauche à droite, décale vers la gauche et ajoute le bit actuel.
la source
JavaScript (ES6),
3331 octetsEdit: plus court mais moins doux: 2 octets économisés grâce à @ETHproductions.
la source
.map
est plus court:s=>[...s].map(c=>+c+r+r,r=0)|r
s=>[...s].map(c=>r+=+c+r,r=0)|r
Labyrinthe ,
1715 octetsEssayez-le en ligne!
Labyrinth est un langage bidimensionnel basé sur la pile. Dans le labyrinthe, l'exécution du code suit le chemin du code comme un labyrinthe avec des espaces agissant comme des murs et commençant par le caractère non spatial le plus à gauche. Le flux de code est déterminé par le signe du haut de la pile. Puisque la pile a des zéros implicites en bas, les quatre premières instructions (
-+:+
) n'ont aucun effet.Boucle commençant au
,
,
Poussez la valeur de code ascii du caractère d'entrée suivant à la fin de la pile, ou appuyez sur -1 si EOF._48
pousse 48 en haut de la pile-
Pop y, pop x, poussezx-y
. Les instructions précédentes ont pour effet de soustraire 48 de l'entrée donnant 0 pour "0" et 1 pour "1".+
Pop y, pop x, poussezx+y
.:
Dupliquez le haut de la pile+
Ceci et l'instruction précédente ont pour effet de multiplier la valeur actuelle par 2Ainsi, la partie circulaire du code, en effet, multiplie le nombre actuel par 2 et ajoute un 1 ou un 0 selon que le caractère 1 ou 0 a été entré.
Queue
Si le haut de la pile est négatif (ce qui signifie que EOF a été trouvé), le code tournera à gauche à la jonction (en direction du point-virgule).
)
Incrémenter le haut de la pile pour obtenir 2/
Pop y, pop x, appuyez sur x / y (division entière). Cela a pour effet d'annuler le dernier*2
de la boucle.!
Affiche la représentation entière du haut de la pile. À ce stade, le programme se retourne car il a atteint une impasse, puis se termine avec une erreur car il essaie de diviser par zéro.Merci à @Martin Ender de m'avoir sauvé 2 octets (et de m'avoir appris à mieux penser dans Labyrinth).
la source
_48-
vous, vous pouvez simplement le faire,#%
mais malheureusement je ne vois pas comment cela pourrait aider avec le nombre d'octets.`)
au lieu de;_2
bien.#%
. Pouvez-vous expliquer comment cela fonctionne en remplacement_48-
de la conversion de ascii en int. Merci pour l')
astuce. Je vais faire ce changement.#
c'est juste court pour_2
. Bien qu'il_2%
ne s'agisse pas d'une méthode de conversion générale pour ASCII en entier, cela fonctionne ici car vous n'êtes intéressé que par les deux premiers chiffres comme entrée possible. Une alternative serait_1&
(puisque modulo 2 extrait simplement le bit le moins significatif).#%
) pour raccourcir le code dans son ensemble.Brain-Flak ,
46, 28 octetsEssayez-le en ligne!
Beaucoup d'octets enregistrés grâce à @Riley!
Étant donné que brain-flak ne peut pas prendre d'entrée binaire, l'entrée est une liste de «0 et de 1».
Explication:
la source
([]){({}[()]<({}<>({}){})><>)}<>
([]){{}({}<>({}){})<>([])}<>
Java,
84794648 octetsModifié en
long
/ 48 octets:A fait du golf / 46 octets:
Merci à @Geobits! / 79 octets:
84 octets:
la source
s
devrait êtrechar[]
. J'espère que c'est permis ...Befunge-98, 12 octets
Essayez-le en ligne!
Lit un caractère à la fois depuis l'entrée, le convertit en 0 ou 1 en prenant sa valeur modulo 2 (0 est char (48), 1 est char (49)), puis utilise l'algorithme habituel de doubler la valeur actuelle et d'ajouter le nouveau chiffre à chaque fois.
Bonus: Cela fonctionne avec n'importe quel type de chaîne d'entrée, j'essaie depuis un certain temps maintenant de trouver une combinaison amusante d'entrée-> sortie, mais je n'ai pas pu produire quoi que ce soit (malheureusement, "réponse" = 46). Peut tu?
la source
Javascript (ES7)
414036 octetsprend une chaîne en entrée
Rasé d'un octet grâce à ETHproductions
la source
**
est bizarre, mais agréable de l'utiliser ici.1<<b.length
ferait la même chose, mais il faudrait des parenthèses pour éviter d'être analysé comme(c*1)<<(b.length+...)
. Je pense que vous pouvez enregistrer un octet en le remplaçantb[0]
parb+b
( voir ici ).C # 6,
853736 octetsla source
05AB1E , 7 octets
Essayez-le en ligne!
Explication
la source
C, 53
Identique à ma réponse javascript
Test Ideone
la source
v
et enc
tant que variables globales (bien que vous deviez changer le nom dev
, car c'est déjà le nom de la fonction) comme ceci:w=0;c;v(char*s){while(c=*s++)w+=w+c-48;return w;}
w,c;
mais je ne veux pas utiliser de globaux quand la réponse est une fonction (même dans code-golf)=0
.Perl, 25 octets
-3 octets grâce à @Dom Hastings.
24 octets de code + 1 octet pour l'
-p
indicateur.Pour l'exécuter:
Explications:
la source
Pushy , 10 octets
Prend entrée comme une liste de 0/1 sur la ligne de commande:
$ pushy binary.pshy 1,0,1,0,1,0
.L'algorithme montre vraiment la beauté d'avoir une deuxième pile:
Cette méthode fonctionne car la pile sera doublée
stack length - n
fois avant d'atteindre le nombren
, qui est ensuite vidé dans la deuxième pile pour plus tard. Voici à quoi ressemble le processus d'entrée101010
:la source
Matlab, 30 octets
Le dernier cas de test a des erreurs d'arrondi (à cause de
double
), donc si vous avez besoin d'une précision totale:avec 47 octets.
la source
@(x)sum(2.^(find(flip(x)-48)-1))
qu'il donnera le résultat correct pour tous les cas pour 32 octets.flip
fonctionne commefliplr
six
est unidimensionnel.f=@(x)..; f('1111001010')
.Rétine , 12 octets
Le nombre d'octets suppose un codage ISO 8859-1.
Essayez-le en ligne!
Solution alternative:
Explication
Cela sera probablement plus facile à expliquer sur la base de mon ancienne version, moins golfée, puis en montrant comment je l'ai raccourcie. J'ai utilisé pour convertir le binaire en décimal comme ceci:
La seule façon raisonnable de construire un nombre décimal dans Retina est de compter les choses (car Retina a quelques fonctionnalités qui lui permettent d'imprimer un nombre décimal représentant un montant). La seule approche possible est donc de convertir le binaire en unaire, puis de compter le nombre de chiffres unaires. La dernière ligne fait le comptage, donc les quatre premiers convertissent le binaire en unaire.
Comment fait-on cela? En général, pour convertir d'une liste de bits en un entier, nous initialisons le résultat en
0
puis parcourons les bits du plus grand au moins significatif, doublons la valeur que nous avons déjà et ajoutons le bit actuel. Par exemple, si le nombre binaire est1011
, nous calculerions vraiment:Où j'ai marqué les bits individuels pour plus de clarté.
L'astuce pour le faire en unaire est a) que doubler signifie simplement répéter le nombre et b) puisque nous comptons les
1
s à la fin, nous n'avons même pas besoin de distinguer0
s et1
s dans le processus. Cela deviendra plus clair dans une seconde.Ce que fait le programme, c'est qu'il ajoute d'abord une virgule au début comme marqueur de la quantité d'entrée que nous avons déjà traitée:
À gauche du marqueur, nous aurons la valeur que nous accumulons (qui est correctement initialisée à la représentation unaire de zéro), et à droite de la valeur sera le bit suivant à traiter. Maintenant, nous appliquons la substitution suivante dans une boucle:
Il suffit de regarder
,(.)
et$1,
cela déplace le marqueur d'un bit vers la droite à chaque fois. Mais nous insérons également$`
, qui est tout ce qui se trouve devant le marqueur, c'est-à-dire la valeur actuelle, que nous doublons. Voici les étapes individuelles lors du traitement de l'entrée1011
, où j'ai marqué le résultat de l'insertion$`
au-dessus de chaque ligne (il est vide pour la première étape):Vous verrez que nous avons conservé et doublé le zéro avec tout le reste, mais comme nous les ignorons à la fin, peu importe la fréquence à laquelle nous les avons doublés, tant que le nombre de
1
s est correct. Si vous les comptez, il y a11
en a, exactement ce dont nous avons besoin.Cela laisse donc la question de savoir comment jouer au golf à 12 octets. La partie la plus chère de la version 18 octets doit utiliser le marqueur. Le but est de s'en débarrasser. Nous voulons vraiment doubler le préfixe de chaque bit, donc une première idée pourrait être la suivante:
Le problème est que ces substitutions se produisent simultanément, donc le premier bit n'est pas doublé pour chaque bit, mais il est copié une seule fois à chaque fois. Pour l'entrée,
1011
nous obtiendrions (marquant l'inséré$`
):Nous devons toujours traiter l'entrée de manière récursive afin que le premier préfixe doublé soit à nouveau doublé par le second et ainsi de suite. Une idée est d'insérer des marqueurs partout et de les remplacer à plusieurs reprises par le préfixe:
Après avoir remplacé chaque marqueur par le préfixe pour la première fois, nous devons nous rappeler où se trouvait le début de l'entrée.Nous insérons donc également les sauts de ligne et utilisons l'
%
option pour nous assurer que le prochain$`
ne récupère que le saut de ligne le plus proche.Cela fonctionne, mais c'est encore trop long (16 octets lors du comptage de
1
s à la fin). Et si on retournait les choses? Les endroits où nous voulons insérer des marqueurs sont identifiés par\B
(une position entre deux chiffres). Pourquoi ne pas simplement insérer des préfixes dans ces positions? Cela fonctionne presque, mais la différence est que dans la solution précédente, nous avons en fait supprimé un marqueur dans chaque substitution, et c'est important pour mettre fin au processus. Cependant, ce\B
ne sont pas des personnages mais seulement des positions, donc rien n'est supprimé. On peut cependant arrêter le\B
de la correspondance en insérant à la place un caractère non numérique à cet endroit. Cela transforme la frontière non mot en une frontière de mot, ce qui équivaut à supprimer le caractère marqueur plus tôt. Et c'est ce que fait la solution à 12 octets:Juste pour être complet, voici les différentes étapes du traitement
1011
, avec une ligne vide après chaque étape:Encore une fois, vous constaterez que le dernier résultat contient exactement 11
1
s.Comme exercice pour le lecteur, pouvez-vous voir comment cela se généralise assez facilement à d'autres bases (pour quelques octets supplémentaires par incrément dans la base)?
la source
T-SQL, 202 octets
la source
PHP, 64 octets
Nous inversons notre nombre binaire, le divisons en ses chiffres composants et les additionnons en fonction de la position.
la source
Utilitaires Bash + GNU, 29 octets
E / S via stdin / stdout.
L'
sed
expression divise le binaire en chaque chiffre et construit une expression RPN pourdc
évaluer.la source
PowerShell v2 +, 55 octets
Cela sembletrop long ...Je n'arrive pas à jouer au golf - des conseils appréciés.Explication
la source
JavaScript (ES6), 32 octets
La récursion sauve à nouveau le jour! Bien que le paramétrage semble un peu long ...
la source
[...n]
il être entouré de parenthèses?Mathematica,
271311 octetsAccepte un
List
de bits comme entrée (par exemple{1, 0, 1, 1, 0}
- représentation binaire de Mathematica du nombre22
)la source
Characters
fonction.IntegerDigits
en premier lieu.D
, qui fait la même chose queIntegerDigits
Clojure,
1141056341 octetsV4: 41 octets
-22 octets grâce à @cliffroot. Puisqu'il
digit
s'agit d'un caractère, il peut être converti en son code viaint
, puis en soustraire 48 pour obtenir le nombre réel. La carte a également été prise en compte. Je ne sais pas pourquoi cela semblait nécessaire.V3: 63 octets
-42 octets (!) En jetant un œil à d'autres réponses. Ma "fermeture éclair" était évidemment très naïve. Au lieu d'élever 2 à la puissance de l'endroit actuel, puis de le multiplier par le chiffre actuel et d'ajouter le résultat à l'accumulateur, il multiplie simplement l'accumulateur par 2, ajoute le chiffre actuel, puis l'ajoute à l'accumulateur. Converti également la fonction de réduction en macro pour raser un peu.
Merci à @nimi et @Adnan!
Ungolfed:
V2: 105 octets
-9 octets en inversant la chaîne, donc je n'ai pas besoin de créer une plage décroissante maladroite.
V1: 114 octets
Eh bien, je ne gagne certainement pas! Pour ma défense, c'est le premier programme que j'ai jamais écrit qui convertit entre les bases, j'ai donc dû apprendre à le faire. Cela n'aide pas non plus à
Math/pow
renvoyer un double qui nécessite une conversion à partir de, etInteger/parseInt
n'accepte pas de caractère, donc le chiffre doit être encapsulé avant de passer.Zippe la chaîne avec un index décroissant représentant le numéro de lieu. Réduit la liste résultante.
Ungolfed:
la source
#(reduce(fn[a b](+(* a 2)(-(int b)48)))0 %)
version améliorée. Déplacement d'unemap
partie du code directement dansreduce
, modification de la méthode d'analyse des entiers, création d'une fonction externe avec une syntaxe lambda abrégée.int
peut être utilisé pour analyser !? Cela va tomber comme 10 octets dans chaque défi que j'ai fait ici lol.Perl,
211916 + 4 = 20 octets-4 octets grâce à @Dada
Courez avec
-F -p
(y compris l'espace supplémentaire après leF
). Canaliser les valeurs vers la fonction à l'aide deecho -n
Courir comme
echo -n "101010" | perl -F -pE '$\+=$_+$\for@F}{'
Je pense que cela est suffisamment différent de la réponse de @ Dada pour mériter sa propre entrée.
Explication:
Cela utilise mon algorithme personnel de choix pour la conversion binaire en décimal. Étant donné un nombre binaire, démarrez votre accumulateur à 0 et parcourez ses bits un par un. Doublez l'accumulateur à chaque bit, puis ajoutez le bit lui-même à votre accumulateur, et vous vous retrouvez avec la valeur décimale. Cela fonctionne parce que chaque bit finit par être doublé le nombre approprié de fois pour sa position en fonction du nombre de bits restants dans le nombre binaire d'origine.
la source
perl -F -pE '$\+=$_+$\for@F}{'
R (32 bits), 64 octets
L'entrée de la fonction doit être donnée sous forme de caractère. Les fonctions de base de R prennent en charge les entiers 32 bits.
Contribution:
Sortie:
R (64 bits), 74 octets
L'entrée de la fonction doit être donnée sous forme de caractère. Le package
bit64
doit être utilisé pour les entiers 64 bits.Contribution:
Sortie:
la source
el(strsplit(x,""))
au lieu destrsplit(x,split="")[[1]]
sauvegarder quelques octets.el
fonction - je n'étais pas au courant.Dyalog APL , 12 octets
⍞
obtenir une entrée de chaîne⍎¨
convertir chaque caractère en nombre⌽
sens inverse(
...)/
insérer la fonction suivante entre les chiffres++⊢
la somme des arguments plus le bon argumentngn rasé 2 octets.
la source
k, 8 octets
Même méthode que la réponse Haskell ci-dessus.
Exemple:
la source