Problem:
MathJax.Hub.Config({
tex2jax: { inlineMath: [['\\(','\\)']] }
});

Problem H: Brainf*ck

BさんはBrainf*ckが大好きで、学校で出された課題も全てBrainf*ckを使って提出している。
最近そんなBさんに洗脳され、先生が課題を解く言語をBrainf*ckに限定してしまった。

このままでは皆が単位を落としてしまう。
あなたは、Brainf*ckプログラムを生成するプログラムを作ることで、皆の単位を救い出す手伝いをすることにした。

もちろん、Brainf*ckプログラムを生成するプログラムはBrainf*ckで記述する必要はない。

問題

指定された文字列\( s \)を出力するBrainf*ckプログラムを生成せよ。

Brainf*ck言語仕様

ジャッジで用いるBrainf*ckの言語仕様を記す。

Brainf*ckプログラムは文字列で記述される。
プログラム文字列は角括弧([および])の対応が取れている必要があるが、それ以外の制限はない。

Brainf*ckプログラムが実行される時、バイト配列とその要素を指し示すポインターを持つ。バイト配列は無限の大きさを持ち、8bit非負整数の情報を保持することができる。
これをC言語で表すと次のようになる。

unsigned char memory[100000]; // バイト配列（実際にはもっと広大な領域を確保する）
unsigned char *ptr = memory; // バイト配列の要素を指し示すポインター

Brainf*ckでは1つの命令は1文字で表され、命令には以下の7種類がある。

.brainfuck {
border-collapse: collapse;
border: solid 1px #999;
font-size: 100%;
}

.brainfuck th, .brainfuck td{
border: solid 1px #999;
padding: 4px 6px;
}

.brainfuck th {
background: #E6E6E6;
text-align: center;
color: #666;
}

文字

意味

C言語での記述法

+

ポインターが示すバイト配列の要素の値を1増やす。値が255の時は0になる。

(*ptr)++;

-

ポインターが示すバイト配列の要素の値を1減らす。値が0の時は255になる。

(*ptr)--;

>

ポインターが示すバイト配列の要素の位置を正に1ずらす。

ptr++;

<

ポインターが示すバイト配列の要素の位置を負に1ずらす。

ptr--;

[

ポインターが示すバイト配列の要素の値が0ならば、対応する]に飛ぶ。そうでなければ次の命令に進む。

while(*ptr) {

]

ポインターが示すバイト配列の要素の値が0ならば、対応する[に飛ぶ。そうでなければ次の命令に進む。

} do while(*ptr);

.

ポインターが示すバイト配列の要素の値をASCIIコードと見なし、文字を出力する。

putchar(*ptr);

命令は先頭から順に実行され、命令を表す文字ではない文字はコメントとして無視される。

以上のBrainf*ckの仕様はおおよそ一般に使われているBrainf*ckと同様なものなので、http://ja.wikipedia.org/wiki/Brainfuckなどを参考にすることができる。ただし、ジャッジに用いるBrainf*ckは、一文字入力命令を使用することはできないので注意すること。

入力

1行に1000文字以内の文字列\( s \)が与えられる。

出力

Brainf*ckコードを20000文字以内で出力せよ。実行結果が\( s
\)に一致した任意のプログラムがAcceptされる。

制約

\( 1 \leq |s| \leq 1000 \)

\( s \)はASCII文字列

\( s \)にはASCIIコード33〜126の文字しか含まれない（記号、英字、数字のみで空白や制御文字を含まない）

出力したプログラムの長さは空白、改行、コメントを含めて\( 20000 \)文字までを許容する

命令は\( 10^7 \)回実行されるとストップする

Brainf*ckプログラムは最後に改行を出力してはならない

入出力例

入力1

ABC

出力1

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

入力2

HelloWorld!!

出力2

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

入力に空白が含まれることはない。

入力3

!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~

出力3

+++++++++++++++++++++++++++++++++.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+
+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+
.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.

このケースは33から126のASCIIコードを順番に並べたものである。

Solution in JavaScript (judge verdict: Accepted)

/**
 * Created by hiroqn on 13/10/06.
 */
var fs = require('fs'),
    length = fs.fstatSync(process.stdin.fd).size,
    buffer = new Buffer(length),
    bytesRead = fs.readSync(process.stdin.fd, buffer, 0, length, 0),
    input = buffer.toString('utf8', 0, bytesRead).split('\n');
main();
function seqStr(n, c) {
  var j, res = '';
  for (j = n; j > 0; j--) {
    res += c;
  }
  return res;
}

function main() {
  var str = input[0],
      len = str.length,
      ans = '>++++++[<+++++>-]<[>+>+>+>++>++>++>+++>+++>+++>++++<<<<<<<<<<-]>',
      i, j, diff, sqr, sqr2,
      pmchar = '',
      prevList = [30, 30, 30, 60, 60, 60, 90, 90, 90, 120],
      pointer = 0,
      pointer2,
      N = 9,
      charCode;
  for (i = 0; i < len; i++) {
    charCode = str.charCodeAt(i);
    pointer2 = ~~((charCode - 33) / 11);
//    console.log(charCode,pointer2)
    ans += seqStr(Math.abs(pointer - pointer2), pointer < pointer2 ? '>' : '<');
    diff = charCode - prevList[pointer2];
    pmchar = diff > 0 ? '+' : '-';
    diff = Math.abs(diff);
//    console.log(prevList,diff,pointer2)
    ans += seqStr(diff, pmchar);
    prevList[pointer2] = charCode;
    ans += '.';
    pointer = pointer2;
  }
  console.log(ans);
}