PKU JudgeOnlineのProblem 1000をBrainf*ckで解いてみた

解いた問題

Problem 1000: A + B Problem
http://poj.org/problem?id=1000

問題説明

a + bを計算せよ.

Input

二つの整数a,b (0 <= a, b <= 10).

Output

a + bの計算結果を出力せよ.

Sample Input (stdin)
1 2
Sample Output (stdout)
3

解答

PKUにはCのコードがsubmitできるので,CでBrainf*ckのインタプリタを書いてBrainf*ckでa + bを計算させた.

#include <stdio.h>
#include <string.h>

void brainfuck(const char *src) {
  int pc = 0;
  int pc_fin = strlen(src);
  int mem[128] = {0};
  int *ptr = mem;

  while (pc < pc_fin) {
    switch (src[pc]) {
    case '>':
      ++ptr;
      break;
    case '<':
      --ptr;
      break;
    case '+':
      *ptr = (*ptr + 1) % 256;
      break;
    case '-':
      *ptr = (*ptr + 255) % 256;
      break;
    case '.':
      putchar(*ptr);
      break;
    case ',':
      *ptr = getchar();
      if (*ptr == EOF) { *ptr = 0; }
      break;
    case '[':
      if (*ptr == 0) {
        int count = 1;
        ++pc;
        while (count > 0) {
          if (src[pc] == '[') { ++count; }
          if (src[pc] == ']') { --count; }
          ++pc;
        }
        --pc;
      }
      break;
    case ']':
      if (*ptr != 0) {
        int count = 1;
        --pc;
        while (count > 0) {
          if (src[pc] == '[') { --count; }
          if (src[pc] == ']') { ++count; }
          --pc;
        }
        ++pc;
      }
      break;
    }
    ++pc;
  }
}

int main() {
  brainfuck(
    ">,>++++++[-<-------->],>++++[-<-------->]<[<+++++++++>,[-]]"
    ",>++++++[-<-------->],----------[<+++++++++>[-]]<[-<+>]<>++"
    "++++++++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>>>[>++++++[-<++++++"
    "++>]<.[-]]++++++[-<++++++++>]<.>++++++++++."
  );

  return 0;
}

<(^o^)>

Brainf*ckのコード

処理の内訳は以下の通り.

// aを標準入力から受けとり,ASCIIコードから数値に変換する
">,>++++++[-<-------->],>++++[-<-------->]<[<+++++++++>,[-]]"
// bを標準入力から受けとり,ASCIIコードから数値に変換する
",>++++++[-<-------->],----------[<+++++++++>[-]]" 
// a + bを計算する
"<[-<+>]<"
// 数値の10を用意する
">++++++++++<"
// (a + b) / 10 と (a + b) % 10を計算する
"[->-[>+>>]>[+[-<+>]>+>>]<<<<<]"
// a + bが10以上ならば10の位を出力する
">>>[>++++++[-<++++++++>]<.[-]]"
// a + bの1の位を出力する
"++++++[-<++++++++>]<."
// \nを出力する
">++++++++++."

以下の仮定を基にしてコードを書いているのでかなり適当.

  • aの後にスペースがひとつだけ来る
  • bの後に\nが来る
  • 0 <= a, b <= 10なので,入力値が2桁の時は必ず10

感想

1から書くのは割とつらかった.Brainf*ckライブラリの必要性を感じた.