Brainfuck'ta Bitsel Operatörler


13

Göreviniz, aşağıdaki ikili işleçlerin her biri için bir beyin fırtınası programı oluşturmaktır. Her program girişten bir veya iki 8-bit sayı (A ve B) almalı ve belirtilen işlemi hesaplamalıdır:

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

5'in hepsini uygulamak zorunda değilsiniz. Puan şu şekilde hesaplanır:

#totalCharacters + {4000 * #problemsNotCompleted}

Geçerli puanlar sıfır (en iyi) ile 20.000 (hiçbir şey tamamlanmadı) arasındadır.

Sonucu nerede sakladığınız ya da girişi koruyup korumadığınız umurumda değil. 8-bit hücreler ve yalnızca sağ tarafa ihtiyacınız olduğu kadar boş hücre olduğunu varsayın.

Sayıların zaten sizin için en uygun bellek konumu içinde olduğunu varsayabilirsiniz, bu nedenle G / Ç işlemleri için endişelenmenize gerek yoktur.


Görevi iot gibi minimalist bir dilde de çözebilir miyiz?
FUZxxl

Bitsel işleçler yerleşik olmadığı sürece başka dillere itirazım yok.
captncraig

Yanıtlar:


7

Puan: 275

Bunları ikili bir sayaçla genişletmek daha iyidir. Daha az sezgisel parçalar A veya B'nin 0 olması olasılığı ile ilgilenir. İlk üçünün gerçek bit manipülasyonunda tahribatsız akış kontrolünü kullanmanın karlı bir yolunu bulamadım. Bu arada bunların hepsi 16 bit hücrelerle ve yavaşça 32 bit ile çalışmalıdır.

XOR, 86

A ve B'nin 1 ve 2 hücrelerinde olduğunu, A XOR B hücresini 2 hücresinde sakladığını, ibre 0 hücresinde başlayıp 5 hücresinde sona erdiğini varsayar.

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

VE, 78

A ve B'nin hücre 1 ve 2'de olduğu, A OR B'yi hücre 4'te sakladığı, işaretçi 0 hücresinde başlayıp 5 hücresinde bittiği varsayılmaktadır.

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

VEYA, 86

A ve B'nin hücre 1 ve 2'de olduğunu, A OR B'yi hücre 2'de depoladığını, işaretçi 0 hücresinde başlayıp 5 hücresinde sona erdiğini varsayar.

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

ROL, 18

A'nın 0 hücresinde olduğunu, A ROL 1'ini hücre 1'de sakladığını, imlecin 0 hücresinde başlayıp bittiğini varsayar.

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

DEĞİL, 7

A'nın 0 hücresinde olduğunu, A hücresini 1 hücresinde saklayamadığını, işaretçinin 0 hücresinde başlayıp biteceğini varsayar.

+[>-<-]

Bu gerçekten kısa ve oldukça havalı. +1
kopyalayın

Ciddi etkileyici gelişmeler.
captncraig

8

Puan: 686

Tüm snippet'ler, sayıların zaten 0 ve 1 hücresine yüklendiğini ve işaretçinin 0 hücresini gösterdiğini varsayar. Şimdilik kodu şöyle deneyebilirsiniz:

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


XOR, 221

Sonuç 10 hücresine yazılır, işaretçi 5. hücrede biter

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

VE, 209

Sonuç 10 hücresine yazılır, işaretçi 5. hücrede biter

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

VEYA, 211

Sonuç 10 hücresine yazılır, işaretçi 5. hücrede biter

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

Sola Döndür, 38

Sonuç hücre 1'e yazılır, işaretçi hücre 4'te biter

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

DEĞİL, 7

Sonuç hücre 1'e yazılır, işaretçi 0 hücresinde biter

+[+>+<]


Açıklama:

XOR, VE ve VEYA hepsi benzer şekilde çalışır: Her sayı için n / 2 hesapla ve n mod 2'yi hatırla. Tek bitler için mantıksal XOR / VE / VEYA hesapla. Ortaya çıkan bit ayarlanmışsa, sonuca 2 ^ n ekleyin. Bunu 8 kez tekrarlayın.

Kullandığım bellek düzeni bu:

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

  8        9        10
temp  |  temp  |  result

İşte XOR kaynağı (sayılar işaretçinin o sırada nerede olduğunu gösterir):

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

    <<<
]


Sola döndürme için, 2n hücresinde 2n'nin sıfır olup olmadığını belirlemek için bir kez daha bir işaretleyici vardır, çünkü yalnızca bir hücrenin doğrudan sıfır olup olmadığını belirleyebilirsiniz. Bu durumda, hücre 4'e bir taşıma biti yazılır ve daha sonra 2n'ye eklenir. Bu bellek düzeni:

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

Harika iş! Her programın konsoldan girdi almasını istedim, ancak daha çok düşündüğümde, yolunuz iyi çalışıyor. Eklemenize gerek yok ,>,<. Soruyu düzenleyeceğim.
captncraig

Bunların nasıl çalıştığına dair biraz açıklama duymak isterim. İlk üçünüz en iç kısım hariç oldukça benzer görünüyor, ancak bir çeşit ikili genişleme (dolayısıyla 8 hücre gerekiyor) veya biraz karşılaştırmalı veya ikisinin bir kombinasyonunu yapıp yapmadığınızdan emin değilim. İçinden geçerek görmek zor.
captncraig

@CMP Daha sonra bir açıklama ekleyeceğim
kopyalayın

3

Puan (şimdiki): 12038837 / -

Programlar, sayıların belirtilen herhangi bir hücreye, tarafından ,veya benzeri şekilde yüklendiğini varsayar . Ayrıca tüm hücrelerin gerektiğinde sarma ile 8 bit imzasız olduğunu varsayar. Her snippet'in başında numaralar 0 hücresine (ve gerekirse 1) yüklenir.

Bit işlemleri - 799

Bit işlemleri aynı genel yapıyı takip eder.

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:

Sola A Döndür, 1 - 31 / -

Sayı A0 hücresine yüklenir.

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 DEĞİL

Sayı A0 hücresine yüklenir.

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

+[->-<]
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.