Opérateurs au niveau du bit dans Brainfuck


13

Votre tâche consiste à créer un programme brainfuck pour chacun des opérateurs binaires suivants. Chaque programme doit prendre un ou deux nombres à 8 bits (A et B) en entrée et calculer l'opération spécifiée:

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

Vous n'êtes pas obligé de mettre en œuvre tous les 5. Le score est calculé par:

#totalCharacters + {4000 * #problemsNotCompleted}

Les scores valides vont donc de zéro (le meilleur) à 20 000 (rien de terminé).

Peu m'importe où vous stockez le résultat, ou si vous conservez ou non l'entrée. Supposons des cellules 8 bits et autant de cellules vides que nécessaire à droite uniquement.

Vous pouvez supposer que les numéros se trouvent déjà dans l'emplacement de mémoire qui vous convient le mieux, vous n'avez donc pas à vous soucier des opérations d'E / S.


Pouvons-nous également résoudre la tâche dans un langage minimaliste similaire comme iot?
FUZxxl

Je n'ai aucune objection à l'égard d'autres langues, tant qu'il n'y a pas d'opérateurs au niveau du bit intégrés.
captncraig

Réponses:


7

Résultat: 275

Il est préférable de les étendre avec un compteur binaire. Les parties moins intuitives traitent de la possibilité que A ou B soit égal à 0. Je n'ai pas trouvé de moyen rentable d'utiliser le contrôle de flux non destructif dans la manipulation réelle des bits des trois premiers. Soit dit en passant, ceux-ci devraient tous fonctionner correctement avec des cellules 16 bits et lentement avec 32 bits.

XOR, 86

Suppose que A et B se trouvent dans les cellules 1 et 2, stocke A XOR B dans la cellule 2, le pointeur commence dans la cellule 0 et se termine dans la cellule 5.

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

ET, 78

Suppose que A et B se trouvent dans les cellules 1 et 2, stocke A OU B dans la cellule 4, le pointeur commence dans la cellule 0 et se termine dans la cellule 5.

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

OU, 86

Suppose que A et B se trouvent dans les cellules 1 et 2, stocke A OU B dans la cellule 2, le pointeur commence dans la cellule 0 et se termine dans la cellule 5.

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

ROL, 18

Suppose que A est dans la cellule 0, stocke A ROL 1 dans la cellule 1, le pointeur commence et se termine dans la cellule 0.

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

NON, 7

Suppose que A est dans la cellule 0, stocke PAS A dans la cellule 1, le pointeur commence et se termine dans la cellule 0.

+[>-<-]

C'est vraiment court et plutôt cool. +1
copie du

Améliorations sérieusement impressionnantes.
captncraig

8

Résultat: 686

Tous les extraits supposent que les nombres sont déjà chargés dans les cellules 0 et 1 et que le pointeur pointe vers la cellule 0. Je peux ajouter un extrait atoi plus tard si cela est nécessaire pour le défi. Pour l'instant, vous pouvez essayer le code comme ceci:

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


XOR, 221

Le résultat est écrit dans la cellule 10, le pointeur se termine dans la cellule 5

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

ET, 209

Le résultat est écrit dans la cellule 10, le pointeur se termine dans la cellule 5

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

OU, 211

Le résultat est écrit dans la cellule 10, le pointeur se termine dans la cellule 5

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

Rotation à gauche, 38

Le résultat est écrit dans la cellule 1, le pointeur se termine dans la cellule 4

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

NON, 7

Le résultat est écrit dans la cellule 1, le pointeur se termine à la cellule 0

+[+>+<]


Explication:

XOR, AND et OR fonctionnent tous de façon similaire: Calculez n / 2 pour chaque nombre et souvenez-vous de n mod 2. Calculez le XOR / AND / OR logique pour les bits simples. Si le bit résultant est défini, ajoutez 2 ^ n au résultat. Répétez cela 8 fois.

Voici la disposition de la mémoire que j'ai utilisée:

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

  8        9        10
temp  |  temp  |  result

Voici la source de XOR (les nombres indiquent où se trouve le pointeur à ce moment):

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

    <<<
]


Pour la rotation vers la gauche, une fois encore, il y a un marqueur dans la cellule 2 pour déterminer si 2n est zéro, car vous ne pouvez déterminer que si une cellule est non nulle directement. Si c'est le cas, un bit de retenue est écrit dans la cellule 4 et ajouté plus tard à 2n. Voici la disposition de la mémoire:

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

Bon travail! J'avais l'intention que chaque programme reçoive des données de la console, mais plus j'y pense, plus votre chemin fonctionne bien. Pas besoin de vous faire ajouter ,>,<. Je vais modifier la question.
captncraig

Je serais intéressé d'entendre un peu d'explication sur leur fonctionnement. Il semble que vos trois premiers soient assez similaires, sauf pour la partie la plus intérieure, mais je ne sais pas si vous faites une sorte d'expansion binaire (d'où 8 cellules nécessaires), ou une comparaison peu à peu, ou une combinaison des deux. Difficile à voir en traversant.
captncraig

@CMP J'ajouterai une explication plus tard
copie

3

Résultat (actuel): 12038837 / -

Les programmes supposent que les nombres sont chargés dans la cellule spécifiée, par ,ou similaire. Il suppose également que toutes les cellules ne sont pas signées 8 bits avec un habillage selon les besoins. Au début de chaque extrait, les nombres sont chargés dans la cellule 0 (et 1 si nécessaire).

Opérations sur les bits - 799

Les opérations sur les bits suivent la même structure générale.

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:

Tourner à gauche A, 1 - 31 / -

Le numéro Aest chargé dans la cellule 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.

PAS A - 7

Le numéro Aest chargé dans la cellule 0.

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

+[->-<]
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.