Binary vereinfachen


20

Herausforderung

Wenn Sie eine Binärzahl als Eingabe verwenden, "vereinfachen" Sie die Zahl mit einem vollständigen Programm oder einer Funktion.

Eingang

[binary]
  • binary ist eine binäre Zahl, die über 0 liegt.

Ausgabe

Nehmen Sie die Eingabe, konvertieren Sie sie zur Basis 10 ohne Verwendung einer eingebauten Zahl. Wenn diese Zahl nur Einsen und Nullen enthält, konvertieren Sie sie in eine Zahl zur Basis 10, als wäre sie eine andere Binärzahl. Wiederholen Sie den Vorgang, bis die Zahl nicht mehr binär gelesen werden kann, und geben Sie diese Zahl aus.

Andere Informationen

  • Wenn der Eingang 1 ist, einfach ausgeben 1. Ihr Programm sollte nicht unendlich weiter vereinfachen 1.

  • Dies ist Codegolf, daher gewinnt die kürzeste Antwort in Bytes bis Dienstag (17. November).

  • Wenn etwas verwirrend ist, hinterlassen Sie einen Kommentar, in dem Sie angeben, was zu klären ist, und ich werde ihn entsprechend bearbeiten.

  • Builtins für die Basiskonvertierung sind nicht erlaubt.

Beispiele

     Input | Output

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

4
Könnte ein paar Testfälle verwenden.
isaacg

Handelt es sich bei der Eingabe um eine ASCII-Zeichenfolge oder tatsächlich um Einsen und Nullen?
Tom Carpenter

@TomCarpenter 1s und 0s.
The_Basset_Hound

@isaacg Es wurden Möglichkeiten hinzugefügt, 1-5 als Ausgabe zu erhalten.
The_Basset_Hound

Sind Funktionen erlaubt, die einen String in eine bestimmte Basis konvertieren?
isaacg

Antworten:


14

Pyth, 20 16 Bytes

u?-GTG`u+yNsTG0z

4 Bytes dank Jakube

Die Hälfte des Codes ( u+yNsTG0) ist einfach der Basisumwandlungscode.

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.

Die Eingabe 1wird von der Tatsache behandelt, dass ufestgestellt wird , dass sich der Wert nicht mehr ändert.


4
Herzlichen Glückwunsch, Sie haben Dennis übertroffen! Für den Moment ...
Conor O'Brien

9
@ CᴏɴᴏʀO'Bʀɪᴇɴ Das Geheimnis ist Pyth.
isaacg

8

CJam, 24 23 Bytes

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

Probieren Sie es online im CJam-Interpreter aus .

Wie es funktioniert

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.

Müssen Sie die "10"Zeichenfolge length-1mal wiederholen , oder können Sie die Dekrementierung überspringen?
DLosc

Das Subtrahieren von 1 von der Länge wird "10"zu, ""wenn die Ganzzahl eine einzelne Ziffer hat. Dies stellt sicher, dass der Code nicht in eine Endlosschleife gerät.
Dennis

2
Faszinierend, Captain. }: ^ |
DLosc

7

Pip, 28 27 Bytes

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

Übernimmt die Eingabe als Befehlszeilenargument. Wir wollen eine Schleife machen bis a=1oder aeinige Zeichen neben 0 und 1 enthalten. Diese letztere Bedingung wird getestet, indem RMalle Zeichen in t= 10from eingegeben werden a. Wenn noch etwas übrig ist, ist die Bedingung wahr.

Innerhalb der Schleife funktioniert die Konvertierung wie folgt:

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

Wenn Sie adas Ende beenden, wird es automatisch gedruckt.

Eine rekursive Lösung in 28 Bytes:

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

Es ist einfacher, sich dies als zwei rekursive Funktionen vorzustellen:

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

Die Funktion gwandelt einen Dezimalwert auf binär, und die Funktion fgilt gwiederholt lang ist als Argument von Ziffern besteht 0 und 1 ( '2'>max(`n`)) und ist nicht 1. Der Golf Code reduziert sie in eine einzige Funktion, indem er die Definition von g(n)for einfügt f(n)und den rekursiven Aufruf von to gdurch ersetzt f. Der Basisfall von n=0von gwird von der Prüfung automatisch behandelt n>1.


Schön :) Das einzige ist, dass das übliche Problem zutrifft - der nervige Lvon repr...
Sp3000

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

Erklärung
p ist die Hauptfunktion und führt die folgenden Schritte aus (mit Hilfe von b, x, y):

  • Prüft, ob die aktuelle Zahl größer als 1 ist
  • wandelt eine Ganzzahl in eine Liste von ASCII-Darstellungen von Ziffern um
  • prüft, ob alle Zahlen 0 oder 1 sind
  • wandelt ASCII-Liste in binäre Ganzzahl-Liste um
  • wandelt eine binäre Ganzzahlliste in eine Dezimalzahl um
  • rekursiv
  • Wird gedruckt, wenn ein Vergleichselement fehlschlägt.

Bearbeiten: 8 Bytes durch Vereinheitlichen der p-Sätze mit OR gespeichert.


3

Mathematica 107 106

Mit einem von DLosc gespeicherten Byte.

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

Teilen Sie die Eingabe in Ziffern auf. Wenn der Eingang 1 ist, wird 1 ausgegeben.

Wenn die Eingabe eine Zahl ist, die aus Nullen und Einsen besteht, konvertieren Sie diese in eine Dezimalzahl und führen Sie sie erneut aus.

Andernfalls geben Sie die Eingabe zurück.


j[1]

1


j[11010001]

209


j[1111110001]

1009


j[1111110011]

3

Der erste Schritt ergibt 1011, was wiederum 3 ergibt.


Hier testen wir ab 1011.

j[1011]

3


3

Javascript, 132 , 123 Bytes

Nun, es ist nicht die beste Antwort, aber ..

Zu Ihrer Information, wenn eine ungültige Eingabe angegeben wird, wird diese dem Benutzer angezeigt.

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
Sie könnten 19 Bytes einsparen, indem Sie stattdessen Werte direkt in der Anweisung festlegen (dies reduziert auch einige ) und einige mithilfe der ES6-Funktionsbeschreibung verwerfen und inline inkrementieren . Es wird wie folgt aussehen: . forwhile{};ic=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, danke für den vorschlag, aber ich habe das c=x=>am anfang nicht verstanden , funktionierte nicht auf chrome oder firefox konsole . :( @ ן nןuɟ ן oן, konnte meinen Kopf nicht um die XOR-Bedingung wickeln und x=0|x/10‌stattdessen parseInthabe ich den Rest der Änderungen übernommen. Danke ..
LearningDeveloper

@GauthamPJ Es tut mir leid, aber irgendwie ist der Code beim Kopieren kaputt gegangen und enthielt nicht druckbare Zeichen. Hier ist die richtige Version: 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()). Es läuft definitiv in Firefox 42, probieren Sie diese Geige . Beachten Sie, dass diese Golf-Version und auch Ihr Originalcode nicht funktionieren 1und in eine Endlosschleife geraten. c=x=>ist wie function c(x){}siehe " Pfeilfunktionen ".
insertusernamehere

2

JavaScript ES6, 52

Als eine Funktion. Das Funktionsargument muss entweder eine Folge von Binärziffern oder eine Zahl sein, deren Dezimalrepräsentation nur 1 und 0 enthält.

Testen Sie die Ausführung des folgenden Snippets in einem EcmaScript 6-kompatiblen Browser - Implementierung von Pfeilfunktionen, Vorlagenzeichenfolgen und Spread-Operator (ich verwende 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
Mag n+=+c+ndie binäre Konvertierung wirklich . So elegant ...
Endpunkt

2

Mathematica, 62 59 55 48 Bytes

7 Bytes gespart dank Martin Büttner.

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

1

Javascript (ES7) 87 80 78 77 74 Bytes

Snippet-Demo zur Unterstützung von Browsern (derzeit unterstützt nur Firefox den Exponentialoperator in der Nacht)

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

Snippet-Demo zur Unterstützung von Browsern

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

PHP, 210 204 Bytes

Es ist das erste Mal, dass ich hier etwas schreibe, also hoffe es wird euch gefallen! Auch wenn es offensichtlich nicht die beste Art ist, es zu schreiben, bin ich trotzdem froh, es hier zu zeigen!

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

Ich habe eine rekursive Funktion "j" erstellt, die zuerst überprüft, ob die Eingabe gleich 1 ist. Wenn dies der Fall ist, gibt die Funktion wie erwartet 1 zurück, andernfalls wird die Zahl in einem Array aufgeteilt, um den Dezimalwert zu berechnen, aber nur wenn die Zahl eine binäre ist. Ist dies nicht der Fall, wird die Nummer unverändert zurückgegeben.

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

Ich habe eine "foreach" -Anweisung anstelle meiner anfänglichen "for" -Anweisung verwendet, was mir einen Gewinn von 6 Bytes ermöglicht, aber ich bin mir ziemlich sicher, dass noch viel mehr zu tun ist.


1

PHP, 114 112 Bytes

funktioniert auch für 0. Laufen Sie mit -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)Gibt eine Zeichenfolge zurück, die alle Zeichen der Zeichenfolge enthält (wie array_uniquebei Arrays). Für Binärzahlen, wird dies sein 0, 1oder 01. Bei anderen Zahlen enthält dies eine Ziffer, die größer als ist 1, sodass <2nur bei Binärzahlen true zurückgegeben wird.

&$s>1wird für den Sonderfall benötigt 1.

Der Rest ist unkompliziert: Durchlaufen Sie die Bits, indem Sie den Wert verschieben und das aktuelle Bit hinzufügen, und kopieren Sie schließlich die Zahl (in Zeichenfolge umgewandelt) für den Test der äußeren Schleife nach $ s.


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 Byte

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

Demo

Funktioniert nur in ES6-kompatiblen Browsern wie Firefox und 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>


Wenn Sie eval verwenden, können Sie möglicherweise eine implizite Rendite erzielen.
Mama Fun Roll

5 Bytes kürzer mit eval und anonymen Funktionen
Downgoat

@ ן nןuɟ ן oן Aus irgendeinem Grund funktioniert die Funktion eval'd nicht 1. weil es nicht in die Schleife
eintritt,

1
@nderscore Danke, aber die Rekursion war 4 Bytes kürzer :-)
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

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

  • Die anonyme Funktion ist die Umwandlung von Zahlentypen ( bin2dec)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.