Semplifica binario


20

Sfida

Dato un numero binario come input attraverso qualsiasi mezzo, "semplifica" il numero usando un programma completo o una funzione.

Ingresso

[binary]
  • binary è un numero in binario superiore a 0.

Produzione

Prendi l'input, convertilo in base 10 senza usare un builtin, quindi se quel numero contiene solo 1 e 0, convertilo in un numero base 10 come se fosse un altro numero binario. Ripeti il ​​processo fino a quando il numero non può essere letto in binario e genera quel numero.

Altre informazioni

  • Se l'ingresso è 1, semplicemente emettere 1. Il tuo programma non dovrebbe continuare all'infinito semplificando 1.

  • Questo è il golf di codice, quindi vince la risposta più breve in byte entro martedì (17 novembre).

  • Se qualcosa è confuso, lascia un commento specificando cosa devo chiarire e lo modificherò di conseguenza.

  • I builtin per la conversione di base non sono ammessi.

Esempi

     Input | Output

         1 | 1
      1010 | 2
      1011 | 3
   1100100 | 4
   1100101 | 5
1111110011 | 3

4
Potrebbe usare un paio di casi di test.
isaacg,

L'input è una stringa ASCII, o in realtà 1 e 0?
Tom Carpenter,

@TomCarpenter 1s e 0s.
The_Basset_Hound

@isaacg Aggiunti modi per ottenere 1-5 come output.
The_Basset_Hound

Sono consentite funzioni che convertono una stringa in una data base?
isaacg,

Risposte:


14

Pyth, 20 16 byte

u?-GTG`u+yNsTG0z

4 byte grazie a Jakube

La metà del codice ( u+yNsTG0) è semplicemente il codice di conversione di base.

Test Suite

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'input 1è gestito dal fatto che si uaccorge che il valore ha smesso di cambiare.


4
Congratulazioni, hai superato Dennis! Per il momento ...
Conor O'Brien,

9
@ CᴏɴᴏʀO'Bʀɪᴇɴ Il segreto è Pyth.
isaacg,

8

CJam, 24 23 byte

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

Provalo online nell'interprete CJam .

Come funziona

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.

Devi ripetere i tempi delle "10"stringhe length-1o potresti saltare il decremento?
DLosc

Sottraendo 1 dalla lunghezza si trasforma "10"in ""se l'intero ha una sola cifra. Questo assicura che il codice non entri in un ciclo infinito.
Dennis,

2
Affascinante, capitano. }: ^ |
DLosc

7

Pip, 28 27 byte

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

Accetta input come argomento della riga di comando. Vogliamo ciclo fino a quando a=1o acontiene alcuni caratteri (s) oltre a 0 e di 1. Quest'ultima condizione viene verificata RM'ing tutti i caratteri in t= 10da a. Se rimane qualcosa, la condizione è vera.

All'interno del ciclo, la conversione funziona come segue:

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

Mettendolo aalla fine lo stampa automaticamente.

Una soluzione ricorsiva in 28 byte:

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

6

Python 2, 52

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

È più facile pensarlo come due funzioni ricorsive:

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 funzione gconverte un valore decimale in binario e la funzione si fapplica gripetutamente finché il suo argomento è composto dalle cifre 0 e 1 ( '2'>max(`n`)) e non lo è 1. Il codice golf li fa collassare in una singola funzione inserendo la definizione di g(n)for f(n), sostituendo la chiamata ricorsiva gcon f. Il caso base di n=0of gviene gestito automaticamente dal controllo n>1.


Bello :) L'unica cosa è che il solito problema si applica - il fastidioso Lda repr...
SP3000

4

Prolog, 220 212 byte

:-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 spiegazione
p è la funzione principale ed esegue i seguenti passaggi (con l'aiuto di b, x, y):

  • controlla se il numero corrente è maggiore di 1
  • converte un numero intero in un elenco di rappresentazioni ASCII di cifre
  • controlla che tutti i numeri siano 0 o 1
  • converte l'elenco ASCII in elenco intero binario
  • converte l'elenco intero binario in numero decimale
  • recurses
  • stampa quando un predicato fallisce.

Modifica: salvato 8 byte unificando le clausole p con OR.


3

Mathematica 107 106

Con un byte salvato da 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])

Dividi l'input nelle sue cifre. Se l'ingresso è 1, uscita 1.

Se l'input è un numero composto da 0 e 1, convertirlo in decimale ed eseguirlo di nuovo.

Altrimenti, restituisce l'input.


j[1]

1


j[11010001]

209


j[1111110001]

1009


j[1111110011]

3

Il primo passo produce 1011 che a sua volta produce 3.


Qui testiamo a partire da 1011.

j[1011]

3


3

Javascript, 132 , 123 byte

Bene, non è la risposta migliore, ma ...

Cordiali saluti, se viene fornito un input non valido, viene visualizzato lo stesso per l'utente.

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())


1
È possibile salvare 19 byte utilizzando forinvece di whilee impostando i valori direttamente nell'istruzione (questo riduce anche alcuni {}), eliminandone alcuni ;, utilizzando la descrizione della funzione ES6, l'incremento in ilinea. Sarà simile a questa: 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()).
inserisci nomeutentedell'11

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

@inserireusernamehere, grazie per il suggerimento, ma all'inizio non ho capito c=x=>, non ha funzionato su console Chrome o Firefox. :( @ ן nɟuɐɯɹɐ ן oɯ, non ho potuto avvolgere la mia testa attorno alla condizione XOR e x=0|x/10‌invece parseInt, ho incorporato il resto delle modifiche. Grazie ..
LearningDeveloper

@GauthamPJ Mi dispiace, in qualche modo il codice si è rotto durante la copia e conteneva caratteri non stampabili. Ecco la versione corretta: 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()). Funziona sicuramente con Firefox 42, prova questo violino . Nota che questa versione più giocata e anche il tuo codice originale non funzionano 1e funzioneranno in un ciclo infinito. c=x=>è come function c(x){}vedere " Funzioni freccia ".
inserire nomeutentequi

2

JavaScript ES6, 52

Come una funzione. L'argomento della funzione deve essere una stringa di cifre binarie o un numero la cui rappresentazione decimale contiene solo 1 e 0.

Prova a eseguire lo snippet di seguito in un browser conforme a EcmaScript 6 - implementando funzioni freccia, stringhe di modelli e operatore di diffusione (utilizzo 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>


1
Mi piace molto n+=+c+nper la conversione binaria. Così elegante ...
nderscore,

2

Mathematica, 62 59 55 48 byte

Salvataggio di 7 byte grazie a Martin Büttner.

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

1

Javascript (ES7) 87 80 78 77 74 byte

Demo dello snippet per il supporto dei browser (attualmente solo Firefox supporta l'operatore esponenziale di notte)

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 byte

Demo dello snippet per i browser di supporto

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>


1

𝔼𝕊𝕄𝕚𝕟, 37 caratteri / 54 byte

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

Try it here (Firefox only).

Non sono sicuro che l' +operatore venga considerato come integrato per la conversione binaria ...



1

PHP, 210 204 byte

È la prima volta che scrivo qui, quindi spero che vi piaccia! Anche se ovviamente non è il modo migliore per scriverlo, sono comunque felice di mostrarlo qui!

Il codice

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

Ho creato una funzione ricorsiva "j" che verificherà prima se l'ingresso è uguale a 1. In tal caso, la funzione restituisce 1 come previsto, altrimenti dividerà il numero in un array per calcolare il valore decimale, ma solo se il numero è binario. In caso contrario, restituirà il numero così com'è.

Codice Ungolfed

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

Ho usato un'istruzione "foreach" anziché la mia "for" iniziale, permettendomi di guadagnare 6 byte, ma sono abbastanza sicuro che ci sia molto altro da fare.


1

PHP, 114 112 byte

funziona anche per 0. Corri 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)restituisce una stringa contenente tutti i caratteri della stringa (come array_uniquefa per le matrici). Per i numeri binari, questo sarà 0, 1o 01. Per altri numeri, questo conterrà una cifra maggiore di 1, quindi <2restituirà vero solo per i numeri binari.

&$s>1è necessario per il caso speciale 1.

Il resto è semplice: scorrere i bit spostando il valore e aggiungendo il bit corrente, infine copiare il numero (da cast a stringa) a $ s per il test del loop esterno.


0

CoffeeScript, 92 89 byte

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 byte

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

dimostrazione

Funziona solo con browser conformi a ES6 come Firefox e 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>


Se usi eval, potresti essere in grado di ottenere un ritorno implicito.
Mama Fun Roll,

5 byte più brevi con funzioni eval e anonime
Downgoat,

@ ן nɟuɐɯɹɐ ן oɯ Per qualche motivo la funzione di valutazione non funziona con 1. perché non entra nel ciclo presumo
rink.attendant.6

1
@nderscore Grazie, ma la ricorsione è stata di 4 byte più breve :-)
rink.attendant.6

0

Scala, 128 byte

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

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 funzione anonima è la conversione del tipo di numero ( bin2dec)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.