Most efficient cubifier Cubically is too tedious to manually write any code in. Your challenge is to translate ASCII text into Cubically source code.

Cubically

This is just a quick run-down of Cubically; the repository has a more complete guide and details.

Cubically is an esolang I wrote a while ago, designed to be painful to use. It contains two pieces of memory, a 3x3x3 Rubik's Cube and a register called the "notepad".

Memory

The internal Rubik's Cube is initialized like this:

   000
   000          top face
   000
111222333444    left, front, right, and back faces, respectively
111222333444
111222333444
   555
   555          down face
   555


After performing a clockwise 90° turn on the right face, the memory cube would look like this:

   002
   002
   002
111225333044
111225333044
111225333044
   554
   554
   554


Commands

A non-integer character sets the default command. For each integer before the default command is set once again, the command is performed with that integer. For example, x524y312 would perform command x with 5, then with 2, then with 4, then perform command y with 3, then with 1, then with 2.

The integers that commands use represent face indexes. So x0 would perform x on the UP (0-indexed) face. x1 would perform x on the LEFT (1-indexed) face, and so on.

Performing any command with 6 will perform that command on the notepad value. Performing any command with any integer over 6 will result in an error.

Here are some example commands:


R1 - turn the RIGHT face clockwise 90° so the internal cube will look like the second example above
R11 - turn the RIGHT face clockwise 90° twice, identical to R2
+0 - add all values of the UP face to the notepad
+000 - add all values of the UP face to the notepad three times
@6 - print the nonexistent 6th-indexed face (memory) as a character
%4 - print the sum of all values on the BACK face as an integer


A complete list of commands and syntax is available at the repository.

Challenge

You will take ASCII text as input and print a Cubically program as output.

Examples (stolen from here and here):

Input -&gt; Output
Hello, World! -&gt; +53@6+1F2L2+0@6L2F2U3R3F1L1+2@66L3F3R1U1B3+0@6:4U1R1+00@6-000@6*0-4+000@6-00@6+2-000000@6-5+4000@6-00@6/0+00@6:0+0/0+00@6
1$2$3$4$5$6$7$8$9$10$ -&gt; B1+2/2%6@4+00/0%6@4+00/1%6@4+21/1%6@4+30/0%6@4+22/1%6@4+22/1%6@4+40/1%6@4+52/1%6@4+42/1%6@4


Rules


Your program may not contain a dictionary containing the translations for the 100 testcases.
Your program must finish in less than 180 seconds (no brute-force programs that take weeks).
Your program must output valid Cubically code that finishes in less than 180 seconds.
Your program will take input via standard input, unless you want to mess with the test driver.
Your program must output Cubically code that produces nothing but your program's input when run. ಠ_ಠ


Scoring

You will test your program with 100 pseudorandom strings of pseudorandom length. (A bash script is provided that will do this for you.) Here is how you will score:


Let the length of the output program be o.
Let the length of the input string be l.
Let a variable r be the result of o/l.
Find the average of all r: (r1 + r2 + r... + r100) / 100.


Test with this script. You'll have to modify it as instructed. Note that the program does not check whether the output is valid Cubically code.
If you can't get the script working, I can help. Ping me in the Cubically chat room.
Lua, Score: 85.91 13.50 13.20 12.70 9.41 9.32 9.83 9.66 9.12 9.06 8.03 (Average)

-- Get input
local inp = io.read("*a")

local out = ""
local faces = { [5] = 45, [4] = 36, [3] = 27, [2] = 18, [1] = 9 }
local lastChar = nil

-- Mode the program is in
-- 2 = not set (needs :), 1 = just set (needs +), 0 = normal
local mode = 1;
for i = 1, inp:len() do
  -- Character value at current position
  local c = string.byte(inp, i)

  if c == lastChar then
    -- Repeat character
    out = out .. "6"
  elseif c % 9 == 0 and c &lt;= 45 then
    if #out == 0 then
      out = out .. "@"
    end
    out = out .. (c / 9)
  else
    local c2 = c

    -- Handle if difference from lastChar is divisible by 9
    if lastChar and (c - lastChar) % 9 == 0 then
      local difference = c - lastChar
      if difference &gt; 0 then
        out = out .. "+"
      else
        out = out .. "-"
        difference = difference * -1
      end

      for index = 5, 1, -1 do
        local face = faces[index]
        while difference &gt;= face do
          difference = difference - face
          out = out .. index
        end
      end
      c = 0
    end

    -- Handle anything not divisible by 9
    local extra = c % 9
    if extra &gt; 0 then
      -- Try to optimize by dividing by 9, if possible
      if lastChar and math.floor(lastChar / 9) == extra then
        out = out .. "/1"
        mode = 1
        extra = 0
      else
        while extra &gt; 0 do
          local n = extra &gt; 5 and 5 or extra

          if mode == 2 then
            out = out .. ":"
            mode = 1
          elseif mode == 1 then
            out = out .. "+"
            mode = 0
          end
          out = out .. n
          extra = extra - n
        end
        out = out .. "/1"
        mode = 1
      end

      c = c - (c % 9)
    end

    -- Handle anything divisible by 9
    for index = 5, 1, -1 do
      local face = faces[index]
      while c &gt;= face do
        if mode == 2 then
          out = out .. ":"
          mode = 1
        elseif mode == 1 then
          out = out .. "+"
          mode = 0
        end
        c = c - face
        out = out .. index
      end
    end

    out = out .. "@6"
    lastChar = c2
  end

  mode = 2
end
print(out)


Try it online!

Okay, I don't think I can optimize this anymore.

This version iterates through each character, adding c % 9 (where c is the character's decimal value) by doing :5+2/1, then adds the parts divisible by 9 by adding that face's value. For example: :2/1+551@ to print "e", where :2/1 adds 2, +551 adds 99 (9 * (5 + 5 + 1), or 9 * 11), and @ prints the output. Input is read with io.read().

Optimizations include directly adding/subtracting after printing if the difference between characters is a multiple of 9, dividing the current value if possible rather than setting c % 9 from scratch, and repeating characters by printing the current value again rather than recalculating it. Additionally, I've implemented Kamil's method of instantly printing any face that already contains the target value, and MD XF's suggestion to not use : at the beginning, but instead just start with a +.