Simplifiez le binaire

20

Défi

Étant donné un nombre binaire entré par n'importe quel moyen, "simplifiez" le nombre en utilisant un programme complet ou une fonction.

Contribution

[binary]
  • binary est un nombre en binaire supérieur à 0.

Production

Prenez l'entrée, convertissez-la en base 10 sans utiliser de code intégré, puis si ce nombre ne contient que 1 et 0, convertissez-le en nombre en base 10 comme s'il s'agissait d'un autre nombre binaire. Répétez le processus jusqu'à ce que le nombre ne puisse pas être lu en binaire et sortez ce nombre.

Les autres informations

  • Si l'entrée est 1, sortez simplement 1. Votre programme ne devrait pas continuer à simplifier à l'infini 1.

  • C'est le golf de code, donc la réponse la plus courte en octets d'ici mardi 17 novembre l'emporte.

  • Si quelque chose prête à confusion, laissez un commentaire précisant ce que je dois clarifier et je le modifierai en conséquence.

  • Les commandes intégrées pour la conversion de base ne sont pas autorisées.

Exemples

     Input | Output

         1 | 1
      1010 | 2
      1011 | 3
   1100100 | 4
   1100101 | 5
1111110011 | 3
The_Basset_Hound
la source
4
Pourrait utiliser quelques cas de test.
isaacg
L'entrée est-elle une chaîne ASCII, ou en fait 1 et 0?
Tom Carpenter
@TomCarpenter 1s et 0s.
The_Basset_Hound
@isaacg Ajout de moyens pour obtenir 1-5 en sortie.
The_Basset_Hound
Les fonctions qui convertissent une chaîne en une base donnée sont-elles autorisées?
isaacg

Réponses:

14

Pyth, 20 16 octets

u?-GTG`u+yNsTG0z

4 octets grâce à Jakube

La moitié du code ( u+yNsTG0) est simplement le code de conversion de base.

Suite de tests

u?-GTG`u+yNsTG0z
                    z = input() (The string of 1s and 0s)
                    T = 10
u              z    Apply until the value stops changing, starting with z
                    G is the current value, a string of 0s and 1s.
 ?-GT               If G - T, e.g., G with the digits 1 and 0 removed is not empty,
     G              Return G, to end the iteration.
       u     G0     Else, reduce over G with initial value 0.
         yN         Double the running total
        +  sT       and add the next digit, cast to an int.
      `             Convert to string.

L'entrée 1est gérée par le fait que ula valeur a cessé de changer.

isaacg
la source
4
Félicitations, vous avez déjoué Dennis! Pour le moment ...
Conor O'Brien
9
@ CᴏɴᴏʀO'Bʀɪᴇɴ Le secret est Pyth.
isaacg
8

CJam, 24 23 octets

q{:~{1$++}*s__,(As*-!}g

Essayez-le en ligne dans l' interpréteur CJam .

Comment ça fonctionne

q                        Read all input.
 {                   }g  Do:
  :~                       Evaluate each character. Maps '0' -> 0 and '1' -> 1.
    {    }*                Fold; for each integer but the first:
     1$                      Copy the second-topmost integer.
       ++                    Add all three integers on the stack.
           s__             Cast to string and push two copies.
              ,(           Calculate string length and subtract 1.
                As         Push the string "10".
                  *        Repeat the string length-1 times.
                   -       Remove its elements from the string representation
                           of the integer.
                    !      Apply logical NOT.
                         If `!' pushed 1, repeat the loop.
Dennis
la source
Devez-vous répéter les temps de "10"chaîne length-1, ou pourriez-vous ignorer la décrémentation?
DLosc
Soustrayant 1 de la longueur se transforme "10"en ""si le nombre entier a un seul chiffre. Cela garantit que le code n'entre pas dans une boucle infinie.
Dennis
2
Fascinant, capitaine. }: ^ |
DLosc
7

Pip, 28 27 octets

Ta=1|aRMta:$+(^a)*2**RV,#aa

Prend l'entrée comme argument de ligne de commande. Nous voulons boucler jusqu'à ce que a=1ou acontient des caractères en plus des 0 et des 1. Cette dernière condition est testée en RMutilisant tous les caractères dans t= 10from a. S'il reste quelque chose, la condition est vraie.

À l'intérieur de la boucle, la conversion fonctionne comme suit:

a:$+(^a)*2**RV,#a

              ,#a  range(len(a))
            RV     reversed
         2**       2 to the power of each element
    (^a)*          multiplied item-wise with each digit in split(a)
  $+               Sum
a:                 and assign back to a

Mettre aà la fin l'imprime automatiquement.

Une solution récursive en 28 octets:

a<2|aRMt?a(f$+(^a)*2**RV,#a)
DLosc
la source
6

Python 2, 52

f=lambda n:n>1<'2'>max(`n`)and f(n%10+2*f(n/10))or n

Il est plus facile de voir cela comme deux fonctions récursives:

g=lambda n:n and n%10+2*g(n/10)
f=lambda n:n>1<'2'>max(`n`)and f(g(n))or n

La fonction gconvertit une valeur décimale en binaire, et la fonction fs'applique à gplusieurs reprises est longue tant que son argument est composé des chiffres 0 et 1 ( '2'>max(`n`)) et ne l'est pas 1. Le code golfed les réduit en une seule fonction en insérant la définition de g(n)for f(n), en remplaçant l'appel récursif de gwith f. Le cas de base de n=0of gest automatiquement traité par le chèque n>1.

xnor
la source
Nice :) La seule chose est que le problème habituel s'applique - le embêtant Lde repr...
Sp3000
4

Prolog, 220 212 octets

:-use_module(library(clpfd)).
x(B,N):-reverse(B,C),foldl(y,C,0-0,_-N).
y(B,J-M,I-N):-B in 0..1,N#=M+B*2^J,I#=J+1.
b(N,I):-N>47,N<50,I is(N-48).
p(N):-N>1,number_codes(N,L),maplist(b,L,Y),x(Y,B),p(B);write(N).

L'explication
p est la fonction principale et effectue les étapes suivantes (avec l'aide de b, x, y):

  • vérifie si le nombre actuel est supérieur à 1
  • convertit un entier en liste de représentations ascii de chiffres
  • vérifie que tous les nombres sont 0 ou 1
  • convertit la liste ascii en liste d'entiers binaires
  • convertit la liste entière binaire en nombre décimal
  • récurrente
  • s'imprime lorsqu'un prédicat échoue.

Edit: 8 octets enregistrés en unifiant les clauses p avec OR.

Emigna
la source
3

Mathematica 107 106

Avec un octet enregistré par DLosc.

j@d_:=(p=0;v=IntegerDigits@d;
Which[d<2,1,Complement[v,{0,1}]=={},j@Fold[#+#2 2^p++&,0,Reverse@v],1<2,d])

Divisez l'entrée en ses chiffres. Si l'entrée est 1, la sortie 1.

Si l'entrée est un nombre composé de 0 et de 1, convertissez-le en décimal et relancez-le.

Sinon, retournez l'entrée.


j[1]

1


j[11010001]

209


j[1111110001]

1009


j[1111110011]

3

La première étape donne 1011 qui à son tour donne 3.


Ici, nous testons en commençant par 1011.

j[1011]

3

DavidC
la source
3

Javascript, 132 , 123 octets

Eh bien, ce n'est pas la meilleure réponse, mais ..

Pour info, si une entrée non valide est donnée, elle affiche la même chose à l'utilisateur.

function c(x){while(x!=0&&!/[2-9]/.test(x)){for(i=r=0;x;i++)r+=x%10*Math.pow(2,i),x=parseInt(x/10);x=r}alert(x)}c(prompt())

LearningDeveloper
la source
1
Vous pouvez économiser 19 octets en utilisant forau lieu de whileet en définissant des valeurs directement dans l'instruction (cela réduit également certains {}) ;, en en supprimant certains , en utilisant la description de la fonction ES6, incrémentez en iligne. Ça va ressembler à ceci: c=x=>{for(r=0;x&&!/[2-9]/.test(x);x=r)for(i=0;x>0;r+=x%10*Math.pow(2,i++),x=parseInt(x/10));alert(x)};c(prompt()).
insertusernamehere
1
114:function c(x){while(x^0&&!/[2-9]/.test(x)){for(i=r=0;x;i++)r+=x%10*Math.pow(2,i),x=0|x/10;x=r}alert(x)}c(prompt())
Mama Fun Roll
@insertusernamehere, merci pour la suggestion, mais je n'ai pas compris c=x=>au début, ne fonctionnait pas sur la console Chrome ou Firefox. :( @ ן nɟuɐɯɹɐ ן oɯ, n'a pas pu envelopper ma tête autour de la condition XOR et au x=0|x/10‌lieu de parseInt, j'ai incorporé le reste des changements. Merci ..
LearningDeveloper
@GauthamPJ Je suis désolé, d'une manière ou d'une autre le code s'est cassé pendant la copie et contenait des caractères non imprimables. Voici la version correcte: c=x=>{for(r=0;x!=0&&!/[2-9]/.test(x);x=r)for(i=r=0;x;)r+=x%10*Math.pow(2,i++),x=parseInt(x/10);alert(x)};c(prompt()). Il fonctionne définitivement dans Firefox 42, essayez ce violon . Notez que cette version plus golfée ainsi que votre code d'origine ne fonctionnent pas 1et s'exécuteront dans une boucle sans fin. c=x=>c'est comme function c(x){}voir " Fonctions flèches ".
insertusernamehere
2

JavaScript ES6, 52

En tant que fonction. L'argument de la fonction doit être soit une chaîne de chiffres binaires, soit un nombre dont la représentation décimale ne contient que 1 et 0.

Testez l'exécution de l'extrait ci-dessous dans un navigateur compatible EcmaScript 6 - implémentation des fonctions fléchées, des chaînes de modèle et de l'opérateur de propagation (j'utilise Firefox)

f=s=>s<2|[...s+''].some(c=>(n+=+c+n,c>1),n=0)?s:f(n)

// To test
console.log=(...x)=>O.innerHTML+=x+'\n';

// Basic test cases
;[[1,1],[1010,2],[1011,3],[1100100,4],[1100101,5],[1111110011,3]]
.forEach(t=>console.log(t[0]+' -> '+f(t[0])+' expected '+t[1]))

function longtest() {
  var o=[],i;
  for (i=1;i<1e6;i++)
    b=i.toString(2),v=f(b),v!=i?o.push(b+' '+v):0;
  O.innerHTML=o.join`\n`
}
Click to run the long test <button onclick="longtest()">go</button>
<pre id=O></pre>

edc65
la source
1
Aimant vraiment n+=+c+nla conversion binaire. Si élégant ...
nderscore
2

Mathematica, 62 59 55 48 octets

Sauvegardé 7 octets grâce à Martin Büttner.

#//.a_/;Max[b=IntegerDigits@a]<2:>Fold[#+##&,b]&
alephalpha
la source
1

Javascript (ES7) 87 80 78 77 74 octets

Démonstration d'extraits pour prendre en charge les navigateurs (actuellement, seul Firefox prend en charge la nuit l'opérateur exponentiel)

f=x=>[...x].reverse(i=y=j=0).map(z=>(j|=z,y+=z*2**i++))&&j<2&y>1?f(y+[]):x
<input type="text" id="x" value="1111110011"><button onclick="o.innerHTML=f(x.value)">Run</button><div id="o"></div>

f=x=>
[...x].reverse(i=y=j=0) // reverse string as array, initialize vars
.map(z=>( // iterate over the all chatacters
    j|=z, // keep track of whether a digit higher than 1 is encountered
    y+=z*2**i++ // build decimal result from binary
))&&
j<2&y>1? // if we encountered only 1's and 0's and result > 1
    f(y+[]) // then call recursively and cast to a string
    :x // else return x

Javascript (ES6) 81 octets

Démo d'extraits pour la prise en charge des navigateurs

f=x=>[...x].reverse(i=y=j=0).map(z=>y+=z*Math.pow(2,i++,j|=z))&&j<2&y>1?f(y+[]):x
<input type="text" id="x" value="1111110011"><button onclick="o.innerHTML=f(x.value)">Run</button><div id="o"></div>

nderscore
la source
1

𝔼𝕊𝕄𝕚𝕟, 37 caractères / 54 octets

↺;ï>1⅋(⬯+ï)ĉ/^[01]+$⌿);)ï=+('ᶀ'+ï);ôï

Try it here (Firefox only).

Je ne sais pas si l' +opérateur compte comme une fonction intégrée pour la conversion binaire ...

Mama Fun Roll
la source
1

Perl 6 , 67 octets

get,{$_=0;for $^a.comb {$_+<=1;$_+=$^b};$_}...1|/<-[01]>/;say $_//1
Brad Gilbert b2gills
la source
1

PHP, 210 204 octets

C'est ma première publication ici, alors j'espère que vous l'aimerez! Même si ce n'est évidemment pas la meilleure façon de l'écrire, je suis quand même content de le montrer ici!

Le code

<?function j($a){$c=0;if($a==1){return 1;}else{if(preg_match("#^[01]+$#",$a)){$b=strlen($a);$a=str_split($a);foreach($a as$d){$c+=($d==0?0:2**($b-1));$b--;}return j($c);}else{return$a;}}}echo j($_GET[0]);

J'ai créé une fonction récursive "j" qui vérifiera d'abord si l'entrée est égale à 1. Si c'est le cas, la fonction renvoie 1 comme prévu, sinon elle divisera le nombre dans un tableau pour calculer la valeur décimale, mais seulement si le nombre est binaire. Si ce n'est pas le cas, le numéro sera renvoyé tel quel.

Code non golfé

<?
function j($a) {
  $c = 0;
  if ($a == 1) {
    return 1;
  }
  else {
    if (preg_match("#^[01]+$#", $a) {
      $b = strlen($a);
      $a = str_split($a);
      foreach ($a as $d) {
        $c += ($d == 0 ? 0 : 2 ** ($b - 1));
        $b--;
      }
      return j($c);
    }
    else {
      return $a;
    }
  }
}
echo j($_GET[0]);

J'ai utilisé une instruction "foreach" au lieu de ma déclaration initiale "for", ce qui me permet un gain de 6 octets mais je suis sûr qu'il y a beaucoup plus à faire.

Vincent Douay
la source
1

PHP, 114 112 octets

fonctionne également pour 0. Courez avec -r.

for($n=$argv[1];count_chars($s="$n",3)<2&$s>1;)for($i=$n=0;""<$c=$s[$i++];)$n+=$n+$c;echo$s;

count_chars($s,3)renvoie une chaîne contenant tous les caractères de la chaîne (comme array_uniquepour les tableaux). Pour les nombres binaires, ce sera 0, 1ou 01. Pour les autres nombres, cela contiendra un chiffre supérieur à 1, donc <2ne retournera vrai que pour les nombres binaires.

&$s>1est nécessaire pour le cas spécial 1.

Le reste est simple: parcourez les bits en décalant la valeur et en ajoutant le bit actuel, enfin copiez le nombre (converti en chaîne) dans $ s pour le test de la boucle externe.

Titus
la source
0

CoffeeScript, 92 89 octets

f=(x)->x>1&/^[01]+$/.test(x)&&f(''+x.split('').reverse().reduce ((p,v,i)->p+v*2**i),0)||x

JavaScript (ES6), 105 101 90 octets

f=y=>y>1&/^[01]+$/.test(y)?f(''+[...y].reverse().reduce(((p,v,i)=>p+v*Math.pow(2,i)),0)):y

Démo

Fonctionne uniquement dans les navigateurs compatibles ES6 tels que Firefox et Microsoft Edge

f=y=>y>1&/^[01]+$/.test(y)?f(''+[...y].reverse().reduce(((p,v,i)=>p+v*Math.pow(2,i)),0)):y

// Snippet stuff
$(`form`).submit((e) => {
  document.getElementById(`y`).textContent = f(document.getElementById(`x`).value);
  e.preventDefault()
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
  <label>Input:
    <input pattern=^[01]+$ required id=x>
  </label>
  <button type=submit>Go</button>
  <p>Output:
    <output id=y></output>
  </p>
</form>

rink.attendant.6
la source
Si vous utilisez eval, vous pourrez peut-être retirer un retour implicite.
Mama Fun Roll
5 octets plus court avec les fonctions eval et anonymes
Downgoat
@ ן nɟuɐɯɹɐ ן oɯ Pour une raison quelconque, la fonction évaluée ne fonctionne pas avec 1. parce qu'il n'entre pas dans la boucle, je suppose
rink.attendant.6
1
@nderscore Merci, mais la récursivité était plus courte de 4 octets :-)
rink.attendant.6
0

Scala, 128 octets

def b(s:String):String=if(s.matches("[10]{2,}"))b(""+s.reverse.zipWithIndex.collect{case('1',i)=>Math.pow(2,i)}.sum.toInt)else s
Jacob
la source
0

Matlab (115)

@(a)num2str(sum((fliplr(a)-48).*arrayfun(@(x)2^x,0:nnz(a)-1)));a=ans(input('','s'));while(find(a<50))a=ans(a);end,a

  • La fonction anonyme est la conversion de type numérique ( bin2dec)
Abr001am
la source