2010年1月25日月曜日

履歴書の書き方2

Check
前回の続き。東京で就活を行っている時に滞在した友人宅で聞いたアドバイスまとめ。

結論は先に書く。「あなたの得意科目について書いてください」とあるなら「私の得意科目は○○です」と先に書いてしまうこと。何百枚も履歴書見てると、飽きるわ疲れるわでダラダラした文章を見ても何も伝わってこないそうな。何より履歴書書く本人が楽な気がしてきた。

履歴書を友人に見てもらい、疑問点を挙げてもらう。履歴書の精度も上がるし、面接対策になるそうです。客観的な視点って重要よね。

社会人に見てもらう。学生の視点と社会人の視点は全く違う。学生の視点だと色々「甘いなぁ」と思ってしまうそうだ。

仕事に対する前向きな気持ちが文章に表れているかチェック。どんなに大学や専門学校で勉強してきたからって、所詮は学生レベル。そんなことは会社もわかっている。今後の成長の見込みがあるかどうかを、履歴書でチェックする。安定志向とか言っちゃ駄目よ。

上京したらまずSuicaを作ろう

Check
初めて東京行ってきました。人が多すぎて頭痛くなりましたが、交通網が発達しているところは本当に羨ましい。特にJRは、ほとんどの街にいけるんじゃねえかというくらい便利なので、電子マネーのSuicaは作っておくと良いでしょう。移動が格段に楽になります。




緑の窓口で2000円出せば、デポジット料500円+電子マネー1500円分が最初から入った状態で購入可能。毎回切符を買うわずらわしさと、行き先にあわせて料金を確認したりする手間から開放されます。

ちなみに不必要になった時には、カードを返せばデポジット金の500円は返却してもらえて安心。

JR九州のSUGOCA(Suicaのパチモン)と連携できればもっといいのですが、現在はそのような仕様にはなっていないようです。ちなみに関西にはICOCAというカードもあります。こういうのはなるべく統一してほしいんですがねぇ…。

2010年1月14日木曜日

wxWidgets事始め

Check
いよいよレイトレーサをGUIアプリケーションとしてまとめることになった。どうせやるならクロスプラットフォームということで、開発にはwxWidgetsを使うことに。

とりあえず導入までに参考にしたサイトを列挙。
以上を参考にして作成したのが以下のアプリケーションだ。


中身は空のハリボテだが、C++でここまで楽にGUIアプリケーションが構築できるのには正直驚いた。オブジェクト指向を取り入れてあるのでJavaのSwingよろしく組みやすい。

2010年1月13日水曜日

C++で経路探索

Check
事の始まりは某所のC#スレで見かけたこの記事。ちょこっと引用すると、
内容は、壁とスペースで構成された迷路が与えられたとき、スタート地点からゴール地点に至る最短経路を求めよ、というものです。
たとえば、S:スタート G:ゴール *:壁 $:解答の経路 としたとき、
**************************
*S* *                    *
* * *  *  *************  *
* *   *    ************  *
*    *                   *
************** ***********
*                        *
** ***********************
*      *              G  *
*  *      *********** *  *
*    *        ******* *  *
*       *                *
**************************
とのこと。ふむ、なかなか面白そうじゃない! 独りでやるのも寂しいので、学校の先生と競争してみることに。
#include <iostream>
#include <string>
#include <fstream>
#include <vector>

typedef unsigned char byte;
typedef unsigned int uint;
typedef std::vector<std::string> StringList;

using namespace std;

/**
* 2次元配列の位置などを表す構造体
*/
struct POS{
    uint x, y;
};

//定数
const char *fname = "dat.txt";//ファイルデータパス
const byte WALL = -1;//壁を表す定数

//
// 再帰的にスタートからゴールへ向かって最短距離を求める
// @param now 現在位置
// @param from 一つ前の位置
// @param dat 書き換えるデータ配列
// @param width データ配列幅
// @param start スタート地点
// @param goal ゴール地点
// @return none
//
void SearchPath(
                uint count,
                const POS &now,
                const POS &from,
                byte *dat,
                uint width,
                const POS &start,
                const POS &goal
                )
{
    //再帰の終了をチェック
    if(now.x == goal.x && now.y == goal.y){
        dat[now.x+now.y*width] = count+1;
    }

    //次に移動する座標を決定する
    POS next[4] ={
        {now.x, now.y-1},//上
        {now.x, now.y+1},//下
        {now.x-1, now.y},//左
        {now.x+1, now.y},//右
    };
    for(uint i=0; i<4; ++i){
        uint idx = next[i].x + next[i].y*width;//次に調べる位置

        //次の位置が壁なら調べない
        if(dat[idx] == WALL){
            continue;
        }

        //次に調べる位置が既に調べてあり
        //かつ、すでに最短パスが出ていたらこれ以上調べない
        if(dat[idx] > 0 && dat[idx] < count){
            continue;
        }

        //現在の位置にこれまでの歩数を記録する
        dat[now.x+now.y*width] = count;

        //次の経路を再帰的に調べる
        SearchPath(count+1, next[i], now, dat, width, start, goal);
    }
}

//
// ゴール地点からスタート地点へ向かって最短経路を描画する
// @param sl 書き出す文字列リスト
// @param now 現在位置への参照
// @param start スタート地点
// @param goal ゴール地点
// @param dat ステップ数が記述されたデータ配列(壁は0xff)
// @param width データ配列幅
//
void FindPath(
              StringList *sl,
              const POS &now,
              const POS &start,
              const POS &goal,
              const byte *dat,
              uint width
              )
{
    //再帰打ち切りの条件
    //すなわち、現在地がスタート地点なら終了
    if(now.x == start.x && now.y == start.y){
        return;
    }

    //次に移動する座標を決定する
    POS next[4] ={
        {now.x, now.y-1},//上
        {now.x, now.y+1},//下
        {now.x-1, now.y},//左
        {now.x+1, now.y},//右
    };

    //現在のステップ数
    uint nowStep = dat[now.x+now.y*width];

    for(uint i=0; i<4; ++i){
        uint idx = next[i].x + next[i].y*width;//次に調べる位置

        //次の位置が壁なら調べない
        if(dat[idx] == WALL){
            continue;
        }

        //次の位置が現在のステップ数より小さいときは
        //再帰的に調べる
        if(dat[idx] == nowStep-1){
            //経路マークをつける
            char mark = '$';
            if(now.x == goal.x && now.y == goal.y){
                mark = 'G';
            }
            sl->at(now.y).at(now.x) = mark;

            //次の経路を再帰的に調べる
            FindPath(sl, next[i], start, goal, dat, width);
            return;
        }
    }
}

//
//エントリポイント
//
int main(){
    //
    // テキストからデータを読み込んで配列に格納
    //
    std::fstream fs(fname);
    StringList sl;
    while(!fs.eof()){
        string tmp;
        getline(fs, tmp, '\n');
        sl.push_back(tmp);
    }

    //数値に変換して配列に格納
    uint height = sl.size();//配列高さ
    uint width = sl[0].size();//配列幅
    byte *dat = new byte [width*height];//作業用配列

    POS start = {0,0};//スタート
    POS goal = {0,0};//ゴール
    POS now = {0,0};//現在地

    for(uint y=0; y<height; ++y){
        for(uint x=0; x<width; ++x){
            uint idx = x+y*width;
            dat[idx] = 0;
            switch(sl[y][x]){
                case '*':
                    dat[idx] = WALL;
                    break;
                case 'G':
                    goal.x = x;
                    goal.y = y;
                    break;
                case 'S':
                    start.x = now.x = x;
                    start.y = now.y = y;
                    break;
            }
        }
    }

    //
    // 経路探索
    // 上下左右に対して再帰的に検索をかける
    //
    SearchPath(0, start, start, dat, width, start, goal);

    //探索したパスを元に最短経路を描画する
    FindPath(&sl, goal, start, goal, dat, width);

    //
    //デバグ用表示
    //
    for(uint y=0; y<sl.size(); ++y){
        cout << sl[y] << endl;
    }

    //
    //ファイル書き出し
    //
    ofstream ofs("out.txt");
    for(uint y=0; y<sl.size(); ++y){
        ofs << sl[y] << endl;
    }
    ofs.close();

    //あとしまつ
    delete [] dat;
    dat = 0;

    return 0;
}
結果は惨敗。相手は1時間ちょっとで終わっていたのに対して、私は4時間かけてようやくといったところ。先生はPythonを使われていいたようです。てかこの手の問題でC++を使う時点でダメだろ俺…。Pythonなどの高級言語や、関数型言語ならもっともっと美しく簡潔に書けたでしょうね。とにかく自分の無能さが身に染みてわかった。くやしい!

自分のアホさにげんなりした問題でした。さて、寝よう(:D)┼─┤

2010年1月7日木曜日

履歴書の書き方

Check
自分で調べたもの+学校の先生に指導していただいたものをまとめておく。参考程度に。

解説サイト
西暦と元号の対応
資格
略称
履歴書への記入
TOEIC
TOEIC公開テスト○○○点
C言語検定
サーティファイ主催 C言語プログラミング能力検定試験○級合格
AP
経済産業省 応用情報技術者試験合格
CGエンジニア検定
CG-ARTS協会主催 CGエンジニア検定試験○級合格

改ざんがないことを示すために無駄な隙間は作らない
×→   平成○○年  ○月   ○○市立    ○○中学校   卒業
○→平成○○年○月 ○○市立○○中学校卒業
住所について
現住所と帰省先が同じ場合でも、「同上」などと略さずにきちんと書くこと。

得意科目について
国語・数学などのいわゆる5教科以外でも、情報系の学校でプログラムの実習などがあればそちらを書いても問題ない(例:C言語)。
むしろIT系の業界を志望するならそこがアピールになる、とのこと。

趣味について
業種にもよるが、パチンコなどのギャンブル関係は避けたほうが吉。
面接で聞かれたときにちゃんと答えられるようなものを書く(まあ当然か)。読書と書いておきながら、本をほとんど読まない人などが多いそうだ。

下書きと清書
レイアウトなどは定規を使って丁寧に下書きを行うこと。
清書は細めの水性ボールペンを使用するほうがいい。
清書後の下書きを消しゴムで消すときは念のため1日はあける(失敗して悲惨な目にあった)。
個人的にお勧めなのはイラスト用のドローイングペン

std::fstreamでファイルサイズを取得

Check
メタセコイア読み込みに関連して、std::fstreamからデータを読み込む際に必要なことのまとめ。
#include <iostream>
#include <fstream>

typedef unsigned int uint;
const char *fname = "C:/hoge/piyo.txt";//ファイルパス

int main()
{
    using namespace std;

    ifstream fs(fname);//ファイルオープン。読み込み形式は指定なしのときはテキストモードになる。

    fs.seekg(0, fstream::end);//ファイル末尾を探す
    uint eofPos = fs.tellg();//ファイル末尾インデクスを取得

    fs.clear();//先頭にもどるために一度clear()をかける。これをしないと次のseekg()でコケるときがある。

    fs.seekg(0, fstream::beg);//ファイル先頭に戻る
    uint begPos = fs.tellg();//ファイル先頭インデクスを取得

    uint size = eofPos - begPos;//末尾-先頭でファイルサイズを計算

    char *buf = new char [ size ];//サイズ分の領域を確保
    memset(buf, 0, size);//0クリアしておく

    fs.read(buf, size);//ファイル先頭からバッファへコピー

    fs.close();//ファイルを明示的に閉じてみる

    cout << buf << endl;//確認のため出力

    SAFE_DELETE_ARRAY(buf);//バッファを削除
    return 0;
}
基本は上記のとおり。

例外処理も入れるべきだが、使い方を間違えると正しく読み込めているのに例外が送出されてしまうので注意。
下記のリストに挙げた『std::ifstream::read()の使い方がツライ』の記事を参考されたい。
参考

新年の抱負など

Check
いよいよ就職本番の年。悔いのない一年(実質半年もないわけだが)を過ごして次へのステップにつなげたい。

今月は中旬より会社説明会のために東京へ。 一次選考を行ってくれる会社もあるので、まずはその突破を図る。
ゲーム関連を受けつつ、IT企業へもエントリーしているので受ける。総合して6月までに内定が出れば上出来としよう。

資格はCG-ARTS協会主催のCGエンジニア検定1級合格を目指す。先月めでたく2級合格を果たせたので、今度は1級だ。
試験内容もこれまでの選択式から記述式へ移行するので、これまでのようにあいまいな理解では合格は難しいだろう。
同時に、実装経験の量がますます重要になってくると思われる。

依然不景気ということで暗い1年になりそうだが、気持ちだけでも明るく生きていきたいものだ。