Tips for golfing in brainfuck What general tips do you have for golfing in brainfuck? I'm looking for ideas that can be applied to code golf problems in general that are at least somewhat specific to brainfuck (e.g. "remove comments" is not an answer). Please post one tip per answer.
Putting one tip per answer would be way too many answers.


Learn to think in Brainfuck. It's very different than anything else. Read and write, and rewrite, and rewrite lots of brainfuck programs. The language doesn't give you much to work with, so it's important to use what it does give you flexibly and efficiently. Don't let any abstractions get between you and the language--get in there and grapple with it.
Get very comfortable with nondestructive flow control. To get out of a decision loop, rather than zeroing the starting cell by copying it elsewhere and then copying it back after leaving the loop, it's often better to move the pointer to a pre-existing zero nearby. Yes, this means the pointer will be in different places depending on whether you went through the loop, but that also means those places probably have different arrangements of nearby zeros and nonzeros, which you can use to resynch the pointer location using another loop. This technique is fundamental to good Brainfuck programming, and various forms of it will constantly prove useful.
That and the fact that every &gt; or &lt; costs mean that the details of memory layout are important. Try out as many variations of your layout as you have patience for. And remember, your memory layout does not have to be a rigid mapping of data to locations. It can morph over the course of execution.
On a larger scale, consider and even try implementing a variety of different algorithms. Initially it will not be obvious exactly what algorithm will be best; it may not even be obvious what basic approach will be best, and it will probably be something different than what would be best in a normal language.
If you're dealing with large or variable-sized data, see if there's any way you can possibly deal with it locally, without having to keep track of how big it is or your numerical location within it.
The same data can be two different things. (Most often, a number or character and also a nonzero positional marker. But see random.b, where a bit counter doubles as the value of one cell of a cellular automaton.)
The same code can do two different things, and it's a lot easier to make it do so in a language where code is as generic as &lt;+&lt;. Be alert to such possibilities. In fact, you may occasionally notice, even in what seems to be a well-written program, that there are small portions that could be deleted entirely, nothing added, and the thing would, by happenstance, still run flawlessly.
In most languages, you use a compiler or interpreter frequently to check your program's behavior. The Brainfuck language demands greater conceptual control; if you need a compiler to tell you what your program does, you don't have a firm enough grasp of your program, and you probably need to stare at it some more--at least if you want to have a clear enough image of the conceptual halo of similar programs to be good at golf. With practice, you'll be producing a dozen versions of your program before you try running one, and by that point you'll be 95% sure that your shortest one will run correctly.
Good luck! Very few people bother to write Brainfuck concisely, but I think that's the only way the language can possibly justify continuing attention--as a stunningly obscure art form.