開発合宿してきます

明日から熱海の旅館で開発合宿をやってきます.2泊3日.温泉を楽しみながらひたすらコードを書くだけの合宿です.

参加者は8人.

私は主にうちのbotのソースを一新する作業をやります.できる限りRSpecでテストを書きながら開発していく予定です.

みんなで集まってわいわい議論しながら開発するのは久し振りなので超楽しみ.

ぱらぽぺった ろっぷんぬいぐるみ 〜登場編〜

ロップイヤー(垂れた耳が特徴のウサギの品種)のキャラクター「ろっぷん」のぬいぐるみ.かわいい.

ロップイヤーなだけあって耳が長い.耳先がふにふにしてて触り心地がいいのだけど,割と重くなってるのでぶんぶん振り回すとやばい.

次に酔っ払った時は是非このぬいぐるみを振り回s(ry

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ライブラリの必要性を感じた.

転移学習とか統計的機械翻訳とか

読みたい論文,読みたい本が溜まってきた.ううう.とりあえず興味があるものの一部を列挙してみる.

論文

最低限読んでおきたい論文
  • Sinno Jialin Pan and Qiang Yang. A Survey on Transfer Learning. IEEE Transactions on Knowledge and Data Engineering (2009)
    • 転移学習のサーベイ論文.
  • Kevin Knight. A Statistical MT Tutorial Workbook. Prepared for the 1999 JHU Summer Workshop (1999)
    • 統計的機械翻訳の基礎的なことがチュートリアル形式で書かれている.
興味がある論文

欲しい.

Statistical Machine Translation

Statistical Machine Translation

id:mamorukさんのレビューが参考になる.
Philipp Koehn の Statistical Machine Translation - 武蔵野日記

参考記事

統計的機械翻訳の分野で最低限読むべき論文については以下の記事が参考になるかも.

自然言語処理のカンファレンスのレベルの話.へぇ〜へぇ〜.

Rubyで配列の条件を満たす要素を列挙するor取り除く(select, reject, partition)

Arrayの以下のメソッドについてまとめてみた.

  1. select (select!)
  2. reject (reject!)
  3. partition

select : 条件を満たす要素を列挙

条件を満たす要素を列挙するにはselectを使う.selectはブロックの評価結果がtrueとなる要素からなる配列を返す.非破壊的.

a = [1, 3, 4, 7, 9, 13]
a.select{|e| e % 3 == 0} #=> [3, 9]

破壊的メソッドあり.ただしRuby 1.9.2以降が必要.

a.select!{|e| e % 3 == 0}

reject : 条件を満たす要素を削除

条件を満たす要素を取り除くにはrejectを使う.rejectはブロックの評価結果がtrueとなる要素を除いた配列を返す.非破壊的.

a = [1, 3, 4, 7, 9, 13]
a.reject{|e| e % 3 == 0} #=> [1, 4, 7, 13]

破壊的メソッドあり.こちらはRuby 1.9.2以前からある.

a.reject!{|e| e % 3 == 0}

partition : 条件を満たす要素と満たさない要素に分ける

partitionはブロックの評価結果がtrueとなる要素とfalseとなる要素に分けた配列をまとめて返す.非破壊的.

a = [1, 3, 4, 7, 9, 13]
a.partition{|e| e % 3 == 0} #=> [[3, 9], [1, 4, 7, 13]]

selectとrejectの両方を呼び出すよりも楽.

破壊的メソッドはない.

Rubyで文字列をn文字ごとに区切って配列に格納する

String#each_charとEnumerable#each_sliceを使えば簡単にできる.

"ABCDEFGH".each_char.each_slice(3).map{|a| a.join} #=> ["ABC", "DEF", "GH"]

ただしRuby 1.8.7以降が必要.

each_charやeach_sliceなどのイテレータメソッドはブロックを与えないで呼び出すとEnumeratorオブジェクトを返すので,これに対してさらにEnumerableのイテレータメソッドを適用したり,外部イテレータとして使ったりすることができる.知っておくと結構便利.