简化二进制


20

挑战

给定通过任何方式输入的二进制数字,请使用完整程序或函数“简化”该数字。

输入值

[binary]
  • binary 是二进制数大于0的数字。

输出量

接受输入,不使用内置函数将其转换为以10为底,然后,如果该数字仅包含1和0,则将其转换为以10为底的数字,就好像它是另一个二进制数一样。重复该过程,直到无法以二进制形式读取该数字并输出该数字。

其他资讯

  • 如果输入为1,则只需输出1。您的程序不应继续无限简化1。

  • 这是代码高尔夫,因此以星期二(11月17日)为单位的最短答案为胜。

  • 如果有什么令人困惑的地方,请留下评论,指出我需要清除的内容,然后我将进行相应的编辑。

  • 不允许用于基本转换的内建函数。

例子

     Input | Output

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

4
可以使用几个测试用例。
isaacg 2015年

输入的是ASCII字符串,还是1和0?
汤姆·卡彭特

@TomCarpenter 1和0。
The_Basset_Hound 2015年

@isaacg添加了获取1-5作为输出的方法。
The_Basset_Hound 2015年

是否允许将字符串转换为给定基数的函数?
isaacg 2015年

Answers:


14

Pyth,20 16字节

u?-GTG`u+yNsTG0z

4个字节,感谢Jakube

代码(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.

输入1是通过u注意到值已停止更改这一事实来处理的。


4
恭喜,您超越了丹尼斯!目前...
Conor O'Brien

9
@CᴏɴᴏʀO'Bʀɪᴇɴ秘密是Pyth。
isaacg 2015年

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 2015年

如果整数有一位数字,则从长度中减去1就"10"变成""了。这样可以确保代码不会陷入无限循环。
丹尼斯

2
迷人的,队长。}:^ |
DLosc 2015年

7

点,28 27字节

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

将输入作为命令行参数。我们要循环直到a=1a包含除0和1之外的某些字符。通过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

将其视为两个递归函数较为容易:

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将十进制值转换为二进制,并且只要其参数由数字0和1()构成且不是,该函数就会重复f应用。所述golfed代码通过插入的定义折叠成一个单一的功能为,代替递归调用与。的基础案例的被单向自动处理。g'2'>max(`n`)1g(n)f(n)gfn=0gn>1


尼斯:)唯一的问题是,通常的问题适用- L来自repr... 的讨厌
Sp3000,2015年

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列表转换为二进制整数列表
  • 将二进制整数列表转换为十进制数
  • 递归
  • 在谓词失败时输出。

编辑:通过与OR统一p子句,节省了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组成的数字,请将其转换为十进制,然后再次运行。

否则,返回输入。


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
您可以通过直接在语句中使用而不是和设置值来节省 19个字节(这也减少了),使用ES6函数描述丢弃一些,并内联增量。看起来像这样:。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())
2015年

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

@insertusername此处,感谢您的建议,但起初我并不理解,c=x=>在Chrome或Firefox控制台上无法使用。:( @@nɟuɐɯɹɐןoɯ,无法绕过XOR条件,x=0|x/10‌而是parseInt我将其余的更改合并了。谢谢
2015年

@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

作为功​​能。函数参数必须是一串二进制数字或一个十进制表示形式仅包含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 2015年

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

我已经创建了一个递归函数“ j”,它将首先检查输入是否等于1。如果是,则该函数按预期返回1,否则它将在数组中拆分数字以计算十进制值,但仅如果数字是二进制数。如果不是,它将按原样返回数字。

非高尔夫代码

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

我使用了一个“ foreach”语句而不是最初的“ for”语句,这使我获得了6个字节的增益,但是我敢肯定,还有很多事情要做。


1

PHP,114112字节

也适用于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数组一样)。对于二进制数字,这将是0101。对于其他数字,此数字将包含一个大于的数字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

演示版

仅在兼容ES6的浏览器(例如Firefox和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>


如果使用eval,则可以提取隐式收益。
Mama Fun Roll'Roll'Nov

使用eval和匿名函数缩短 5个字节
Downgoat 2015年

@ןnɟuɐɯɹɐןoɯ出于某些原因,评估功能无法使用1。因为它没有进入循环,所以我认为是
rink.attendant.15年

1
@nderscore谢谢,但是递归缩短了4个字节:-)
rink.attendant.6 2015年

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.