Toán tử bitwise trong Brainfuck


13

Nhiệm vụ của bạn là tạo một chương trình brainfuck cho mỗi toán tử nhị phân sau. Mỗi chương trình nên lấy một hoặc hai số 8 bit (A và B) từ đầu vào và tính toán thao tác đã chỉ định:

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

Bạn không phải thực hiện tất cả 5. Điểm được tính bằng:

#totalCharacters + {4000 * #problemsNotCompleted}

Vì vậy, điểm hợp lệ là từ 0 (tốt nhất) đến 20.000 (không có gì hoàn thành).

Tôi không quan tâm nơi bạn lưu trữ kết quả, hoặc liệu bạn có bảo toàn đầu vào hay không. Giả sử các ô 8 bit và càng nhiều ô trống bạn chỉ cần ở bên phải.

Bạn có thể cho rằng các số đã có trong bất kỳ vị trí bộ nhớ nào phù hợp nhất với bạn, vì vậy bạn không cần phải lo lắng về các hoạt động IO.


Chúng ta cũng có thể giải quyết nhiệm vụ bằng một ngôn ngữ tối giản mô phỏng như iot không?
FUZxxl

Tôi không phản đối bất kỳ ngôn ngữ nào khác, miễn là không có toán tử bit được xây dựng.
captncraig

Câu trả lời:


7

Điểm: 275

Nó hoạt động tốt hơn để mở rộng những cái này với một bộ đếm nhị phân. Các phần ít trực quan hơn liên quan đến khả năng A hoặc B là 0. Tôi không tìm thấy cách nào có lợi để sử dụng điều khiển luồng không phá hủy trong thao tác bit thực tế của ba phần đầu. Ngẫu nhiên tất cả đều hoạt động tốt với các ô 16 bit và chậm với 32 bit.

XOR, 86

Giả sử A và B ở trong ô 1 và 2, lưu A XOR B trong ô 2, con trỏ bắt đầu ở ô 0 và kết thúc ở ô 5.

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

VÀ, 78

Giả sử A và B ở trong ô 1 và 2, lưu A OR B trong ô 4, con trỏ bắt đầu ở ô 0 và kết thúc ở ô 5.

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

HOẶC, 86

Giả sử A và B ở trong ô 1 và 2, lưu A OR B trong ô 2, con trỏ bắt đầu ở ô 0 và kết thúc ở ô 5.

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

VAI TRÒ, 18

Giả sử A ở trong ô 0, lưu trữ ROL 1 trong ô 1, con trỏ bắt đầu và kết thúc ở ô 0.

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

KHÔNG, 7

Giả sử A ở trong ô 0, lưu trữ KHÔNG A trong ô 1, con trỏ bắt đầu và kết thúc ở ô 0.

+[>-<-]

Điều đó thực sự ngắn và khá tuyệt. +1
sao chép

Cải tiến nghiêm túc ấn tượng.
captncraig

8

Điểm: 686

Tất cả các đoạn mã giả định rằng các số đã được tải trong ô 0 và 1 và con trỏ trỏ đến ô 0. Tôi có thể thêm một đoạn trích sau nếu điều đó là bắt buộc cho thử thách. Hiện tại, bạn có thể thử mã như thế này:

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


XOR, 221

Kết quả được ghi vào ô 10, con trỏ kết thúc ở ô 5

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

VÀ, 209

Kết quả được ghi vào ô 10, con trỏ kết thúc ở ô 5

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

HOẶC, 211

Kết quả được ghi vào ô 10, con trỏ kết thúc ở ô 5

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

Xoay trái, 38

Kết quả được ghi vào ô 1, con trỏ kết thúc ở ô 4

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

KHÔNG, 7

Kết quả được ghi vào ô 1, con trỏ kết thúc tại ô 0

+[+>+<]


Giải trình:

XOR, AND và OR đều hoạt động theo kiểu tương tự: Tính n / 2 cho mỗi số và nhớ n mod 2. Tính toán XOR / AND / OR logic cho các bit đơn. Nếu bit kết quả được đặt, thêm 2 ^ n vào kết quả. Lặp lại 8 lần đó.

Đây là cách bố trí bộ nhớ tôi đã sử dụng:

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

  8        9        10
temp  |  temp  |  result

Đây là nguồn cho XOR (số cho biết con trỏ đang ở đâu tại thời điểm đó):

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

    <<<
]


Đối với xoay trái, một lần nữa có một điểm đánh dấu trong ô 2 để xác định xem 2n có bằng 0 hay không, vì bạn chỉ có thể xác định nếu một ô khác không trực tiếp. Nếu vậy, một bit mang được ghi vào ô 4 và sau đó được thêm vào 2n. Đây là cách bố trí bộ nhớ:

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

Công việc tuyệt vời Tôi đã có ý định cho mỗi chương trình lấy đầu vào từ bàn điều khiển, nhưng tôi càng nghĩ về nó, cách của bạn hoạt động tốt. Không cần phải làm cho bạn thêm ,>,<. Tôi sẽ chỉnh sửa câu hỏi.
captncraig

Tôi sẽ thích thú khi nghe một chút giải thích về cách thức hoạt động của chúng. Có vẻ như ba phần đầu của bạn khá giống nhau ngoại trừ phần trong cùng, nhưng tôi không chắc liệu bạn có đang thực hiện một số loại mở rộng nhị phân (do đó cần 8 ô), hoặc so sánh từng chút một, hoặc kết hợp cả hai. Khó nhìn thấy bằng cách bước qua.
captncraig

@CMP Tôi sẽ thêm một lời giải thích sau
sao chép

3

Điểm (hiện tại): 12038 837 / -

Các chương trình giả định số được tải trong bất kỳ ô nào được chỉ định, bằng ,hoặc tương tự. Nó cũng giả định rằng tất cả các ô là 8 bit không dấu với gói khi cần thiết. Khi bắt đầu mỗi đoạn mã, các số được tải tại ô 0 (và 1 nếu cần).

Hoạt động bit - 799

Các hoạt động bit theo cùng một cấu trúc chung.

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:

Xoay trái A, 1 - 31 / -

Số Ađược tải trong ô 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.

KHÔNG A - 7

Số Ađược tải trong ô 0.

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

+[->-<]
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.