Brainfuck中的按位运算符


13

您的任务是为以下每个二进制运算符创建一个Brainfuck程序。每个程序应从输入中获取一个或两个8位数字(A和B)并计算指定的运算:

  1. A XOR B
  2. A AND B
  3. A OR B
  4. A Shifted Left by 1 (circular shift)
  5. NOT A

您不必全部实施5。得分的计算方式为:

#totalCharacters + {4000 * #problemsNotCompleted}

因此,有效分数是从零(最佳)到20,000(未完成)。

我不在乎您将结果存储在哪里,也不管您是否保留输入。假设8位单元以及仅在右侧需要的空单元数。

您可能会认为数字已经在最适合您的任何内存位置中,因此您无需担心IO操作。


我们是否也可以使用类似的简约语言(如物联网)解决任务?
FUZxxl 2012年

我不反对任何其他语言,只要没有内置的按位运算符即可。
captncraig

Answers:


7

得分:275

用二进制计数器扩展它们更好。不太直观的部分处理的是A或B为0的可能性。在前三个的实际位操作中,我没有找到使用无损流量控制的有利方法。顺便说一句,这些都应该适用于16位单元,而缓慢地适用于32位。

异或,86

假定A和B在单元格1和2中,将A XOR B存储在单元格2中,指针在单元格0中开始,在单元格5中结束。

-[[>>>>>>[>>>]++[-<<<]<<<-]>]>>>[<]>[[>[>-<-]>[<<<<<<+>>>>>>[-]]>]+[<[<<<++>>>-]<<]>>]

AND,78

假设A和B在单元格1和2中,将A OR B存储在单元格4中,指针在单元格0中开始,在单元格5中结束。

-[[>>>>>>[>>>]++[-<<<]<<<-]>]>>>[<]>[[>[>[<<<<+>>>>-]<-]>+>]<[<[<<<++>>>-]<<]]

或86

假定A和B在单元格1和2中,将A OR B存储在单元格2中,指针在单元格0中开始,在单元格5中结束。

-[[>>>>>>[>>>]++[-<<<]<<<-]>]>>>[<]>[[>[>+<-]>[<<<<<<+>>>>>>[-]]>]+[<[<<<++>>>-]<<]>>]

ROL,18岁

假设A在单元格0中,将A ROL 1存储在单元格1中,指针在单元格0中开始和结束。

[>++[>>]<[>+>]<<-]

不,7

假设A在单元0中,NOT A存储在单元1中,指针在单元0中开始和结束。

+[>-<-]

那真的很短而且很酷。+1
复制

令人印象深刻的改进。
captncraig

8

得分:686

所有代码段均假定数字已经加载到单元格0和1中,并且指针指向单元格0。如果挑战需要,我可以稍后添加一个atoi代码段。现在,您可以尝试如下代码:

+++++++++>    number 1
++++<         number 2


异或221

结果写入单元格10,指针在单元格5处结束

>>>>>++++++++[-<<<<<[->>+<<[->>->+<]>>[->>>>+<<]<<<<]>>>[-<<<+>>>]<<[->+<[->->+>
>>>>]>[->>>>>+>>]<<<<<<<<]>>[-<<+>>]>>>[->>+<<]>[>[-<->]<[->+<]]>[[-]<<<[->+>-<<
]>[-<+>]+>+++++++[-<[->>++<<]>>[-<<+>>]<]<[->>>>+<<<<]>>]<<<]

AND,209

结果写入单元格10,指针在单元格5处结束

>>>>>++++++++[-<<<<<[->>+<<[->>->+<]>>[->>>>+<<]<<<<]>>>[-<<<+>>>]<<[->+<[->->+>
>>>>]>[->>>>>+>>]<<<<<<<<]>>[-<<+>>]>>>[->[->+<]<]>[-]>[-<<<[->+>-<<]>[-<+>]+>++
+++++[-<[->>++<<]>>[-<<+>>]<]<[->>>>+<<<<]>>]<<<]

或211

结果写入单元格10,指针在单元格5处结束

>>>>>++++++++[-<<<<<[->>+<<[->>->+<]>>[->>>>+<<]<<<<]>>>[-<<<+>>>]<<[->+<[->->+>
>>>>]>[->>>>>+>>]<<<<<<<<]>>[-<<+>>]>>>[->>+<<]>[->+<]>[[-]<<<[->+>-<<]>[-<+>]+>
+++++++[-<[->>++<<]>>[-<<+>>]<]<[->>>>+<<<<]>>]<<<]

向左旋转,38

结果写入单元格1,指针在单元格4处结束

[->++>+<[>-]>[->>+<]<<<]>>>>[-<<<+>>>]

不,7

结果写入单元格1,指针在单元格0处结束

+[+>+<]


说明:

XOR,AND和OR都以类似的方式工作:为每个数字计算n / 2,并记住n mod2。为单个位计算逻辑XOR / AND / OR。如果结果位被置1,则将结果加2 ^ n。重复8次。

这是我使用的内存布局:

 0      1        2        3      4        5         6        7
n1  |  n2  |  marker  |  n/2  |  0  |  counter  |  bit1  |  bit2  |

  8        9        10
temp  |  temp  |  result

这是XOR的来源(数字表示当时指针的位置):

>>>>>
++++ ++++ counter
[
    -
    <<<<<

    divide n1 by two
    [ 0 
        -
        >>+ set marker 2
        << 0
        [->>->+<] dec marker inc n/2
        >> 2 or 4
        [->>>>+<<] 
        <<<<
    ]
    >>>
    [-<<<+>>>]
    <<

    divide n2 by two
    [ 1
        -
        >+ set marker 2
        < 1
        [->->+>>>>>] dec marker inc n/2
        > 2 or 9
        [->>>>>+>>]
        <<<< <<<< 
    ]
    >>[-<<+>>] 3

    >>> 6

    [->>+<<]>[>[-<->]<[->+<]]>  one bit xor 8

    [
        [-]<<< 5
        [->+>-<<] copy counter negative
        > 6
        [-<+>]
        +> 7
        ++++ +++  cell 6 contains a one and cell 7 how many bits to shift
        [-<[->>++<<]>>[-<<+>>]<]  2^n
        < 6
        [->>>>+<<<<]
        >> 8
    ]

    <<<
]


对于左旋转,再次在单元格2中有一个标记来确定2n是否为零,因为您只能直接确定单元格是否为非零。如果是这样,则将进位位写入单元4,然后加到2n。这是内存布局:

0      1        2       3       4   
n  |  2n  |  marker  |  0  |  carry 

做得好!我确实打算让每个程序从控制台获取输入,但是我考虑得越多,您的方法就越好。无需让您添加,>,<。我将编辑问题。
captncraig

我希望听到一些有关它们如何工作的解释。看起来除了最里面的部分外,前三个非常相似,但是我不确定您是在进行某种二进制扩展(因此需要8个单元格),还是进行一点点比较,还是两者的某种组合。单步执行很难看到。
captncraig 2012年

@CMP我稍后会添加解释
复制

3

得分(当前):12038 837 /-

程序假定通过,或类似方式将数字加载到指定的任何单元中。它还假定所有单元都是8位无符号的,并根据需要进行换行。在每个代码段的开头,数字将加载到单元格0(如果需要,则加载1)。

钻头操作-799

位操作遵循相同的一般结构。

Firstly, we define a divmod 2 (DM2) function.
CELLS:   A  B   C  D
INPUT:  *A  0   0  0
OUTPUT: *0 A/2 A%2 0
dp@A; while{
  dec A,2; inc B,1; dp@A; inc A,1
  while{ #Check if A was 1 at the start
    dec D,1; pour A,C; dp@A;
  }
  dec C,1; pour C,A; inc D,1; dp@D
  #If A was 1 at the start, D will be 1 here
  while{ 
    dec D,1; inc C,1; dec B,1; dp@D
  }
  dp@A
}
Translated into BF, we have
    [->+<[>>>-<<<[->>+<<]]>>-[<<+>>-]>+[-<+<->>]<<<]
I'm not that good at BF, so my algorithm may not be the smallest.

Next, we define the program.
In this, we assume that the numbers are loaded in $2 (cell 2) and $3.

inc $1,8; dp@1 {
  dec  $1
  pour $3,$6
  DM2  $2        # result in $3,$4
  DM2  $6        # result in $7,$8
  pour $7, $2
  pour $8,$5
  bop  $4,$5     # result in $6
  pour $1,$5
  pour $5,$4,$1
  down $4,$5     # decrease $4 till 0, decrease $5 by same amount
  inc  $5,#7
  shl  $6,$5
  pour $6,$0     # $0 is result
  dp@  1
}
#Now, the result is in $0

Translated to BF (with linebreaks for readability):
  >++++++++[
    ->>[->>>+<<<]<
    [->+<[>>>-<<<[->>+<<]]>>-[<<+>>-]>+[-<+<->>]<<<]>>>>  #DM2 $2
    [->+<[>>>-<<<[->>+<<]]>>-[<<+>>-]>+[-<+<->>]<<<]>     #DM2 $6
    [-<<<<<+>>>>>]>
    [-<<<+>>>]<<<<
    (bop)<<<
    [->>>>+<<<<]>>>>
    [<+<<<+>>>>-]<
    [->-<]>
    +++++++
    [->[-<<++>>]<<[->>+<<]>]
    [-<<<<<<+>>>>>>]
    <<<<<
  ]

Replace (bop) by the appropriate expression.

XOR works like this: (252-5+15=262)
  [->-<]>[[-]>+<]
AND works like this: (252-5+11=258)
  [>[>+<-]<-]
OR  works like this: (252-5+32=279)
  [->>>+<<<]>[->>+<<]>>[[-]<+>]<<<

So, combining these, we have a total of 262+258+279=799 D:

向左旋转A,1-31 /-

该号码A已加载到单元格0中。

Pseudocode
    $0 := A
    $1 := $0 << 1    # this has the effect of discarding the top bit of A
    $2 := $0
    $3 := $0 << 1
    $2 -= $1 >> 1    # $2 now contains the top bit of A
    if $2 then $3++  # $3 now contains A rotated left 1
    res:= $3         # the result is in cell 3 now

Real code
    [->++>+>++<<<]>[-->-<]>[>+<[-]]
If you don't always need the pointer in the same position,
substitute [>+>] for the last loop (3 less chars).
However, the pointer will then sometimes end up in position 2, sometimes in position 4.

不是-7

该号码A已加载到单元格0中。

Pseudocode
    $0  := A
    $0  += 1
    $1  := 256-$0   #since ~A=255-A
    res := $1

+[->-<]
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.