LoginSignup
1
1

More than 5 years have passed since last update.

文字列(英語 + 記号)をBrainf*ckに変換

Last updated at Posted at 2016-12-01

先日Brainf*ckでうまる言語を作ってみたんですが、その逆版です!
同僚にテストツールで使えるのではと言われ、作ってみました!

文字が半角英数の判断

Text2Brainf*ck.java
private void splitString(String str) {
    for (int count = 0; count < str.length(); count++) {
        String s = str.substring(count, count + 1);
        byte[] b = s.getBytes();
        if (s.length() == b.length) {
            calcString(s);
        }
    }
}

Stringの長さ(length)と、Stringをbyteに変換した時の長さを比べて等しかったら、半角文字であるという感じにしてます

文字を10進数に変換

Text2Brainf*ck.java
int code = str.charAt(0);

これだけでできます

1つ前の文字との差分

これが大事でした
続けていくので、1つ前の文字の10進数からどれだけ進めて行くかを決めます

Text2Brainf*ck.java
private int text code = 0;
private int calcDiff(int code) {
    return (code - textcode);
}

引数のcodeに今の10進数、testcodeに1つ前の10進数文字を覚えておきます

差分をBrainf*ckに変換

ここまでは準備段階です
ここから出力文字の計算になります

Text2Brainf*ck.java
int diff = calcDiff(code);
if (diff != 0) {
    if (textcode != 0) {
        outputBf(Token.PREVIOUS.text);
    }
    int count = Math.abs(diff / 10;
    int remainder = Math.abs(diff % 10;
    outputTen(count, diff > 0);
    outputRemainder(remainder, diff > 0);
}
outputBf(Token.PUT.text);

先ほど計算したdiffを10の倍数と余りに分解していきます
outputBf()は、引数を出力するメソッドだと思ってください)

Text2Brainf*ck.java
private void outputTen(int count, boolean isInc) {
    for (int index = 0; index < count; index++) {
        outputBf(Token.INC.text);
    }
    outputBf(Token.LOOP.text);
    outputBf(Token.NEXT.text);
    for (int index = 0; index < 10; index++) {
        outputBf(isInc ? Token.INC.text : Token.DEC.text);
    }
    outputBf(Token.PREVIOUS.text);
    outputBf(Token.DEC.text);
    outputBf(Token.JUMP.text);
}

10の倍数を出力するメソッドになります

最初のfor文で何回ループするかを決めます
LOOPJUMPの間が10(マイナスするなら-10)を出力する形です

Text2Brainf*ck.java
private void outputRemainder(int remainder, boolean isInc) {
    outputBf(Token.NEXT.text);
    for (int index = 0; index < remainder; index++) {
        outputBf(isInc ? Token.INC.text : Token.DEC.text);
    }
}

diffを10で割った余りは最後にインクリメントしていきます(for文
引数のisIncで値を増やすか減らすかを区別しています

継承クラス

T2bf.java
class T2bf extends Text2Brainfuck {
    public static void main(String[] args) {
        T2bf tb = new T2bf(args[0]);
    }

    public T2bf(String arg) {
        super(arg);
    }
}

mainメソッドの引数で、読み込むファイル名を取得します

読み込むファイル

helloworld.tb
Hello, World!

無難ですがw

実行

$ javac T2bf.java; java T2bf helloworld.tb hello.tt
$ javac [実行するファイル名]; java [実行するクラス名] [読み込むファイル名] [書き込むファイル名]

となってます

結果

hello.tt
+++++++[>++++++++++<-]>++.
<++[>++++++++++<-]>+++++++++.
<[>++++++++++<-]>+++++++.
.
<[>++++++++++<-]>+++.
<++++++[>----------<-]>-------.
<+[>----------<-]>--.
<+++++[>++++++++++<-]>+++++.
<++[>++++++++++<-]>++++.
<[>++++++++++<-]>+++.
<[>----------<-]>------.
<[>----------<-]>--------.
<++++++[>----------<-]>-------.

(わかりやすく改行してみました)
こうみると、構成が全部おなじになっちゃってますねw

GitHubGist

追記

うまる言語で使用している処理だと、うまくこれをHello, World!にできませんでした....
(他の方の処理をお借りしましたら、きちんとHello, World!になりましたのでご安心ください)
うまる言語の中の処理を改良していきます...
-> 修正したので、うまるでもできるようになりました
-> 日本語だと出力でUTF-8に変換がうまくできなかったため、結果をファイルに書き込むように修正しました

参考

http://www.kmonos.net/alang/etc/brainfuck.php
http://d.hatena.ne.jp/kobapan/20081225/1230156733
http://www.eva.hi-ho.ne.jp/cgi-bin/user/zxcv/decodeUTF8.cgi

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1