将我一分为二


15

您将获得一个号码x,在哪里0 <= x <= 2^32 - 1

在以二进制格式递归拆分后,您应该以十进制输出数字列表。

例子:

范例1:

255 -> 255 15 15 3 3 3 3 1 1 1 1 1 1 1 1

当前列表为255

的二进制表示形式2551111 1111。拆分它,我们得到1111and 1111,其中十进制是15and 15

我们将它们添加到列表中,因此我们将拥有255 15 15

现在的数字1515将作为输入,这些数字是被分裂。

老毛病又犯了,我们(获得3 3来自两个15或多个): 255 15 15 3 3 3 3

继续逻辑,最终列表将为255 15 15 3 3 3 3 1 1 1 1 1 1 1 1。并且由于1无法再拆分,因此输出停止。

范例2:

225 -> 225 14 1 3 2 1 1 1 0

开始列表是225

的二进制表示形式2251110 0001。拆分它,我们得到1110and 0001,其中十进制是14and 1

将它们添加到列表中,我们得到225 14 1

现在的数字141将作为输入,这些数字是被分裂。

由于1没有可拆分的,因此输出为225 14 1 3 2

范例3:

32 -> 32 4 0 1 0

条件

  1. 如果二进制数的位数为奇数,则第一个数字的位数将比下一个数字少。例如,20 (10100)将被拆分为10100,十进制输出为24
  2. 适用标准漏洞规则。
  3. 0s和1s不会进一步传播。
  4. 试图显示太多数字而导致程序崩溃是有效的退出条件。

只是一个建议,但是0当长度为奇数时,用s 填充二进制数字该怎么办?
Caird coinheringaahing

1
@ Satan'sSon如果您在前面垫垫,则等同于说明。
isaacg

1
指定的输出顺序是必需的还是仅是值?
乔纳森·艾伦

@ Satan'sSon不使用0s 填充。
ctrl-shift-esc

1
@JonathanAllan需要指定的输出顺序。
ctrl-shift-esc

Answers:


13

Pyth,18个字节

u+QiR2smc2+0dt#.BM

测试套件

这段代码使用uPyth的不动点算符进行了一些非常棘手和巧妙的操作。

该函数的主体(除以外的所有东西u)非常简单:

+QiR2smc2+0dt#.BM
+QiR2smc2+0dt#.BMG    Implicit variable
                      G will store the list of numbers from the previous iteration.
              .BMG    Map each number to its binary representation
            t#        Filter out the ones of length 1 (0 and 1)
      m               Map the remaining binary
         +0d          Prefix with a 0
       c2             Chop in half.
                      Since c puts the larger half first, prefixing with a 0
                      makes the chop work out right, and doesn't change the value.
     s                Concatenate
  iR2                 Map back to binary
+Q                    Add the input to the front of the list

此代码删除0和1,分割每个数字,然后在前面添加输入。

u 将在函数的先前结果上运行此函数,直到结果停止更改。

使用什么初始值u?那是聪明的部分:代码没有指定要使用的值,因此默认为输入。但是输入不是数字列表,而是一个数字。Pyth通过循环将第一个时间的数字隐式强制为-的范围[0, 1, ..., Q-1]。看起来不像我们想要的输出。幸运的是,u无论初始输入是什么,都将找到正确的结果-所需的输出是该函数的唯一固定点,重复应用将始终达到该结果。

我们来看一下带有input的程序的中间值7。我已经强调了结果的前缀,无论初始输入如何,该前缀都保证是正确的:

  1. 7(含蓄地[0, 1, 2, 3, 4, 5, 6]

  2. [7,1, 0, 1, 1, 1, 0, 1, 1, 1, 2]

  3. [7, 1, 3,1, 0]

  4. [7, 1, 3, 1, 1]

这是输出。


打包的Pyth,16个字节

请注意,由于Pyth仅使用0-127范围的ASCII,因此可以使用7位编码而不是8位编码对其进行压缩。因此,上述程序可以打包为16个字节。结果程序为:

ꮎ�L����[
    ���4

十六进制转储:

0000000: eaae 8e9a 4cb9 edc6 c95b 0c9d 11ae 8534  ....L....[.....4

可以在这里找到口译员。提供输入作为命令行参数。

该语言的代码页(打包的Pyth)是ASCII的0-127范围,每个字符用7位表示,并在末尾填充。因此,上述不可读的十六进制转储表示:

u+QiR2smc2+0dt#.BM

但以16个字节为单位。


6

05AB1E21 20 18 17字节

,¸[Žrbvy0ì2äCʒ=1›

在线尝试!

说明

,¸[Žrbvy0ì2äCʒ=1›   Argument n
,¸                  Print n and push n as array
  [Ž                Loop until stack is empty
    r               Reverse stack
     b              Convert elements in array to binary
      v             For each y in array
       y0ì2ä        Prepend '0' to y and split it into 2 elements
                    (the first element will take the additional character)
            C       Convert elements to decimal
             ʒ=1›   Keep only elements greater than 1, while printing each element

@JonathanAllan Yep现在修复了它。例子似乎没有解决问题,谢谢:)
kalsowerus

ʒ-这个新的代码页... 05AB1E果冻何时开始销售?我喜欢。
魔术章鱼缸

4

JavaScript(ES6),99个字节

这看起来太长了。可能会有更好的方法来获得正确的订单。

f=(n,p=(a=[],1),i=33-Math.clz32(n)>>1)=>(a[p]=n)>1?f(n>>i,p*=2)&&f(n&(1<<i)-1,p+1):a.filter(n=>1/n)

演示版


4

果冻21 20 字节

-1个字节,方法是删除单子链,然后处理将空列表从二进制转换为0的结果。

ỊÐḟBUœs€2UḄF
WÇÐĿṖUF

单调链接,获取一个数字并返回指定的列表。

在线尝试!

怎么样?

ỊÐḟBUœs€2UḄF - Link 1, perform an iteration: list of numbers
 Ðḟ          - filter out if:
Ị            -   insignificant (absolute value <= 1 - hence any 0s or 1s)
   B         - convert to a binary list (vectorises)
    U        - upend (reverse each)
     œs€2    - split €ach into 2 equal chunks (the first half is longer if odd ...hence
         U   - upend (reverse each)         ...this upend and the previous one)
          Ḅ  - convert from binary list to number (vectorises, although when the filter
             -                                     removes everything a zero is yielded)
           F - flatten the resulting list of lists to a single list

WÇÐĿṖUF - Main link: number
W       - wrap in a list
  ÐĿ    - loop and collect results until no change occurs:
 Ç      -   call last link (1) as a monad
    Ṗ   - pop (remove the last element - a list containing a single zero which results
        -     from the effect of Ḅ when link 1's input only contained ones and zeros)
     U  - upend (put the iterations into the required order)
      F - flatten to yield a single list

这是如何运作的?
caird coinheringaahing

@ Satan'sSon我刚刚添加了一个解释
乔纳森·艾伦

您在我评论的同时添加了它:D
Caird coinheringaahing

@ØrjanJohansen两种方式的字节开销相同
Jonathan Allan

哦,首先没有看到Pyth答案,该答案已经使用了该技巧。
与Orjan约翰森

2

Java 7,541字节

import java.util.*;List l=new ArrayList(),L=new ArrayList();String c(int n){l.add(x(n));return a(n+" ",l,n);}String a(String r,List q,Integer n){boolean e=q.equals(l),E=q.equals(L);if(e)L.clear();else l.clear();for(String i:new ArrayList<String>(q)){int s=i.length()/2,a=n.parseInt(i.substring(0,s),2),z=n.parseInt(i.substring(s),2);r+=a+" "+z+" ";if(e&a>1)L.add(x(a));if(e&z>1)L.add(x(z));if(E&a>1)l.add(x(a));if(E&z>1)l.add(x(z));}if(e&L.size()>0)r=a(r,L,n);if(E&l.size()>0)r=a(r,l,n);return r;}String x(Integer n){return n.toString(n,2);}

长时间保持原始订单很麻烦,否则这将只是一个简单的循环和递归调用原则。尽管如此,在保留订单的同时找出一个有趣的挑战。

说明:

import java.util.*;                    // Required import for List and Array List

List l=new ArrayList(),L=new ArrayList(); 
                                       // Two Lists on class-level

String c(int n){                       // Method (1) with integer parameter and String return-type
  l.add(x(n));                         //  Start by adding the binary-String of the input integer to list `l`
  return a(n+" ",l,n);                 //  And let the magic begin in method `a` (2)
}                                      // End of method (1)

String a(String r,List q,Integer n){   // Method (2) with a bunch of parameters and String return-type
  boolean e=q.equals(l),E=q.equals(L); //  Determine which of the two class-level Lists the parameter-List is
  if(e)                                //  If it's `l`:
    L.clear();                         //   Empty `L`
  else                                 //  If it's `L` instead:
    l.clear();                         //   Empty `l`
  for(String i:new ArrayList<String>(q)){
                                       //  Loop over the input list (as new ArrayList to remove the reference)
    int s=i.length()/2,                //   Get the length of the current item in the list divided by 2
                                       //   NOTE: Java automatically floors on integer division,
                                       //   which is exactly what we want for the splitting of odd-length binary-Strings
    a=n.parseInt(i.substring(0,s),2),  //   Split the current binary-String item in halve, and convert the first halve to an integer
    z=n.parseInt(i.substring(s),2);    //   And do the same for the second halve
    r+=a+" "+z+" ";                    //   Append the result-String with these two integers
    if(e&a>1)                          //   If the parameter List is `l` and the first halve integer is not 0:
      L.add(x(a));                     //    Add this integer as binary-String to list `L`
    if(e&z>1)                          //   If the parameter List is `l` and the second halve integer is not 0:
      L.add(x(z));                     //    Add this integer as binary-String to List `L`
    if(E&a>1)                          //   If the parameter List is `L` and the first halve integer is not 0:
      l.add(x(a));                     //    Add this integer as binary-String to List `l`
    if(E&z>1)                          //   If the parameter List is `L` and the second halve integer is not 0:
      l.add(x(z));                     //    Add this integer as binary-String to List `l`
  }                                    //  End of loop
  if(e&L.size()>0)                     //  If the parameter List is `l` and List `L` now contains any items:
    r=a(r,L,n);                        //   Recursive call with List `L` as parameter
  if(E&l.size()>0)                     //  If the parameter List is `L` and List `l` now contains any items:
    r=a(r,l,n);                        //   Recursive call with List `l` as parameter
  return r;                            //  Return the result-String with the now appended numbers
}                                      // End of method (2)

String x(Integer n){                   // Method (3) with Integer parameter and String return-type
  return n.toString(n,2);              //  Convert the integer to its Binary-String
}                                      // End of method (3)

测试代码:

在这里尝试。

import java.util.*;
class M{
  List l=new ArrayList(),L=new ArrayList();String c(int n){l.add(x(n));return a(n+" ",l,n);}String a(String r,List q,Integer n){boolean e=q.equals(l),E=q.equals(L);if(e)L.clear();else l.clear();for(String i:new ArrayList<String>(q)){int s=i.length()/2,a=n.parseInt(i.substring(0,s),2),z=n.parseInt(i.substring(s),2);r+=a+" "+z+" ";if(e&a>1)L.add(x(a));if(e&z>1)L.add(x(z));if(E&a>1)l.add(x(a));if(E&z>1)l.add(x(z));}if(e&L.size()>0)r=a(r,L,n);if(E&l.size()>0)r=a(r,l,n);return r;}String x(Integer n){return n.toString(n,2);}

  public static void main(String[] a){
    M m=new M();
    System.out.println(m.c(255));
    m.l.clear();
    m.L.clear();
    System.out.println(m.c(225));
    m.l.clear();
    m.L.clear();
    System.out.println(m.c(32));
  }
}

输出:

255 15 15 3 3 3 3 1 1 1 1 1 1 1 1 
225 14 1 3 2 1 1 1 0 
32 4 0 1 0 

2

Python 2,110个字节

l=[input()];i=1
while i:
 z=0
 for k in l[-i:]:
	if k>1:b=~-len(bin(k))/2;l+=[k>>b,k&2**b-1];z+=2
 i=z
print l

在线尝试!


2

视网膜,142字节

.+
$*
+`(1+)\1
${1}0
01
1
{`.+$
$&¶<$&>
+`;(\d*)>
>;<$1>
<.>

{`(\d)>
>$1
}`<(\d)
$1<
<>
;
\b0+\B

}`^;|;\B

¶
;
;;

1
01
+`10
011
0\B

1+
$.&

在线尝试!


2

PHP,132字节

for($r=[$argn];""<$n=$r[+$i++];)$n<2?:[$r[]=bindec(substr($d=decbin($n),0,$p=strlen($d)/2)),$r[]=bindec(substr($d,$p))];print_r($r);

在线尝试!


根据此页面中的“尝试在线”系统,这行不通
Martin Barker

@MartinBarker是什么意思?
约尔格Hülsermann

tio.run/nexus/…= > Array( [0] => 225 [1] => 14 [2] => 1 [3] => 3 [4] => 2 [5] => 1 [6] => 1 [7] => 1 [8] => 0 )时不= 255 15 15 3 3 3 3 1 1 1 1 1 1 1 1 1
Martin Barker

@MartinBarker您必须更改标题Version中的输入。更改变量$argn如果从命令行运行带有-R选项的PHP,则此变量可用。这是输入255的示例,请在线尝试!
约尔格Hülsermann

那就是我要说的,根据try it online系统,它不起作用。(链接后)
马丁·巴克


1

红宝石,98字节

f=->*a{a==[]?a:a+=f[*a.flat_map{|i|s='%b'%i;i>1?[s[0...h=s.size/2].to_i(2),s[h..-1].to_i(2)]:[]}]}

在线尝试!

只是Value Ink答案的基本优化:使用flat_map而不是map ... flatten,然后使用

a==[]?a 代替 a==[]?[]

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.