[Question]
  [
One of easiest code written by a programming language is a program printing sequence of characters (ex. "Hello, world!"). However, [s](http://www.lscheffer.com/malbolge.shtml)[o](http://esolangs.org/wiki/Asdf)[m](http://esolangs.org/wiki/Polynomial)[e](http://esolangs.org/wiki/Funciton) [e](http://esolangs.org/wiki/Fugue)[s](http://esolangs.org/wiki/DNA-Sharp)[o](http://esolangs.org/wiki/NULL)[t](http://esolangs.org/wiki/Fractran%2B%2B)[e](http://www.bigzaphod.org/whirl/)[r](http://en.wikipedia.org/wiki/Shakespeare_%28programming_language%29)[i](http://www.dangermouse.net/esoteric/piet.html)[c](http://compsoc.dur.ac.uk/whitespace/) programming languages like [Brainfuck](http://en.wikipedia.org/wiki/Brainfuck), even this simplest code is quite annoying to write.
Your task is to write a program (don't have to written in brainfuck), which prints a (minimum-length) Brainfuck program printing the given text.
## Input
A sequence of characters (between `1` and `255`) is given by any format (variable, argument, stdin, file, ...).
## Output
Output is a valid (no non-matching `[` and `]`) brainfuck code (assume unsigned 8-bit wrapping cell and unlimited number of cells to left and right) printing exact string that was given as input.
For example, one possible output for input `A` is `++++++++[<++++++++>-]<+.`.
Your program shouldn't take long time (`>2m`) to run.
The BF program shouldn't take long time (`>10s`) to run.
## Scoring
*(Notice : current scoring method may change, since it is not easy to calculate...)*
The length of program (generating BF code) itself *doesn't* matter. However, hard-coding BF codes in the program code is not OK. Only acceptable range (ex. a BF code printing a single character `0x01` : `+.`) of BF codes might be hard-coded.
The score is sum of length of BF codes printing these strings.
* A string `Hello, world!` appended with a single `0x0A` (`\n`) (i.e. the "Hello, world!" program)
* Single character from `0x01` ~ `0xFF`
	+ Sum of length of these 255 BF codes are multiplied by `1/16`, rounded, and added to the score.
* List of first 16 strings, generated by splitting [a random sequence of bytes generated on 11-11-11](http://www.random.org/files/) by `0x00`, removing all zero-length strings.
* [Lenna.png](http://en.wikipedia.org/wiki/File%3aLenna.png), removing all `0x00`s.
* Lyrics of the song [99 bottles of beer](http://99-bottles-of-beer.net/lyrics.html), starting with `99 bottles~`, newlines are `0x0A`, paragraphs are separated by two `0x0A`s, and no newline character at the end.
* Other strings you may provide.
Your program may include calculating the score of itself.
Of-course, lowest-score code will be the winner.
  
[Answer]
In Java, computes a short BF snippet which can convert any number to any other number. Each output byte is generated by either transforming the last output byte or a fresh 0 on the tape.
The snippets are generated in three ways. First by simple repetitions of `+` and `-` (e.g. `++++` converts 7 to 11), by combining known snippets (e.g. if A converts 5 to 50 and B converts 50 to 37, then AB converts 5 to 37) and simple multiplications (e.g. `[--->+++++<]` multiplies the current number by 5/3). The simple multiplications take advantage of wraparound to generate unusual results (e.g. `--[------->++<]>` generates 36 from 0, where the loop executes 146 times, with a total of 4 descending and 1 ascending wraparounds).
I'm too lazy to compute my score, but it uses about 12.3 BF operations per byte on `Lenna.png`.
```
import java.io.*;
class shortbf {
    static String repeat(String s, int n) {
        StringBuilder b = new StringBuilder();
        for (int i = 0; i < n; i++) b.append(s);
        return b.toString();
    }
    // G[x][y]: BF code that transforms x to y.                                                     
    static String[][] G = new String[256][256];
    static {
        // initial state for G[x][y]: go from x to y using +s or -s.                                
        for (int x = 0; x < 256; x++) {
            for (int y = 0; y < 256; y++) {
                int delta = y - x;
                if (delta > 128) delta -= 256;
                if (delta < -128) delta += 256;
                if (delta >= 0) {
                    G[x][y] = repeat("+", delta);
                } else {
                    G[x][y] = repeat("-", -delta);
                }
            }
        }
        // keep applying rules until we can't find any more shortenings                             
        boolean iter = true;
        while (iter) {
            iter = false;
            // multiplication by n/d                                                                
            for (int x = 0; x < 256; x++) {
                for (int n = 1; n < 40; n++) {
                    for (int d = 1; d < 40; d++) {
                        int j = x;
                        int y = 0;
                        for (int i = 0; i < 256; i++) {
                            if (j == 0) break;
                            j = (j - d + 256) & 255;
                            y = (y + n) & 255;
                        }
                        if (j == 0) {
                            String s = "[" + repeat("-", d) + ">" + repeat("+", n) + "<]>";
                            if (s.length() < G[x][y].length()) {
                                G[x][y] = s;
                                iter = true;
                            }
                        }
                        j = x;
                        y = 0;
                        for (int i = 0; i < 256; i++) {
                            if (j == 0) break;
                            j = (j + d) & 255;
                            y = (y - n + 256) & 255;
                        }
                        if (j == 0) {
                            String s = "[" + repeat("+", d) + ">" + repeat("-", n) + "<]>";
                            if (s.length() < G[x][y].length()) {
                                G[x][y] = s;
                                iter = true;
                            }
                        }
                    }
                }
            }
            // combine number schemes                                                               
            for (int x = 0; x < 256; x++) {
                for (int y = 0; y < 256; y++) {
                    for (int z = 0; z < 256; z++) {
                        if (G[x][z].length() + G[z][y].length() < G[x][y].length()) {
                            G[x][y] = G[x][z] + G[z][y];
                            iter = true;
                        }
                    }
                }
            }
        }
    }
    static void generate(String s) {
        char lastc = 0;
        for (char c : s.toCharArray()) {
            String a = G[lastc][c];
            String b = G[0][c];
            if (a.length() <= b.length()) {
                System.out.print(a);
            } else {
                System.out.print(">" + b);
            }
            System.out.print(".");
            lastc = c;
        }
        System.out.println();
    }
    static void genFile(String file) throws IOException {
        File f = new File(file);
        int len = (int)f.length();
        byte[] b = new byte[len];
        InputStream i = new FileInputStream(f);
        StringBuilder s = new StringBuilder();
        while (true) {
            int v = i.read();
            if (v < 0) break;
            if (v == 0) continue; // no zeros                                                       
            s.append((char)v);
        }
        generate(s.toString());
    }
    public static void main(String[] args) throws IOException {
        genFile(args[0]);
    }
}
```
[Answer]
Well here's about the worst possible solution, although a rather nice looking one in Brainfuck itself:
```
++++++[>+++++++>+++++++++++++++>+++++++<<<-]>++++>+>+>,[[<.>-]<<<.>.>++.--<++.-->>,]
```
Score is probably the worst we are likely to see without intentionally making it bad.
Working on calculating actual score.
[Answer]
# Python 3.x
Well, I'm not going to win any prizes for the shortest output code but maybe for the program to generate the code...
```
x=input();o=''
for i in x:
 a=ord(i)
 o+="+"*a+".[-]"
print(o)
```
'Hello, World!\n':
```
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.[-]++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++.[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++.[-]+++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+.[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++.[-]++++++++++++++++++++++++++++++++++++++++
++++.[-]++++++++++++++++++++++++++++++++.[-]++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++.[-]+++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++.[-]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++.[-]++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.[-]
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++.[-]+++++++++++++++++++++++++++++++++.[-]++++++++++.[-]
```
[Answer]
I'm not sure how good it is, but I had fun writing this. (In Clojure...)
```
(ns bf.core)
(def input "Hello world!")
(defn abs [x] (if (and (< x 0) (= (type x) (type 1))) (* x -1) x)) 
(defn sqrt? [x y] (if (= (* y y) x) true false) )
(defn sqrt [x] (for [y (range x) :when (sqrt? x y)] y) )
(defn broot [x]
;  Run this using trampoline, e.g., (trampoline broot 143)
  (if (< x 2) nil)
  (let [y (sqrt x)]
    (if (not= (seq y) nil)
      (first y)
      (broot (dec x) )
      )
    )
  )
(defn factor [x]
  (if (<= x 2) x)
  (for [y (range (- x 1) 1 -1)
        :when (= ( type (/ x y) ) (type 1) )
        ]
    y)
  )
(defn smallest_factors [x]
  (let [ facts (factor x) ]
  (if (= (count facts) 2) facts)
  (if (< (count facts) 2) (flatten [facts facts])
    (let [ y (/ (dec (count facts) ) 2)
          yy (nth facts y)
          z (inc y)
          zz (nth facts z)
          ]
      (if (= (* yy zz) x ) [yy zz] [yy yy])
      )
    )
    )
  )
(defn smallestloop [x]
  (let [ facts (smallest_factors x)
        fact (apply + facts)
        sq (trampoline broot x)
        C (- x (* sq sq) )]
    (if (and (< fact (+ (* 2 sq) C) ) (not= fact 0))
      facts
      [sq sq C])
    )
  )
(def lastx nil)
;Finally!
(defn buildloop [x]
  (if (nil? lastx)
     (let [pluses (smallestloop x)]
       (apply str
              (apply str (repeat (first pluses) \+))
              "[>"
              (apply str (repeat (second pluses) \+))
              "<-]>"
              (if (and (= (count pluses) 3) (> (last pluses) 0))
                (apply str(repeat (last pluses) \+))
              )
              "."
              )
    )
    (let [diff (abs (- x lastx) )]
      (if (< diff 10)
        (if (> x lastx)
          (apply str
               (apply str (repeat diff \+))
               "."
                 )
          (apply str
                 (apply str (repeat diff \-))
                 "."
                 )
          )
        (let [signs (smallestloop diff)]
          (apply str
             "<"
             (apply str (repeat (first signs) \+))
             "[>"
             (if (> x lastx)
               (apply str (repeat (second signs) \+))
               (apply str (repeat (second signs) \-))
             )
             "<-]>"
             (if (and (= (count signs) 3) (> (last signs) 0))
               (if (> x lastx)
                 (apply str(repeat (last signs) \+))
                 (apply str(repeat (last signs) \-))
               )
             )
             "."
           )
         )
        )
      )
    )
  )
(for [x (seq input)
  :let [y (buildloop (int x))]
      ]
  (do 
   (def lastx (int x))
   y
   )
  )
```
There are probably more efficient solutions, and more elegant ones, but this follows my thought pattern somewhat linearly, so it was easiest.
[Answer]
**Score: ~~4787486~~ ~~4143940~~ 4086426** (without randomly generated data)
(4085639 of that are from Lenna.png. That's 99.98%)
I don't get the part with the random data. Don't I need an account which I have to pay for to get the data?
Pretty naive. Here's the generated code for "1Aa" (49, 65, 97) with a little documentation:
```
                   // field 0 and 1 are loop counters.
                   // The fields 2, 3 and 4 are for "1", "A" and "a"
++++++++++[        // do 10 times
    >
    ++++++++++[    // do 10 times
        >          // "1" (49) is below 50 so we don't need to do anything here
        >+         // When the loops are done, this part will have increased the value of field 3 by 100 (10 * 10 * 1)
        >+         // same as above
        <<<-       // decrease inner loop counter
    ]
    >+++++         // this will add 50 (10 * 5) to field 2, for a total of 50
    >----          // subtract 40 from field 3, total of 60
    >              // Nothing done, value stays at 100
    <<<<-          // decrease outer loop counter
]
>>-.               // subtract 1 from field 2, total now: 49, the value for "1"
>+++++.            // add 5 to field 3, makes a total of 65, the value for "A"
>---.              // subtract 3 from field 4, total of 97, the value for "a"
```
The Java code is a bit ugly but it works. The generated instruction per input byte ratio is probably better the higher the average byte value is.
If you want to run it, you have to put Lenna.png in the same directory as the .class file. It prints the score to console and writes the generated BF code into a file called "output.txt".
```
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
public class BrainFuckGenerator {
    public static CharSequence generate(byte[] bytes) {
        final StringBuilder brainfuckBuilder = new StringBuilder();
        for(int j = 0; j<10; j++)
                brainfuckBuilder.append("+");
        brainfuckBuilder.append("[>");
        for(int j = 0; j<10; j++)
            brainfuckBuilder.append("+");
        brainfuckBuilder.append("[");
        final StringBuilder singles = new StringBuilder();
        final StringBuilder tens = new StringBuilder();
        final StringBuilder goBack = new StringBuilder();
        for(byte b: bytes) {
            brainfuckBuilder.append(">");
            for(int j=0; j<(b/100); j++) {
                brainfuckBuilder.append("+");
            }
            tens.append(">");
            if((b - (b/100)*100)/10 <= 5) {
                for(int j=0; j<(b - (b/100)*100)/10; j++) {
                    tens.append("+");
                }
            } else {
                brainfuckBuilder.append("+");
                for(int j=0; j<10 - (b - (b/100)*100)/10; j++) {
                    tens.append("-");
                }
            }
            singles.append(">");
            if(b%10 <= 5) {
                for(int j=0; j<b%10; j++) {
                    singles.append("+");
                }
            } else {
                tens.append("+");
                for(int j=0; j<10 - (b%10); j++) {
                    singles.append("-");
                }
            }
            singles.append(".");
            goBack.append("<");
        }
        goBack.append("-");
        brainfuckBuilder
            .append(goBack)
            .append("]")
            .append(tens)
            .append("<")
            .append(goBack)
            .append("]>")
            .append(singles);
        return brainfuckBuilder;
    }
    public static void main(String[] args) {
        /* Hello, World! */
        int score = score("Hello, world!"+((char)0xA));
        /* 255 single chars */
        int charscore = 0;
        for(char c=1; c<=0xff; c++)
            charscore += score(String.valueOf(c));
        score += Math.round(((double)charscore)/16);
        /* Lenna */
        final File lenna = new File("Res/Lenna.png");
        final byte[] data = new byte[(int)lenna.length()];
        int size = 0;
        try(FileInputStream input = new FileInputStream(lenna)) {
            int i, skipped=0;
            while((i = input.read()) != -1)
                if(i == 0)
                    skipped++;
                else
                    data[size++ - skipped] = (byte)(i&0xff);
        } catch (IOException e) {
            e.printStackTrace();
        }
        score += score(Arrays.copyOf(data, size), "Lenna");
        /* 99 Bottles */
        final StringBuilder bottleBuilder = new StringBuilder();
        for(int i=99; i>2; i--) {
            bottleBuilder
                .append(i)
                .append(" bottles of beer on the wall, ")
                .append(i)
                .append(" bottles of beer.")
                .append((char) 0xa)
                .append("Take one down and pass it around, ")
                .append(i-1)
                .append(" bottles of beer on the wall.")
                .append((char) 0xa)
                .append((char) 0xa);
        }
        bottleBuilder
            .append("2 bottles of beer on the wall, 2 bottles of beer.")
            .append((char) 0xa)
            .append("Take one down and pass it around, 1 bottle of beer on the wall.")
            .append((char) 0xa)
            .append((char) 0xa)
            .append("No more bottles of beer on the wall, no more bottles of beer. ")
            .append((char) 0xa)
            .append("Go to the store and buy some more, 99 bottles of beer on the wall.");
        score(bottleBuilder.toString(), "99 Bottles");
        System.out.println("Total score: "+score);
    }
    private static int score(String s) {
        return score(s, null);
    }
    private static int score(String s, String description) {
        final CharSequence bf = generate(s.getBytes());
        try(FileWriter writer = new FileWriter("Res/output.txt", true)) {
            writer.write((description == null ? s : description));
            writer.write(NL);
            writer.write("Code:");
            writer.write(NL);
            writer.write(bf.toString());
            writer.write(NL+NL);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bf.length();
    }
    private static int score(byte[] bytes, String description) {
        final CharSequence bf = generate(bytes);
        try(FileWriter writer = new FileWriter("Res/output.txt", true)) {
            if(description != null) {
                writer.write(description);
                writer.write(NL);
            }
            writer.write("Code:");
            writer.write(NL);
            writer.write(bf.toString());
            writer.write(NL+NL);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bf.length();
    }
    private static final String NL = System.getProperty("line.separator");
}
```
~~I'm going to make some small improvements but probably not much.~~ Done.
[Answer]
# BrainF\*\*k
I'm a pretty bad BF programmer, so this answer is probably pretty inefficient. I'm unsure of the score, but it should perform slightly better than the existing answer on your average text. Rather than zeroing the cell out after every character, this one will "adjust" to a new character with subtraction if the previous character given is larger.
```
>>++++++[-<+++++++>]<+>>+++++[-<+++++++++>]>+++++[-<+++++++++>]<+>>,[-<+>>>>>>+<<<<<]<[-<<<.>>>]<.>>+>,[[-<<+>>>+>>+<<<]>>>>[-<<+>>]<[->+<]<<[->-[>]<<]<[->->[-<<<<<<.>>>>>>]<<]>+[-<<->>>[-<<<<<<.>>>>>>]<]<<<[>]<<.>[-]>+>,]
```
(Note, this is code I wrote a long time ago, and have repurposed for this competition. I sincerely hope I've done the conversion correctly, but if it fails for any input let me know.)
A version showing the state of the tape throughout the code:
```
>>++++++[-<+++++++>]<+>             [0 '+' 0]
                                           ^
>+++++[-<+++++++++>]                [0 '+' '-' 0]
                                               ^
>+++++[-<+++++++++>]<+>             [0 '+' '-' '.' 0]
                                                   ^
>,[-<+>>>>>>+<<<<<]                 [0 '+' '-' '.' a 0 0 0 0 0 a]
                                                     ^
<[-<<<.>>>]<.>>+>                   [0 '+' '-' '.' 0 1 0 0 0 0 a]
                                                       ^
,[[-<<+>>>+>>+<<<]                  [0 '+' '-' '.' b 1 0 b 0 b a]
                                    [b is not 0]       ^
>>>>[-<<+>>]<[->+<]                 [0 '+' '-' '.' b 1 0 b a 0 b]
                                                             ^    
<<[->-[>]<<]
<[->->[-<<<<<<.>>>>>>]<<]           
>+[-<<->>>[-<<<<<<.>>>>>>]<]        [0 '+' '-' '.' b 0 0 0 0 0 b]
                                                       ^|^
                                    [OUTPUT ONE CHARACTER BY THIS POINT]
<<<[>]<<.>[-]>                      [0 '+' '-' '.' 0 0 0 0 0 0 b]
                                                     ^
+>,]                                [End when b == 0]
                                    [GOAL: '+' '-' '.' b 1 0 b a 0 a]
```
Generated code for `Hello, World!`:
```
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.+++++++++++++++++++++++++++++.+++++++..+++.-------------------------------------------------------------------.------------.+++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++++++++++++++.+++.------.--------.-------------------------------------------------------------------.
```
*This is my first answer on CG.SE! If I've screwed something up, let me know!*
[Answer]
## ><>
```
i:&v
.21<>i:0(?;:&:@(4g62p$:&-01-$:@0(?*l2=?~02.
>:?!v"+"o1-
"."~<.15o
+-
```
I wrote this in response to a question marked for a duplicate, and even though this isn't the greatest golf (for this specific question, at least) I figured it'd be kind of a waste if I didn't share it in all of its disgustingly gibberish-y glory. Really, I'm half-surprised it even works. I'll take any suggestions to golf it down since that was my main goal in its creation.
As a side note, in the second line the beginning three characters `.21` could be replaced with `v` followed by two spaces if that makes it any easier to read. I don't like to see spaces in my ><> programs because that means there's wasted space (literally). It also is a remnant from one of many prototypes.
The way it functions is really simple, and quite frankly I'd have a difficult time thinking of a way to implement another algorithm. It prints however many "+"s need to be printed for the first character, and then prints more "+"s or "-"s as needed for each additional character, separating each section with periods. What I find cool about the program is that it modifies its own source code so that it prints "+" or "-" (it replaces the "+" on line 3 with the appropriate character after determining whether the current character is greater than or less than the previous one).
Output for `Hello, World!`:
```
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.+++++++++++++++++++++++++++++.+++++++..+++.-------------------------------------------------------------------.------------.+++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++++++++++++++.+++.------.--------.-------------------------------------------------------------------.
```
I might score this the way it was intended to be scored, but I'm almost positive I'd lose and I don't entirely know how to read something like lenna.png in ><>.
If this answer interests you and you'd like an explanation, by all means ask, but for now I'll leave it without one just because of how twisty and turny it is.
EDIT 1: It's been a while but I was able to golf off 2 bytes with an almost complete overhaul of the way the program decides whether to print a plus or a minus. It's a somewhat disappointing return for a large overhaul but at least it works.
[Answer]
# Kotlin
First I must admit that about half of this is shamelessly stolen from Keith Randel's answer. I literally copied and pasted his code for finding multiplications into mine. It is very well done. I have made 2 modifications to his code.
1. It is very easy to reverse the direction of any of the transitions Keith's code produces. All you have to do is replace `<` with `>` and `>` with `<`. Ex. `+[->++<]>` becomes `+[-<++>]<`. This means that equally, good code\* that only uses 2 cells can be produced.
2. The second thing I did was to add a hash. To add a hash the code simply includes a `>` after the `.`. Then for all subsequent characters, the program calculates if the code to move to the hash (such as `<<<.>>>`) is shorter than the regular code to produce this output. To find the locations for the hash the program loops through each character of the input and checks if hashing that character decreases the length of the program. It only hashes each type of character once which is slightly inefficient but is necessary to make the program not run like a snail.
Speaking of time complexity my program is quadratic time as opposed to Keith's which is linear. This is because the full code for any hash configuration has to be generated for each character. It is still possible to stop the algorithm early and get a better result than you started with as each cache only improves the score.
So how good does it do. Theoretically, it always does better than Keith's however, this isn't quite true. Keith's code can get to zero from any number simply by inserting a `>` but mine cannot because it would move too far from the hash. As a result, some of my transitions are slightly longer than Keith's meaning I actually achieve a lower score on `Lenna.png`. However since most of the transitions where starting with zero instead are very small or very large if you only include letters in the printable ASCII range 32 to 126 my program does beat Keith's. So although it can be worse my algorithm is better in practice. Lets look at some numbers.
### Numbers
```
Lenna.png (no 0s), 471470 characters
Keith:  5832730 bf chars,  12.37 bf chars / input
Me:    <5894582 bf chars, <12.5  bf chars / input
Keith + 0.13
```
```
Lenna.png (32 to 126), 174177 characters
Keith:  2022451 bf chars,  11.61 bf chars / input 
Me:    <1977716 bf chars,  11.25 bf chars / input
Me + 0.36
```
```
Hello, World!\n, 14 characters
Keith:      139 bf chars, 9.93 bf chars / input
Me:         139 bf chars, 9.93 bf chars / input
Even
```
```
I went to the store today, 25 characters
Keith:      265 bf chars, 10.6 bf chars / input
Me:         190 bf chars,  7.6 bf chars / input
Me + 3
```
```
447 characters of Lorem Ipsum
Keith:     4427 bf chars,  9.9 bf chars / input
Me:        3017 bf chars, 6.75 bf chars / input
Me + 3.15 
```
```
1001 random lowercase letters
Keith:     8035 bf chars, 8.03 bf chars / input
Me:        7028 bf chars, 7.02 bf chars / input
Me + 1.01
```
### Code
```
const val CELL_SIZE = 256
const val WRAPPING = true
enum class Direction {
    LEFT, RIGHT;
    fun opposite() = when (this) {
        LEFT -> RIGHT
        RIGHT -> LEFT
    }
}
data class Transition(
    val code: String,
    val startD: Direction,
    val endD: Direction,
) {
    fun plus(t: Transition) = if (endD == t.startD) {
        Transition(code + t.code, t.startD, t.endD)
    } else {
        val r = t.reverse()
        Transition(code + r.code, t.startD, r.endD)
    }
    fun reverse(): Transition {
        val newCode = code.replace(">", "|").replace("<", ">").replace("|", "<")
        return Transition(newCode, startD.opposite(), endD.opposite())
    }
}
var simpleTransitions = {
    val list = Array(CELL_SIZE) { start ->
        Array(CELL_SIZE) { end ->
            var delta = end - start
            if (WRAPPING) when {
                delta > CELL_SIZE / 2 -> delta -= CELL_SIZE
                delta < -CELL_SIZE / 2 -> delta += CELL_SIZE
            }
            val char = if (delta > 0) "+" else "-"
            Transition(char.repeat(abs(delta)), Direction.LEFT, Direction.LEFT)
        }
    }
    //check for multiplication
    for (x in 0..255) {
        for (n in 1..39) {
            for (d in 1..39) {
                var j = x
                var y = 0
                for (i in 0..255) {
                    if (j == 0) break
                    j = j - d + 256 and 255
                    y = y + n and 255
                }
                if (j == 0) {
                    val s = "[" + "-".repeat(d) + ">" + "+".repeat(n) + "<]>"
                    if (s.length < list[x][y].code.length) {
                        list[x][y] = Transition(s, Direction.LEFT, Direction.RIGHT)
                    }
                }
                j = x
                y = 0
                for (i in 0..255) {
                    if (j == 0) break
                    j = j + d and 255
                    y = y - n + 256 and 255
                }
                if (j == 0) {
                    val s = "[" + "+".repeat(d) + ">" + "-".repeat(n) + "<]>"
                    if (s.length < list[x][y].code.length) {
                        list[x][y] = Transition(s, Direction.LEFT, Direction.RIGHT)
                    }
                }
            }
        }
    }
    for (i in 0 until CELL_SIZE) {
        if (list[i][0].code.length > 3) list[i][0] = Transition("[-]", Direction.LEFT, Direction.LEFT)
    }
    var change = true
    while (change) {
        change = false
        for (i in 0 until CELL_SIZE) {
            for (j in 0 until CELL_SIZE) {
                for (k in 0 until CELL_SIZE) {
                    if (list[i][j].code.length + list[j][k].code.length < list[i][k].code.length) {
                        list[i][k] = list[i][j].plus(list[j][k])
                        change = true
                    }
                }
            }
        }
    }
    println("done")
    list
}()
fun generate(s: String, cells: Int): String {
    var caches: MutableList<Boolean> = MutableList(s.length) { false }
    var currentCost = generateFromCache(s, caches)
    val changes: MutableMap<Char, Int> = mutableMapOf()
    if (cells > 2) {
        for ((i, c) in s.withIndex()) {
            val newCaches = caches.mapIndexed { index, b -> if (s[index] == c) false else b }.toMutableList()
            var lowest: Char? = null
            if (newCaches.count { it } >= cells - 2) {
                lowest = changes.minByOrNull { it.value }!!.key
                newCaches[newCaches.withIndex().indexOfFirst { it.value && s[it.index] == lowest }] = false
            }
            newCaches[i] = true
            val newCost = generateFromCache(s, newCaches)
            if (newCost.length < currentCost.length) {
                println(newCost.length)
                changes[c] = currentCost.length - newCost.length
                currentCost = newCost
                caches = newCaches
                if (lowest != null) changes.remove(lowest)
            }
        }
    }
    return currentCost
}
```
[Answer]
my JavaScript solution it`s quick and dirty :)
output for `Hello World\n`
```
++++++++++[>+++++++>++++++++++>+++++++++++>+++>+++++++++>+<<<<<<-]>++.>+.>--..+++.>++.>---.<<.+++.------.<-.>>+.>>.
```
Source:
```
BfGen("Hello World!\n");
// ++++++++++[>+++++++>++++++++++>+++++++++++>+++>+++++++++>+<<<<<<-]>++.>+.>--..+++.>++.>---.<<.+++.------.<-.>>+.>>.
// Length of BF code: 115
// Score: 8.846153846153847
function BfGen(input) {
    function StringBuilder() {
        var sb = {};
        sb.value = '';
        sb.append = (txt) => sb.value += txt;
        return sb;
    }
    function closest (num, arr) {
        var arr2 = arr.map((n) => Math.abs(num-n))
        var min = Math.min.apply(null, arr2);
        return arr[arr2.indexOf(min)];
    }
    function buildBaseTable(arr) {
        var out = StringBuilder();
        out.append('+'.repeat(10));
        out.append('[')
        arr.forEach(function(cc) {
            out.append('>');
            out.append('+'.repeat(cc/10));    
        });
        out.append('<'.repeat(arr.length));
        out.append('-');
        out.append(']');
        return out.value;
    }
    var output = StringBuilder();
    var charArray = input.split('').map((c) =>c.charCodeAt(0));
    var baseTable = charArray.map((c) => Math.round(c/10) * 10).filter((i, p, s) => s.indexOf(i) === p);
    output.append(buildBaseTable(baseTable));
    var pos = -1;
    charArray.forEach(function (charCode) {
        var bestNum = closest(charCode, baseTable);
        var bestPos = baseTable.indexOf(bestNum);
        var moveChar = pos < bestPos? '>' : '<';
        output.append(moveChar.repeat(Math.abs(pos - bestPos)))
        pos = bestPos;
        var opChar = baseTable[pos] < charCode? '+': '-';
        output.append(opChar.repeat(Math.abs(baseTable[pos] - charCode)));
        output.append('.');
        baseTable[pos] = charCode;
    });
    console.log(output.value)
    console.log('Length of BF code: ' + output.value.length);
    console.log('Score: ' + output.value.length / input.length);
}
```
[Answer]
I built something in Java. Didn't calculate the score. Texts with 3 or less characters are encoded with a multiplication per letter e.g. "A" = `++++++++[>++++++++<-]>+.`. Texts with more than 3 characters are encoded with a calculated list which is split into 3 areas. The first area is x times 49, then plus x times 7 and finally plus x. For example "A" is 1\*49 + 2\*7 + 2
```
public class BFbuilder {
    public static void main(String[] args) {
        String text = "### INSERT TEXT HERE ###";
        if (text.length()<=3){
            String result = "";
            for (char c:text.toCharArray()) {
                result += ">";
                if (c<12) {
                    for (int i=0;i<c;i++) {
                        result += "+";
                    }
                    result += ".>";
                } else {
                    int root = (int) Math.sqrt(c);
                    for (int i = 0; i<root;i++) {
                        result += "+";
                    }
                    result += "[>";
                    int quotient = c/root;
                    for (int i = 0; i<quotient;i++) {
                        result += "+";
                    }
                    result += "<-]>";
                    int remainder = c - (root*quotient);
                    for (int i = 0; i<remainder;i++) {
                        result += "+";
                    }
                    result += ".";
                }
            }
            System.out.println(result.substring(1));
        } else {
            int[][] offsets = new int[3][text.length()];
            int counter = 0;
            String result = "---";
            for(char c:text.toCharArray()) {
                offsets[0][counter] = c/49;
                int temp = c%49;
                offsets[1][counter] = temp/7;
                offsets[2][counter] = temp%7;
                counter++;
            }
            for (int o:offsets[0]) {
                switch (o) {
                case 0: result+=">--";
                break;
                case 1: result+=">-";
                break;
                case 2: result+=">";
                break;
                case 3: result+=">+";
                break;
                case 4: result+=">++";
                break;
                case 5: result+=">+++";
                break;
                }
            }
            result += ">+[-[>+++++++<-]<+++]>----";
            for (int o:offsets[1]) {
                switch (o) {
                case 0: result+=">---";
                break;
                case 1: result+=">--";
                break;
                case 2: result+=">-";
                break;
                case 3: result+=">";
                break;
                case 4: result+=">+";
                break;
                case 5: result+=">++";
                break;
                case 6: result+=">+++";
                break;
                }
            }
            result += ">+[-[>+++++++<-]<++++]>----";
            for (int o:offsets[2]) {
                switch (o) {
                case 0: result+=">---";
                break;
                case 1: result+=">--";
                break;
                case 2: result+=">-";
                break;
                case 3: result+=">";
                break;
                case 4: result+=">+";
                break;
                case 5: result+=">++";
                break;
                case 6: result+=">+++";
                break;
                }
            }
            result += ">+[-<++++]>[.>]";
            System.out.println(result);
        }
    }
}
```
The provided String "### INSERT TEXT HERE ###" becomes
`--->-->-->-->-->->->->->->->-->->->->->-->->->->->-->-->-->-->+[-[>+++++++<-]<+++]>---->++>++>++>+>>+>+>->+>++>+>++>->++>++>+>>->+>->+>++>++>++>+[-[>+++++++<-]<++++]>---->--->--->--->+>>-->+++>+++>++>--->+>--->+++>+>--->+>->+++>++>+++>+>--->--->--->+[-<++++]>[.>]`
"Hello, World!" becomes
`--->->>>>>-->-->->>>>>-->+[-[>+++++++<-]<+++]>---->>--->-->-->-->+++>+>++>-->->-->--->+>+[-[>+++++++<-]<++++]>---->->>>>+++>->+>>+++>->>->++>+[-<++++]>[.>]`
[Answer]
# Python 3
```
print("".join("+"*ord(i)+".[-]"for i in input()))
```
This is essentially just an slightly improved version of icedvariables' answer.
(-1 Byte from Wheat Wizard, -5 from FatalError, -2 from jez)
]