バイナリを簡素化


20

チャレンジ

任意の手段を介した入力として2進数が与えられた場合、完全なプログラムまたは関数を使用して数値を「単純化」します。

入力

[binary]
  • binary 0を超える2進数の数値です。

出力

入力を取得し、ビルトインを使用せずに基数10に変換し、その数値に1と0のみが含まれている場合は、別の2進数であるかのように基数10に変換します。番号をバイナリで読み取ることができなくなるまでプロセスを繰り返し、その番号を出力します。

その他の情報

  • 入力が1の場合、単にoutput 1です。プログラムを無限に単純化してはいけません1。

  • これはコードゴルフであるため、火曜日(11月17日)までのバイト単位の最短回答が勝ちです。

  • 混乱を招くものがある場合は、解決する必要があるものを指定してコメントを残し、それに応じて編集します。

  • 基本変換の組み込みは許可されていません。

     Input | Output

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

4
いくつかのテストケースを使用できます。
isaacg

入力はASCII文字列ですか、実際は1と0ですか?
トムカーペンター

@TomCarpenter 1および0。
The_Basset_Hound

@isaacg 1-5を出力として取得する方法を追加しました。
The_Basset_Hound

文字列を特定のベースに変換する関数は許可されますか?
isaacg

回答:


14

Pyth、20 16バイト

u?-GTG`u+yNsTG0z

ジャクベのおかげで4バイト

コードの半分(u+yNsTG0)は、単に基本変換コードです。

テストスイート

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.

入力1u、値の変更が停止したことに気づいたという事実によって処理されます。


4
おめでとうございます、デニスを追い越しました!今のところ...
コナーオブライエン

9
@CᴏɴᴏʀO'Bʀɪᴇɴ秘密はPythです。
isaacg

8

CJam、24 23バイト

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

CJamインタープリターでオンラインで試してください。

使い方

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.

"10"文字列を繰り返すlength-1必要がありますか、それともデクリメントをスキップできますか?
DLosc

整数が1桁の場合、長さから1を引くと"10"変換され""ます。これにより、コードが無限ループに陥らないようにします。
デニス

2
魅惑的、キャプテン。}:^ |
DLosc

7

ピップ、28 27バイト

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

入力をコマンドライン引数として受け取ります。0と1以外の文字が含まれるまでループするa=1必要aがあります。この後者の条件はRMt= 10fromのすべての文字を ' テストすることによってテストされaます。何か残っている場合、条件は真実です。

ループ内では、変換は次のように機能します。

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

a最後に置くと、自動印刷されます。

28バイトの再帰的ソリューション:

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

これは、2つの再帰関数と考える方が簡単です。

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

この関数gは10進値を2進数に変換し、引数が数字0と1()で構成されていない限り、関数fg繰り返し適用されます。golfedコードが定義挿入することによって、単一の機能にそれらを崩壊するために、再帰呼び出しを置き換えると。ベースケースのは自動的にチェックすることによって処理されます。'2'>max(`n`)1g(n)f(n)gfn=0gn>1


ニース:)唯一の通常の問題が適用されることである-厄介なLのがrepr...
SP3000

4

プロローグ、220 212バイト

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

説明
pはメイン関数であり、次の手順を実行します(b、x、yの助けを借りて)。

  • 現在の数が1より大きいかどうかをチェックします
  • 整数をASCII数字表現のリストに変換します
  • すべての数値が0または1であることを確認します
  • ASCIIリストをバイナリ整数リストに変換します
  • 2進整数リストを10進数に変換します
  • 再帰する
  • 述語が失敗したときに出力します。

編集: p節をORで統合して8バイトを保存しました。


3

Mathematica 107 106

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

入力を数字に分割します。入力が1の場合、出力1。

入力が0と1で構成される数値の場合、それを10進数に変換し、再度実行します。

それ以外の場合は、入力を返します。


j[1]

1


j[11010001]

209


j[1111110001]

1009


j[1111110011]

3

最初のステップでは1011が生成され、3が生成されます。


ここでは、1011からテストを開始します。

j[1011]

3


3

Javascript、132、123バイト

まあ、それは最良の答えではありませんが、..

参考までに、無効な入力が与えられると、ユーザーに同じように表示されます。

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
ステートメントの代わりにを使用し、値を直接設定して(これにより一部が削減されます)、一部を破棄し、ES6関数の説明を使用して、インラインでインクリメントすることで19バイトを節約 できます。次のようになります。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())
ここにユーザー名を挿入します

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())
ママファンロール

@insertusernamehere、提案に感謝しますが、c=x=>最初は理解できませんでした、ChromeまたはFirefoxコンソールでは動作しませんでした。:( @ןnɟuɐɯɹɐןoɯ、XOR条件に頭を包むことができず、x=0|x/10‌代わりにparseInt、残りの変更を取り入れました。ありがとう。
LearningDeveloper

@GauthamPJすみません、コピー中にコードが壊れてしまい、印刷できない文字が含まれていました。正しいバージョンは次のとおり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())です。間違いなくFirefox 42で実行されます。このフィドルを試してください。このよりゴルフされたバージョンと元のコードは機能せず1、無限ループに陥ることに注意してください。c=x=>以下のようなものfunction c(x){}「を参照してください。矢印機能を」。
ここにユーザー名を挿入

2

JavaScript ES6、52

機能として。関数の引数は、2進数の文字列か、10進数表現に1と0のみが含まれる数値のいずれかでなければなりません。

EcmaScript 6準拠のブラウザーで以下のスニペットを実行してテストします-矢印関数、テンプレート文字列、スプレッド演算子を実装します(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
n+=+c+nバイナリ変換が本当に好きです。だから、エレガントな...
nderscore

2

Mathematica、62 59 55 48バイト

MartinBüttnerのおかげで7バイト節約されました。

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

1

Javascript(ES7)87 80 78 77 74バイト

ブラウザをサポートするためのスニペットデモ(現在、Firefoxのみが指数演算子をサポートしています)

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バイト

ブラウザをサポートするためのスニペットデモ

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バイト

ここに投稿するのは初めてなので、皆さんが気に入ってくれることを願っています!それが明らかにそれを書くための最善の方法ではない場合でも、私はここでそれを披露するためにまだ嬉しいです!

コード

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

入力が1に等しいかどうかを最初にチェックする再帰関数「j」を作成しました。等しい場合、関数は期待どおりに1を返します。数値が2進数の場合。そうでない場合は、数値をそのまま返します。

未ゴルフコード

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

私は最初の「for」ステートメントの代わりに「foreach」ステートメントを使用しました。これにより、6バイトのゲインが得られますが、やるべきことはまだたくさんあると確信しています。


1

PHP、114 112バイト

にも有効です0。で実行し-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)文字列のすべての文字を含む文字列を返します(array_unique配列の場合と同様)。2進数の場合、これは01または01です。他の数値の場合、これにはより大きい数字が含まれます1ので、<2唯一の二進数のためにtrueを返します。

&$s>1 特別な場合に必要です 1

残りは簡単です。値をシフトして現在のビットを追加してビットをループし、最後に外側のループテスト用に数値を文字列にキャストして$ sにコピーします。


0

CoffeeScript、92 89バイト

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バイト

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

デモ

FirefoxやMicrosoft EdgeなどのES6準拠のブラウザーでのみ動作します

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>


evalを使用すると、暗黙の戻り値を取得できる場合があります。
ママファンロール

図5は、バイト短いのevalと匿名の機能を持つ
Downgoat

@ןnɟuɐɯɹɐןoɯ何らかの理由でeval'd関数はで動作しません1。それがループに入らないので、私は仮定
rink.attendant.6

1
@nderscoreありがとう、しかし再帰は4バイト短くなりました:
rink.attendant.6 5

0

Scala、128バイト

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

  • 無名関数は、数値型変換(bin2dec)です
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.