Simplificar binario

20

Desafío

Dado un número binario como entrada por cualquier medio, "simplifique" el número usando un programa completo o una función.

Entrada

[binary]
  • binary es un número en binario que está por encima de 0.

Salida

Tome la entrada, conviértala en base 10 sin usar un incorporado, luego, si ese número contiene solo 1s y 0s, conviértalo en un número base 10 como si fuera otro número binario. Repita el proceso hasta que el número no se pueda leer en binario y envíe ese número.

Otra información

  • Si la entrada es 1, simplemente salga 1. Su programa no debe continuar simplificando infinitamente 1.

  • Este es el código de golf, por lo que la respuesta más corta en bytes para el martes (17 de noviembre) gana.

  • Si algo es confuso, deje un comentario que especifique lo que necesito aclarar y lo editaré en consecuencia.

  • No se permiten construcciones para la conversión de bases.

Ejemplos

     Input | Output

         1 | 1
      1010 | 2
      1011 | 3
   1100100 | 4
   1100101 | 5
1111110011 | 3
The_Basset_Hound
fuente
44
Podría usar un par de casos de prueba.
isaacg
¿Es la entrada una cadena ASCII, o en realidad 1's y 0's?
Tom Carpenter
@TomCarpenter 1s y 0s.
The_Basset_Hound
@isaacg Se agregaron formas de obtener 1-5 como salida.
The_Basset_Hound
¿Están permitidas las funciones que convierten una cadena en una base dada?
isaacg

Respuestas:

14

Pyth, 20 16 bytes

u?-GTG`u+yNsTG0z

4 bytes gracias a Jakube

La mitad del código ( u+yNsTG0) es simplemente el código de conversión base.

Banco de pruebas

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.

La entrada 1se maneja por el hecho de que se uda cuenta de que el valor ha dejado de cambiar.

isaacg
fuente
44
¡Felicitaciones, superaste a Dennis! Por el momento ...
Conor O'Brien
99
@ CᴏɴᴏʀO'Bʀɪᴇɴ El secreto es Pyth.
isaacg
8

CJam, 24 23 bytes

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

Pruébelo en línea en el intérprete de CJam .

Cómo funciona

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
fuente
¿Tiene que repetir los tiempos de la "10"cadena length-1, o podría omitir la disminución?
DLosc
Restar 1 de la longitud se convierte "10"en ""si el entero tiene un solo dígito. Esto asegura que el código no entre en un bucle infinito.
Dennis
2
Fascinante, capitán. }: ^ |
DLosc
7

Pip, 28 27 bytes

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

Toma entrada como argumento de línea de comando. Queremos hacer un bucle hasta a=1o que acontenga algunos caracteres además de 0 y 1. Esta última condición se prueba RM'ing todos los caracteres en t= 10froma . Si queda algo, la condición es verdadera.

Dentro del bucle, la conversión funciona de la siguiente manera:

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

Poner aal final lo imprime automáticamente.

Una solución recursiva en 28 bytes:

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

Pitón 2, 52

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

Es más fácil pensar en esto como dos funciones recursivas:

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 función gconvierte un valor decimal a binario, y la función se faplica grepetidamente mientras su argumento esté formado por los dígitos 0 y 1 ( '2'>max(`n`)) y no lo sea 1. El código de golf los contrae en una sola función insertando la definición de g(n)for f(n), reemplazando la llamada recursiva a gcon f. El caso base de n=0de ges manejado automáticamente por el cheque n>1.

xnor
fuente
Agradable :) Lo único es que se aplica el problema habitual: la Lrepr
molestia
4

Prolog, 220 212 bytes

:-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).

La explicación
p es la función principal y realiza los siguientes pasos (con ayuda de b, x, y):

  • comprueba si el número actual es mayor que 1
  • convierte un entero en una lista de representaciones ascii de dígitos
  • comprueba que todos los números son 0 o 1
  • convierte la lista ascii en una lista de enteros binarios
  • convierte la lista de enteros binarios en número decimal
  • recurre
  • se imprime cuando falla un predicado.

Editar: se guardaron 8 bytes al unificar las cláusulas p con OR.

Emigna
fuente
3

Mathematica 107 106

Con un byte guardado por 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])

Divide la entrada en sus dígitos. Si la entrada es 1, salida 1.

Si la entrada es un número que consiste en 0 y 1, conviértalo a decimal y ejecútelo nuevamente.

De lo contrario, devuelva la entrada.


j[1]

1


j[11010001]

209


j[1111110001]

1009


j[1111110011]

3

El primer paso produce 1011 que a su vez produce 3.


Aquí probamos comenzando con 1011.

j[1011]

3

DavidC
fuente
3

Javascript, 132 , 123 bytes

Bueno, no es la mejor respuesta, pero ...

Para su información, si se proporciona una entrada no válida, se muestra lo mismo al usuario.

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
fuente
1
Puede guardar 19 bytes usando en forlugar de whiley estableciendo valores directamente en la declaración (esto también reduce algunos {}), descartando algunos ;, usando la descripción de la función ES6, incremente en ilínea. Se verá así: 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, gracias por la sugerencia, pero al principio no entendí c=x=>, no funcionaba en la consola Chrome o Firefox. :( @ ן nɟuɐɯɹɐ ן oɯ, no pude entender la condición XOR y en su x=0|x/10‌lugar parseInt, he incorporado el resto de los cambios. Gracias ..
LearningDeveloper
@GauthamPJ Lo siento, de alguna manera el código se rompió durante la copia y contenía caracteres no imprimibles. Aquí está la versión correcta: 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()). Definitivamente se ejecuta en Firefox 42, prueba este violín . Tenga en cuenta que esta versión más golfizada y también su código original no funcionan 1y se ejecutarán en un bucle sin fin. c=x=>es como function c(x){}ver " Funciones de flecha ".
insertusernamehere
2

JavaScript ES6, 52

Como una función. El argumento de la función debe ser una cadena de dígitos binarios o un número cuya representación decimal contenga solo 1 y 0.

Pruebe ejecutar el fragmento a continuación en un navegador compatible con EcmaScript 6 - implementando funciones de flecha, cadenas de plantilla y operador de propagación (uso 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
fuente
1
Realmente me gusta n+=+c+nla conversión binaria. Tan elegante ...
nderscore
2

Mathematica, 62 59 55 48 bytes

Guardado 7 bytes gracias a Martin Büttner.

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

Javascript (ES7) 87 80 78 77 74 bytes

Demostración de fragmentos para admitir navegadores (actualmente solo Firefox admite todas las noches el operador exponencial)

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 bytes

Fragmento de demostración para admitir navegadores

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
fuente
1

𝔼𝕊𝕄𝕚𝕟, 37 caracteres / 54 bytes

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

Try it here (Firefox only).

No estoy seguro si el +operador cuenta como una función para la conversión binaria ...

Mama Fun Roll
fuente
1

Perl 6 , 67 bytes

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

PHP, 210 204 bytes

Es la primera vez que publico aquí, ¡espero que les guste! Incluso si obviamente no es la mejor manera de escribirlo, ¡todavía estoy feliz de mostrarlo aquí!

El código

<?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]);

Hice una función recursiva "j" que primero verificará si la entrada es igual a 1. Si es así, la función devuelve 1 como se esperaba, de lo contrario dividirá el número en una matriz para calcular el valor decimal, pero solo si el número es binario Si no es así, devolverá el número tal como está.

Código sin 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]);

He usado una declaración "foreach" en lugar de mi "for" inicial, lo que me permite una ganancia de 6 bytes, pero estoy bastante seguro de que hay mucho más por hacer.

Vincent Douay
fuente
1

PHP, 114 112 bytes

También funciona para 0. Corre con -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)devuelve una cadena que contiene todos los caracteres de la cadena (como lo array_uniquehace para las matrices). Para números binarios, esto será 0, 1o 01. Para otros números, este contendrá un dígito más grande que 1, por lo<2 lo que solo será verdadero para los números binarios.

&$s>1 es necesario para el caso especial 1 .

El resto es sencillo: recorra los bits cambiando el valor y agregando el bit actual, finalmente copie el número (convertir en cadena) a $ s para la prueba del bucle externo.

Titus
fuente
0

CoffeeScript, 92 89 bytes

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 bytes

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

Manifestación

Solo funciona en navegadores compatibles con ES6 como Firefox y 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
fuente
Si usa eval, es posible que pueda obtener un retorno implícito.
Mama Fun Roll
5 bytes más cortos con funciones eval y anónimas
Downgoat
@ ן nɟuɐɯɹɐ ן oɯ Por alguna razón, la función evaluada no funciona 1. porque no entra en el bucle, supongo
rink.attendant.6
1
@nderscore Gracias, pero la recursión fue 4 bytes más corta :-)
rink.attendant.6
0

Scala, 128 bytes

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
fuente
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 función anónima es la conversión de tipo de número ( bin2dec)
Abr001am
fuente