SyntaxHighlighter

StackEdit CSS

2013年11月18日月曜日

Rubyの式をTeXのソースコードに変換するgem作った

ふと思い立って作ってみた。勢いでRubygemsにアップロードしてみた(初gem)。

GitHub

RubyGems.org

gem install ratex

説明

 最近レポートを書くのにStackEditを使っている。このエディタはTeXで数式が書けるのだが、このTeXが自分の肌には合わなく、Rubyで書けたらいいなぁと思ったのが動機。
 このgemはRubyの式をTeXの式に変換してくれる。例えば、

puts Ratex.generate{ f(x, y, t) == 2 * sin(pi / 4 * sqrt(x ** 2 + y ** 2) - pi / 2 * t) }

で、

$$f(x, y, t) = 2 \sin(\frac{\pi}{4} \sqrt{x ^{2} + y ^{2}} - \frac{\pi}{2} t)$$

となる。わかりやすいよね!(強引

puts Ratex.generate{ f[n] == f[n - 2] + f[n - 1] }

は

$$f_{n} = f_{n - 2} + f_{n - 1}$$

となる。

仕組み

 今までの自分の知識をフルに活用した黒魔術バリバリのコードになっていると思う。詳しいことはQiitaのアドベントカレンダーに書こうと思う。

2013年11月7日木曜日

U20プログラミングコンテストに参加した話

 最近の活動としてU20プログラミングコンテストに参加して、そこでいろいろ得たものがあるのでそれを整理するという意味でこのエントリを書こうと思った。

提出した作品

「Cuick」(GitHub)というプログラミング言語。これは、速く書くことを目的としたプログラミング言語で、競技などの小規模なプログラム向けだ。バイナリコードではなく、C++のコードを生成する。開発言語はJavaで、パーサジェネレータにJavaCCを使わせてもらった。
速く書くために、

  • 糖衣(ショートカット)構文の充実
    →タイプ量の軽減や余計なことを考えずにすみ、速くなる
  • 覚えることは少なめに
    →調べる時間を減らすことで速くなる
  • デバッグ支援
    →デバッグの時間を軽減することで速くなる

という方針で言語仕様を決定した。

予選締切りまで

 原案を思いついたのはたしか6月ぐらいだと思う。最初はRubyとかPythonとかのLLの機能をつけた言語だったのだが、これだと存在意義がよく分からないので、目をつけたのが競技プログラミング。競技プログラミングは実装時間が重要なのでなるべく早くソースコードをかけるようなプログラミング言語を作ろうと考えた。
 7月半ばまでは言語仕様を考えた。なるべく早くソースコードをかける=>ソースコードが短くなることを考慮した。また、C++にはないデバッグ、テスト機能も考えた。@testは相談に乗ってくれた先生が元だ。また、このあたりから実装を始めた。とりあえずパーサーを作った。
 8月は夏休みなのだが自分は高専プロコンにも参加しているのでそっちとの兼ね合いをとるのが難しかった。高専プロコンを少しおざなりにしていたところがあったので、高専プロコンのメンバーにも怒られたりした。
 8月後半。締め切りの8月30日までにすべての機能を実装できないと悟ったので、バグを治すことにした。また、友人のアイデアでWeb上でもC++に変換できるようにもした(これはRubyのsinatraを使った)。締め切り当日まで予選資料を書いていたがなんとか間に合ってホッとした

最終審査会まで

 9月に入ってからは期末テストだったので、テスト勉強をしながら結果を待った。で、結果が来たときは結構嬉しかった(そのせいか勉強に身が入らずにテスト結果が微妙だったのは秘密)。
 最終審査会のプレゼン資料締め切りが9月後半で、テストが終わったのがその1週間前だったので普通に間に合うかと思ったが、高専プロコンも終盤でなかなか忙しかったので、あまり作成、練習時間が取れなかった。

最終審査会

 結論から言うと、もっとプレゼンを練習しておけばよかったと思う。
 自分は個人部門の最後だったので他の参加者のプレゼンを見ていたのだがあまり練習していなさそうな人が資料もなしにスラスラしゃべるのを見て、自分大丈夫かなぁと思っていたら見事失敗しましたよ。前に出たら緊張で頭真っ白になって原稿飛んだし、内容も内容で後から見たらここはこうしたら方がいいんじゃないかというところが何箇所かあった。緊張は練習すれば消えると先生が言っていたのを思い出した。内容も練習すれば問題点が見つかるものだと思う。
 また、Cuick自体の評価だが「ユニーク」とは言われたがそれ以上は言われなかった。色々理由を考えた。

  • アプローチが微妙だった

    審査員の方がエディタのスニペットや補完と違って学習コストがかかると仰っていた。それに自分はC++と構文を似せていると押し通したが、今考えるとプログラミング言語というアプローチが微妙なのかなぁと思ったり思わなかったり。

  • Cuickって結局何なのか

    審査員の方が仰っていたのだがCuickって実行環境としてなのか、ただ単にツールとしてなのかはっきりしない。確かに考えてみると中途半端な感じがする。だからなんだろうと思わなくもないが。同じ個人部門のFulynは実行環境だとはっきりわかった。

  • 競技プログラミングをよく知らない

    実は競技プログラミングはよくわからない(情報オリンピック予選落ちレベル)。すみません。よく知っている人に意見を聞けばよかったなぁと後悔する。とはいいつつもそういう人は周りにいないので聞けないが。

  • 目に見える具体的なデータが示せてない

    プレゼン前日にある問題をC++とCuickで解いてみたのだが、ぶっちゃけあまり時間が変わらなかった。問題によって個体差はあると思うが、正直Cuickの存在意義がわからなくなってしまった(ホビー言語としてなら十分面白いかも)

  • プレゼンがアレゲだった

というわけで、最終審査会当日はクタクタだった(東京までの移動もあるしね)。次の日は表彰式だが2時45分集合で、どうせなので東京観光していた。と言っても秋葉原に行っただけだがw 一人でぶらぶら移動するのが結構楽しくて、一人旅の面白さを知ってしまった気がする。

他の作品

 これはいいと思った作品が数点あるので感想を書いておく。

  • Arrow Judge

    オンラインジャッジを実現するためのオープンソースシステム。自分もオンラインジャッジシステムを作ったことがあるが、それよりも1枚も2枚も上手だった。例えば、セキュリティ対策だ。自分が作ったやつはセキュリティ対策は皆無だったが、Arrow Judgeはちゃんとセキュリティ対策をしておりすごいと思った。また自分で問題を投稿できるというところは使用場面もはっきりしておりいいと思った。

  • Fulyn

    OSECPU向けの関数型言語。関数型言語はよくわからないので、言語自体の感想は言えないが、まだ高級プログラミング言語がないOSECPU向けに作るのは少し興味が出た。プレゼンは全然わからんかったw

プレゼンを見ただけだがレベルが高いなーと思った。自分は彼らのようにはなれないが、自分の強いところを生かして彼らに並べるようになりたいなーと漠然と思ったわけですよ

感想

 今まで生きてきた中で一番濃い体験をしたと思う(小並感)。まず、自分より上の人と接したことでワールドというものを肌で感じたとこだ。井の中の蛙ってやつですよ。次に、自分はプレゼンが苦手だと決めつけていたがそれは練習してないだけだったということだ。
 こういう大会に出るといろいろ考えられて成長できるのでこれからもどんどん大会などの出場しようと思った。

2013年10月11日金曜日

2013年4月15日月曜日

C++で遠隔操作

釣り。

授業を聞いててふと思いついた。
その授業では、モジュールの隠ぺい(オブジェクトのprivateとか)について説明していたんだけど、C++ではprivateにしても外からいじれるという話をどこかで聞いたので試したくなった。

そのオブジェクト自身が漏らす場合

class Player {
    int money;
public:
    Player(int m) : money(m) { }

    int getMoney() { return money; }

    int* wrongMethod() { return &money; }
};

int main(){
    Player player(10);

    cout << player.getMoney() << endl; //=> 10

    int* money = player.wrongMethod();
    *money *= 100;
    cout << player.getMoney() << endl; //=> 1000

    return 0;
}
何かのミスで、privateのメンバ変数のアドレスを漏らしてしまった場合。これはほかの言語でもありうるだろう

外から位置を特定して触る方法

class Player {
public:
    int power;
private:
    int HP;
    int MP;
    int money;
public:
    Player(int m) : money(m) {
        cout << &power << endl;
        cout << &HP << endl;
        cout << &MP << endl;
        cout << &money << endl;
    }

    int getMoney() { return money; }
};

int main(){
    Player player(10);
    cout << &player << endl;

    cout << player.getMoney() << endl; //=> 10

    int* money = (int*)&player + 3;
    *money *= 100;
    cout << player.getMoney() << endl; //=> 1000

    return 0;
}
Playerのコンストラクタでメンバのアドレスを調べたら、playerのアドレスがpowerと一致していて、また、power、HP、MP、moneyの順でアドレスが4(=sizeof(int))ずつ増えていったのでもしやと思い、playerのアドレスに+3したら見事にアクセスできたw
C++のポインタが理解しにくいといわれてるのは、クラスなどの先進的な機能とポインタなどのプリミティブな機能が同居しているところにあるってどっかで見たけど、まさにその通りだとこれで実感した。こういうキケンなことができることは、速度とのトレードオフだろうけど。

おまけ

privateメソッドは内部から漏れることぐらいしか思いつかなかった
class Player {
    void privateMethod(){
        cout << "@privateMethod" << endl;
    }
public:
    void (Player::*wrongMethod())() { return &Player::privateMethod; }
};

int main(){
    Player player;
    (player.*(player.wrongMethod()))();

    return 0;
}
関数ポインタの書き方わからんwww

2013年4月11日木曜日

CoffeeScript + enchant.jsでパズドラもどきを作ってみた感想

動機

パズドラ面白そうだなぁ → ソシャゲーはちょっとなぁ。。。 → じゃあつくってみるか

スクショ


どう見てもパズル&ドラゴンズです。本当にありがとうございました。

感想

CoffeeScriptとenchant.js、どちらも初めてだったが、意外とすんなりできた。バグを直す時間のほうが長かったんじゃないかってくらい。CoffeeScriptはRubyがまぁまぁ使えるので、直ぐに書けるようになったし、enchant.jsは情報が多かったのでそれほど詰まるってことはなかった。
 JavaScriptはよくわからないので比べられないが、少なくともCoffeeScriptで実装中のストレスはほとんどなかった。0引数の関数を呼ぶときのかっこをRubyのノリで付け忘れてすこし悩んだり、インデントを間違えて数時間悩んだりしたぐらい。豊富なシンタックスシュガーのおかげでサクサクかけた気がする。->が結構かっこいい。
isInField = (x, y) ->
    #...
とか。
lines.forEach (line) ->
    #...
はRubyでいうブロックみたいに見える
 enchant.jsはSpriteで画像を表現するのに少し慣れなかった。勝手にカウントしてくれるラベルがあったのは少し驚いた。こうしたもののおかげで実装の負担が軽くなるのはいいことだと思う。何より好感が持てたのは、ゲームに使える画像がいくらか付属していることだ。ゲームを作っても絵が描けないので、見た目が残念だったりして、結構萎える。クオリティの高い画像が付属していると、作る側のモチベーションも上がるよなぁと思った。自分もドラゴンの画像を使わせてもらった。
 最初は充実感があったが、だんだん完成に近づくにつれ、充実感が無くなってきた。どれだけ頑張っても、本家には勝てない気がしてきたからだ(あたりまえ)。つまり劣化コピーだ。やはり模倣は面白くないなと身に染みてわかった。コピーしようと思ったらそれを超えるものを作らないと成長しないしね。
 ちなみに動機は実装している間に消えてしまったwww

2013年3月26日火曜日

return関数実装したった

もうなんかありそうなネタ。
思い立ったので、return関数をC++のインラインアセンブリを使って実装してみた。


#include <stdio.h>

void _return(){
    __asm{
        pop ebp //フレームポインタ回収
        pop ebp //_returnから脱出
        pop ebp //呼び出し元のフレームポインタ回収
        ret
    }
}

void _return(int val){
    __asm{
        mov eax, dword ptr [ebp + 8] //返り値セット
        pop ebp
        pop ebp
        add esp, 4 //呼び出し側の仕事
        pop ebp
        ret
    }
}

void func1(){
    _return();
    puts("ここは実行されない");
    return;
}

int func2(){
    _return(10);
    puts("ここは実行されない");
    return -1;
}

int main(){
    
    func1();
    
    printf("%d\n", func2()); //=> 10
    
    return 0;
}

実装してから思ったが誰得だwww

2013年2月23日土曜日

OnlineJudge自作2

 前のやつの日付を見たら、もう2か月以上も前だった…
 一応ショートコーディング大会当日までに実装は間に合ったんだが、エラーは出るわ、ランキングに反映されないわ、ソースを送っても無視されるブラウザ(Firef○x)があるわでうまく動かなかった。


終わりの始まり

 当日2週間前。1週間前から始めればおk!と、余裕をこいて実装をはじめなかった。
 当日1週間前。そろそろはじめないとやヴぁいと思い実装開始。だが最初で最後の土日(当日は土曜日)を環境のセットアップでつぶしてしまう。
 土曜日は、流行のRuby on Railsを使おうと思い環境を入れ、実装をしているうちに、方法に慣れなかったのか思うように実装できなかったので、時間もないしこれは捨てたほうがいいのではと思い、Ruby on Railsの使用を中止し、PHPとPerlを使うことにした。
 日曜日は、さぁ環境を作ろうずと思い、Apacheをいれるも、なかなか思うように設定できず、1日つぶしてしまった。

最後の希望

 残り1週間。このあたりの記憶はあまりないが、毎日1~3時まで実装してた気がする。特に前日の金曜日は睡魔がやヴぁかった。

ぼくらのサーバー

 当日。朝起きたら、実装途中のPCがあった。急いで実装し、学校にいき、さぁテストしようと思ったら動かない。サーバーのスペースは友人に貸してもらったのだが、当方の環境と違ったのだ。GoogleTalkで友人と連絡を取りながら、何とか修正したが、(冒頭へ)


反省点

一番大きいのは、計画不足だ。ってあれこれ前もあったぞ。完成してから、アナウンスすべきだった。
マルチタスク慣れてないくせに、やりたいと思ったらすぐはじめてしまったのも裏目に出た。
まぁ経験になったからいいや。
今度から気を付けます。