Brainfuckのビット演算子


13

あなたの仕事は、以下の二項演算子のそれぞれに対して1つのBrainfuckプログラムを作成することです。各プログラムは、入力から1つまたは2つの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操作を心配する必要はありません。


また、iotのような類似した最小限の言語でタスクを解決できますか?
FUZxxl

ビット単位の演算子が組み込まれていない限り、他の言語に異議はありません。
captncraig

回答:


7

スコア:275

バイナリカウンターを使用してこれらを展開する方が適切です。直感的でない部分は、AまたはBが0である可能性を扱います。最初の3つの実際のビット操作で非破壊的なフロー制御を使用する有益な方法は見つかりませんでした。ちなみに、これらはすべて16ビットセルで正常に動作し、32ビットでゆっくり動作するはずです。

XOR、86

AとBがセル1と2にあり、A XOR Bをセル2に保存すると仮定します。ポインタはセル0で始まり、セル5で終わります。

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

そして、78

AとBがセル1と2にあり、A OR Bをセル4に格納すると仮定します。ポインターはセル0で始まり、セル5で終わります。

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

または、86

AとBがセル1と2にあり、セル2にA OR Bを格納すると仮定します。ポインタはセル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


XOR、221

結果はセル10に書き込まれ、ポインターはセル5で終了します

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

そして、209

結果はセル10に書き込まれ、ポインターはセル5で終了します

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

または、211

結果はセル10に書き込まれ、ポインターはセル5で終了します

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

左に回転、38

結果はセル1に書き込まれ、ポインターはセル4で終了します

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

ない、7

結果はセル1に書き込まれ、ポインターはセル0で終了します

+[+>+<]


説明:

XOR、AND、ORはすべて同様の方法で機能します。各数値のn / 2を計算し、n mod 2を記憶します。単一ビットの論理XOR / AND / ORを計算します。結果のビットが設定されている場合、結果に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

これらがどのように機能しているかについて少し説明を聞きたいと思います。あなたの最初の3つは最も内側の部分を除いてかなり似ているように見えますが、何らかの種類のバイナリ展開(したがって8セルが必要です)、ビットごとの比較、または2つの何らかの組み合わせを行っているかどうかはわかりません。ステップスルーでは見づらい。
captncraig

@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.

NOT A-7

番号Aはセル0にロードされます。

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

+[->-<]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.