ผู้ประกอบการ Bitwise ใน 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


เราสามารถแก้ปัญหาด้วยภาษามินิมอลลิสต์เช่น iot ได้หรือไม่?
FUZxxl

ฉันไม่มีการคัดค้านภาษาอื่นใด ๆ ตราบใดที่ไม่มีตัวดำเนินการระดับบิตในตัว
captncraig

คำตอบ:


7

คะแนน: 275

มันทำงานได้ดีกว่าในการขยายด้วยตัวนับไบนารี ชิ้นส่วนที่ใช้งานง่ายน้อยลงจัดการกับความเป็นไปได้ที่ A หรือ B คือ 0 ฉันไม่พบวิธีที่ได้ผลกำไรในการใช้การควบคุมการไหลแบบไม่ทำลายในการจัดการบิตจริงของสามตัวแรก บังเอิญสิ่งเหล่านี้ควรทำงานได้ดีกับเซลล์ 16 บิตและช้าด้วย 32 บิต

แฮคเกอร์, 86

สมมติว่า A และ B อยู่ในเซลล์ 1 และ 2 เก็บ A XOR B ในเซลล์ 2 ตัวชี้เริ่มในเซลล์ 0 และสิ้นสุดในเซลล์ 5

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

และ, 78

สมมติว่า A และ B อยู่ในเซลล์ 1 และ 2 เก็บ A หรือ B ในเซลล์ 4 ตัวชี้เริ่มในเซลล์ 0 และสิ้นสุดในเซลล์ 5

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

หรือ, 86

สมมติว่า A และ B อยู่ในเซลล์ 1 และ 2 เก็บ A หรือ B ในเซลล์ 2 ตัวชี้เริ่มในเซลล์ 0 และสิ้นสุดในเซลล์ 5

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

ROL, 18

ถือว่า A อยู่ในเซลล์ 0 เก็บ A ROL 1 ในเซลล์ 1 ตัวชี้เริ่มต้นและสิ้นสุดในเซลล์ 0

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

ไม่ใช่ 7

ถือว่า A อยู่ในเซลล์ 0 เก็บไม่ได้ในเซลล์ 1 ตัวชี้เริ่มต้นและสิ้นสุดในเซลล์ 0

+[>-<-]

มันสั้นและเท่ห์จริงๆ +1
คัดลอก

การปรับปรุงที่น่าประทับใจอย่างจริงจัง
captncraig

8

คะแนน: 686

ตัวอย่างทั้งหมดสมมติว่ามีการโหลดตัวเลขในเซลล์ 0 และ 1 แล้วและตัวชี้ชี้ไปที่เซลล์ 0 ฉันสามารถเพิ่มข้อมูลโค้ด atoi ในภายหลังหากจำเป็นสำหรับความท้าทาย ในตอนนี้คุณสามารถลองใช้รหัสดังนี้:

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


แฮคเกอร์ 221

ผลลัพธ์ถูกเขียนไปที่เซลล์ 10 ตัวชี้สิ้นสุดที่เซลล์ 5

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

และ, 209

ผลลัพธ์ถูกเขียนไปที่เซลล์ 10 ตัวชี้สิ้นสุดที่เซลล์ 5

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

หรือ, 211

ผลลัพธ์ถูกเขียนไปที่เซลล์ 10 ตัวชี้สิ้นสุดที่เซลล์ 5

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

หมุนซ้าย, 38

ผลลัพธ์ถูกเขียนลงในเซลล์ 1 ตัวชี้สิ้นสุดที่เซลล์ 4

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

ไม่ใช่ 7

ผลลัพธ์ถูกเขียนลงในเซลล์ 1 ตัวชี้สิ้นสุดที่เซลล์ 0

+[+>+<]


คำอธิบาย:

XOR และและหรือทั้งหมดทำงานในลักษณะที่คล้ายกัน: คำนวณ n / 2 สำหรับแต่ละหมายเลขและจดจำ n mod 2 คำนวณตรรกะ XOR / AND / หรือสำหรับบิตเดียว หากตั้งค่าบิตผลลัพธ์ให้เพิ่ม 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

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

ไม่ใช่ 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.