4

Given that a number in the 0th cell of tape is filled and the rest are all just used as scratch cells (i.e. they all start at 0 and are temporaries -- I don't care what happens to them), I would like to replace the 0th cell with a 0 or a 1. 0 if even, 1 if odd.

Basically, what I want to do is (in C-esque pseudocode):

cell[0] = (cell[0] % 2)

I know that there exists a divmod algorithm defined as follows:

If one does not need to preserve n, use this variant:

# >n d
[->-[>+>>]>[+[-<+>]>+>>]<<<<<]
# >0 d-n%d n%d n/d

However, since X % 2 == X & 1, i.e. X mod 2 is the rightmost bit of X, I think that divmod might be overkill in terms of complexity of calculation.

Is there any better algorithm/technique for finding out if the cell is even or not?

Jay Bosamiya
  • 3,011
  • 2
  • 14
  • 33

4 Answers4

5

You need an algorithm that keeps only parity, you could do it like that :

result=0
while(n > 0) {
  result++;
  n--;
  if(n > 0) {
    result--;
    n--;
  }
}

To test n without losing its value, you need to copy it : copy from A to B and C then move C to A. You could test B and keep n into A. Here is the brainfuck code :

[->+<] # move @0 to @1
> # goto @1
[-<+ # if @1 then decrements @1 and increments @0
 > # goto @1
 [->+>+<<] # if @1 then move @1 to @2 and @3
 >> # goto @3
 [-<<+>>] # if @3 then move @3 to @1
 < # goto @2
 [<-<->>[-]] # if @2 then decrements @0, decrements @1 and sets 0 into @2
 < # go to @1
] # continue loop if @1 is not null
< # goto @0

light-form:

[->+<]>[-<+>[->+>+<<]>>[-<<+>>]<[<-<->>[-]]<]<
alexscott
  • 86
  • 3
3

N odd or even:

>,             load m1 with N

[-[->]<]+      set m0 = 1 if odd
               set m1 = 1 if even
6502asm
  • 51
  • 2
  • Can you explain how this works? Also, won't this go further left than m0 (which then leads to undefined behaviour)? – Jay Bosamiya Jan 23 '16 at 06:45
  • I played with this over a few days, got it from 11 to 9 commands. Probably clear how it works, now. – 6502asm Feb 02 '16 at 15:50
2

Here is a version that completely resolves P:

Is N odd or even?

>,              ~load m1 with N (not counted for golf scoring)
>>+>+<<<        ~set 'trail of breadcrumbs' so we can figure out 
                   where P is
[-[->]<]+       ~if N is odd set m0 = 1
>>>[>]          ~figure out where P is
<[-<]<[-]<      ~go back to m1 and zero out if N is even

Pointer P ends on m0 odd: m0 = 1 even: m0 = 0

6502asm
  • 51
  • 2
0

You have to check the modulus to know whether it's even or odd. It's the simplest way. But I'd be wary of that divmod algorithm you posted. It should work when checking modulo 2 but if I remember correctly don't try to divide by 1 using it.

On a PC you could just AND the number with 1 (assuming it's an integer). But brainfuck doesn't have an AND operator, so you're going to have to go the long way round. You know the computer stores numbers in binary, but that's none of brainfuck's concern. It doesn't give you an array of binary values to manipulate. It gives you an array of numbers which you can only increment, decrement or compare to 0.

Cedric Mamo
  • 1,724
  • 2
  • 18
  • 33