Uprość binarne


20

Wyzwanie

Biorąc pod uwagę liczbę binarną wprowadzaną dowolnymi środkami, „uprość” liczbę, używając pełnego programu lub funkcji.

Wejście

[binary]
  • binary jest liczbą dwójkową, która jest większa od 0.

Wynik

Weź dane wejściowe, przekonwertuj je na bazę 10 bez użycia wbudowanego, a następnie jeśli ta liczba zawiera tylko 1 i 0, przekonwertuj ją na liczbę podstawową 10, jakby to była kolejna liczba binarna. Powtarzaj ten proces, dopóki numer nie będzie mógł zostać odczytany w trybie binarnym i wyślij go.

Inne informacje

  • Jeśli wejście wynosi 1, po prostu wyślij 1. Twój program nie powinien w nieskończoność upraszczać 1.

  • To jest golf golfowy, więc wygrywa najkrótsza odpowiedź w bajtach do wtorku (17 listopada).

  • Jeśli coś jest mylące, zostaw komentarz określający, co muszę wyjaśnić, i odpowiednio go zmodyfikuję.

  • Wbudowane konwersje podstawowe są niedozwolone.

Przykłady

     Input | Output

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

4
Przydałoby się kilka przypadków testowych.
isaacg

Czy wejście jest łańcuchem ASCII, czy faktycznie 1 i 0?
Tom Carpenter,

@TomCarpenter 1s i 0s.
The_Basset_Hound

@isaacg Dodano sposoby uzyskania 1-5 jako wyjścia.
The_Basset_Hound

Czy dozwolone są funkcje konwertujące ciąg znaków na daną bazę?
isaacg

Odpowiedzi:


14

Pyth, 20 16 bajtów

u?-GTG`u+yNsTG0z

4 bajty dzięki Jakube

Połowa kodu ( u+yNsTG0) to po prostu podstawowy kod konwersji.

Pakiet testowy

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.

Dane wejściowe 1są obsługiwane przez fakt, że uwartość przestała się zmieniać.


4
Gratulacje, wygraliście Dennisa! Na razie ...
Conor O'Brien

9
@ CᴏɴᴏʀO'Bʀɪᴇɴ Sekretem jest Pyth.
isaacg

8

CJam, 24 23 bajty

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

Wypróbuj online w interpretatorze CJam .

Jak to działa

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.

Czy musisz powtórzyć "10"ciąg znaków length-1, czy możesz pominąć dekrement?
DLosc

Odejmowanie 1 od długości zmienia się "10"w, ""jeśli liczba całkowita ma jedną cyfrę. Dzięki temu kod nie dostanie się w nieskończoną pętlę.
Dennis

2
Fascynujące, kapitanie. }: ^ |
DLosc

7

Pip, 28 27 bajtów

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

Pobiera dane wejściowe jako argument wiersza polecenia. Chcemy pętli aż a=1lub azawiera jakiś znak (ów) oprócz 0 i 1 roku. Ten ostatni warunek jest testowany przez RMwpisanie wszystkich znaków w t= 10z a. Jeśli coś pozostało, warunek jest prawdziwy.

Wewnątrz pętli konwersja działa w następujący sposób:

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

Po umieszczeniu ana końcu drukuje się automatycznie.

Rozwiązanie rekurencyjne w 28 bajtach:

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

Łatwiej jest myśleć o tym jako o dwóch funkcjach rekurencyjnych:

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

Funkcja gkonwertuje wartość dziesiętną na binarną, a funkcja fstosowana gwielokrotnie jest długa, dopóki jej argument składa się z cyfr 0 i 1 ( '2'>max(`n`)) i nie jest 1. Golfed kod wali ich w jednej funkcji przez wprowadzenie definicji g(n)dla f(n)zastępując rekurencyjne wywołanie gz f. Sprawa podstawowa n=0z gautomatycznie obsługiwane przez czekiem n>1.


Fajnie :) Jedyne, co się Lrepr
dzieje

4

Prolog, 220 212 bajtów

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

Wyjaśnienie
p jest główną funkcją i wykonuje następujące kroki (z pomocą b, x, y):

  • sprawdza, czy bieżąca liczba jest większa niż 1
  • konwertuje liczbę całkowitą na listę reprezentacji cyfr ascii
  • sprawdza, czy wszystkie liczby są równe 0 lub 1
  • konwertuje listę ascii na binarną listę liczb całkowitych
  • konwertuje binarną listę liczb całkowitych na liczbę dziesiętną
  • powtarza się
  • wypisuje się, gdy predykat się nie powiedzie.

Edycja: Zapisano 8 bajtów poprzez ujednolicenie klauzul p z OR.


3

Mathematica 107 106

Z bajtem zapisanym przez 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])

Podziel dane wejściowe na cyfry. Jeśli wejście to 1, wyjście 1.

Jeśli wejście jest liczbą składającą się z zer i jedynek, przekonwertuj to na dziesiętne i ponownie uruchom.

W przeciwnym razie zwróć dane wejściowe.


j[1]

1


j[11010001]

209


j[1111110001]

1009


j[1111110011]

3)

Pierwszy krok daje 1011, co z kolei daje 3.


Tutaj testujemy zaczynając od 1011.

j[1011]

3)


3

JavaScript, 132 , 123 bajtów

Cóż, to nie jest najlepsza odpowiedź, ale ...

FYI, jeśli podano nieprawidłowe dane wejściowe, wyświetla to samo użytkownikowi.

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
Możesz zapisać 19 bajtów , używając forzamiast whilei ustawiając wartości bezpośrednio w instrukcji (to również zmniejsza niektóre {}), odrzucając niektóre ;, używając opisu funkcji ES6, zwiększaj iinline. Będzie to wyglądać tak: 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()).
inserttusernamehere

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, dzięki za sugestię, ale c=x=>na początku nie zrozumiałem, nie działałem na konsoli Chrome ani Firefox. :( @ ן nɟuɐɯɹɐ ן oɯ, nie mogłem owinąć głowy wokół warunku XOR, a x=0|x/10‌zamiast tego parseIntwprowadziłem resztę zmian. Dzięki ..
LearningDeveloper

@GauthamPJ Przepraszam, jakoś kod został uszkodzony podczas kopiowania i zawierał znaki, które nie mogą być drukowane. Oto poprawna wersja: 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()). Na pewno działa w Firefox 42, spróbuj tego skrzypka . Pamiętaj, że ta bardziej golfowa wersja, a także oryginalny kod nie działają 1i będą działać w nieskończonej pętli. c=x=>jest jak function c(x){}patrz „ Funkcje strzałek ”.
inserttusernamehere

2

JavaScript ES6, 52

Jako funkcja. Argument funkcji musi być ciągiem cyfr binarnych lub liczbą, której reprezentacja dziesiętna zawiera tylko 1 i 0.

Przetestuj poniższy fragment kodu w przeglądarce zgodnej z EcmaScript 6 - implementując funkcje strzałek, ciągi szablonów i operator rozkładania (używam 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
Naprawdę podoba mi n+=+c+nsię konwersja binarna. Tak elegancko ...
nderscore

2

Mathematica, 62 59 55 48 bajtów

Zaoszczędzono 7 bajtów dzięki Martinowi Büttnerowi.

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

1

JavaScript (ES7) 87 80 78 77 74 bajtów

Wersja demonstracyjna fragmentu do obsługi przeglądarek (obecnie tylko Firefox co noc obsługuje operatora wykładniczego)

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 bajtów

Prezentacja Snippet do obsługi przeglądarek

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 bajtów

To mój pierwszy post tutaj, więc mam nadzieję, że wam się spodoba! Nawet jeśli to oczywiście nie jest najlepszy sposób na napisanie tego, nadal cieszę się, że mogę to tutaj pokazać!

Kod

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

Zrobiłem funkcję rekurencyjną „j”, która najpierw sprawdzi, czy wartość wejściowa jest równa 1. Jeśli tak, funkcja zwraca 1 zgodnie z oczekiwaniami, w przeciwnym razie podzieli liczbę w tablicy, aby obliczyć wartość dziesiętną, ale tylko jeśli liczba jest liczbą binarną. Jeśli nie, zwróci liczbę w niezmienionej postaci.

Nieskluczony kod

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

Użyłem wyrażenia „foreach” zamiast początkowego „for”, co pozwala mi zyskać 6 bajtów, ale jestem prawie pewien, że jest o wiele więcej do zrobienia.


1

PHP, 114 112 bajtów

działa również dla 0. Uruchom z -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)zwraca ciąg zawierający wszystkie znaki z ciągu (podobnie jak w array_uniqueprzypadku tablic). Dla liczb binarnych, to będzie 0, 1albo 01. W przypadku innych liczb będzie zawierała cyfrę większą niż 1, więc <2zwróci prawdę tylko dla liczb binarnych.

&$s>1jest potrzebny w specjalnym przypadku 1.

Reszta jest prosta: zapętlaj bity, przesuwając wartość i dodając bieżący bit, w końcu skopiuj liczbę (rzut na ciąg) do $ s dla testu zewnętrznej pętli.


0

CoffeeScript, 92 89 bajtów

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 bajtów

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

Próbny

Działa tylko w przeglądarkach zgodnych z ES6, takich jak Firefox i 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>


Jeśli użyjesz eval, być może uda ci się uzyskać niejawny zwrot.
Mama Fun Roll

5 bajtów krótszych z funkcjami eval i anonimowymi
Downgoat

@ ן nɟuɐɯɹɐ ן oɯ Z jakiegoś powodu funkcja eval'd nie działa 1. ponieważ nie wchodzi w pętlę, którą zakładam
rink.attendant. 6

1
@nderscore Dzięki, ale rekursja była o 4 bajty krótsza :-)
rink.attendant.6

0

Scala, 128 bajtów

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

  • Anonimowa funkcja to konwersja typu liczb ( bin2dec)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.