Hatena::ブログ(Diary)

id:wakutekaのプログラミングメモ このページをアンテナに追加 RSSフィード

2008-07-11

2008-07-09

今日やったことのまとめ

Vimメモ

基本vimperatorと同じ(当たり前

:help user-manualを読む

Ctrl-]でリンク先を開いて、Ctrl-oでたまに戻りつつ読んでいく

:e ./でカレントディレクトリを開くとエクスプローラみたいな感じ。ファイル名にフォーカスしてRでリネーム。tでtabopen、iで詳細表示(作成日時とかわかる)。

:vnewで垂直フレームとして開ける。

Normal mode

xで削除 iで挿入 aで追加 dwで単語削除, ddで行削除 uはundo(「元に戻す」)

Ctrl-d,uで半画面down,upスクロールが便利

Vimperatorのエントリも多いBig skyさんとこにTipsがあった

はてなグループVimとか

↓ここが単一エントリではたぶん一番詳しい

vimで効率的にコードを書くための小技 - bonar note

C以外でやりたいこと

テキスト処理→正規表現覚える

ゲノム解析の初歩はテキスト処理だから。

ハミング距離とかレーベンシュタイン距離とか出せるようにしたい

とりあえず、はじRubyを買ったのでp.68の正規表現の表を眺めて今日はおしまい

メタキャラクタとかCの文字列処理で実装してみたら覚えそう

(…普通に使って覚えてもいいんだけどww

2008-07-05

119日目 C引数付き置換マクロで作る、擬似timesメソッド(Ruby)

Rubyのtimesメソッドがうらやましくなってマクロで遊んでみました。

Ruby

    3.times {
        puts "hello"
}

C

#include <stdio.h>

#define times(N) for(num = 0; num < N; num++)

int main()
{
    int num;

    times(3)
        printf("hello\n");
    return 0;
}

次に、times(num, 3)と書けば、numを0から1ずつ増やしながら、3になるまで(つまり3回)以下の行を実行するようにしました。

Ruby

3.times {|num|           /* numを0から1ずつ増やしながら */
    puts "num = #{num}"  /* 3になるまで実行する         */ 
}

C

#include <stdio.h>

#define times(M, N) for(M = 0; M < N; M++) 

int main()
{
    int num;

    times(num, 3)         /* numを0から1ずつ増やしながら */
        printf("num = %d\n", num);
    return 0;
}

で、これを使えば回数のみの多重ループの可読性が上がるはず。

くどいようだがループの回数アスタリスク表示をまたやりましたよ。

#include <stdio.h>

#define times(M, N) for(M = 0; M < N; M++) 

int main()
{
    int ast, num;

    times(num, 10) {         /* numを0から1ずつ増やしつつ */
	printf("%d\t", num);     /*  num == 10 になるまで実行 */
	times(ast, num)      /* astを0から1ずつ増やしなつつ */
	    printf("*");         /*  ast == num になるまで実行 */
	printf("\n");
    }
    return 0;
}

マクロ置換前

#include <stdio.h>

int main()
{
    int num, ast;

    for (num = 0; num < 10; num++){    // numを0から1ずつ増やしつつ
        printf("%d\t", num);             // num == 10 になるまで実行
        for (ast = 0; ast < num; ast++)  // astを0から1ずつ増やしなつつ
            printf("*");                    // ast == num になるまで実行
        printf("\n");
    }
    return 0;
}

一度この置換を経験してみると、2種類のfor文の違いがはっきりしていいかも?

参考:102日目 これは遅延評価勉強法なのか - id:wakutekaのプログラミングメモ

ループの回数だけアスタリスクを表示 - yaottiの日記 - ハチロク世代

36日目 K&amp;RのExerciseをやってみた - id:wakutekaのプログラミングメモ


ちなみにRubyだとこうなるかな。

10.times {|num| 
    print "#{num} "
    num.times {|ast|
	print "*"
    }
    print "\n"
}

動作確認はcodepad.orgでやりました。

codepad


追記

10.times { |num| puts "#{num} #{'*' * num}" }
君の名は。ヒッセンさんのツイート: "@wakuteka 今更だけど,「ループの回数だけアスタリスクを表示」はこんな感じで行けるかも(Ruby). 10.times { |num| puts "#{num} #{'*' * num}" }"

rubyだとこれでおkだと教えていただきました。

2008-06-30

113日目 等差数列の和


まず末項を計算させる

#include <stdio.h> /* arithmetic progression (print last term)*/
#include <stdlib.h>

int main(int argc, char *argv[])
{
    int i, sum;
    int first = atoi(argv[1]), diff = atoi(argv[2]), num = atoi(argv[3]);

    for (i = 1, sum = first; i < num; i++)
        sum += diff;
    (num >= 1) ? (printf("a(%d) = %d", num, sum)) : (printf("error!"));
    return 0;
}

んで関数化します。


配列を表示して挙動を確認

#include <stdio.h> /* arithmetic progression (print array)*/
#include <stdlib.h>

int func(int first, int diff, int num)
{
    int i, sum;
    for (i = 1, sum = first; i < num; i++)
        sum += diff;
    return sum;
}

int main(int argc, char *argv[])
{
    int i, sum, first = atoi(argv[1]), diff = atoi(argv[2]), num = atoi(argv[3]);
    for (i = 1, sum = first; i < num; i++)
        sum += diff, printf(" %3d", sum);
    printf("\n%3d", first);
    for(i = 1, sum = first; i < num; i++)
        sum += func(first, diff, i+1), printf(" %3d", sum);
    printf("\nsum(%d) = %d", num, sum);
    return 0;
}

和だけを表示させる

#include <stdio.h> /* arithmetic progression (ver 2.0) */
#include <stdlib.h>/* a(1) + a(2)+ ... + a(n-1) + a(n) */

int func(int first, int diff, int num) {
    int i, sum;
    for (i = 1, sum = first; i < num; i++)
        sum += diff;    /* calc a(n) */
    return sum;
}

int main(int argc, char *argv[]) {
    int i, sum;
    int first = atoi(argv[1]), diff = atoi(argv[2]), num = atoi(argv[3]);
    for(i = 1, sum = first; i < num; i++)    /* sum = a(1) */
        sum += func(first, diff, i+1);      /* sum + a(2)+ ... + a(n-1) + a(n) */
    (num >= 1) ? (printf("sum(%d) = %d", num, sum)) : printf("error!");
    return 0;
}

2008-06-29

112日目 整数の乗除を加減記号で実装(途中ww)

パズルみたいで面白かったけれども実用とかけ離れてるwww


注1:コマンドライン引数を使用してます

注2:めちゃめちゃですww


割られる数<割る数でもオッケー、ただし両方10のn乗

#include <stdio.h> /* division, if(a < b, both a and b included in pow(10,x))*/
#include <stdlib.h>

int divi(int a, int b);

int main(int argc, char *argv[])
{
    int a = atoi(argv[1]), b = atoi(argv[2]);
    int i , j, num;
    if (b == 0)
        printf("error: zero divisior");
    else if (a >= b)
        printf("%d", divi(a, b));
    else if (a < b) {
        for (i = 0, num = a; divi(num, b) <= 1; ++i)
            num *= 10;
        printf("0.");
        for (j = 0; j < i-1; ++j)
            printf("0");
        printf("%d", divi(num, b));
    }
}

int divi(int a, int b)
{
    int i;
    for (i = 0; a > 0; i++)
        a -= b;
    return i;
}

モジュロ

#include <stdio.h> /* modulo */
#include <stdlib.h>

int mod(int a, int b)
{
    while (a >= b)
        a -= b;
    return a;
}

int main(int argc, char *argv[])
{
    int a = atoi(argv[1]), b = atoi(argv[2]);
    (b != 0) ? (printf("%d", mod(a, b))) : (printf("error: zero divisior"));
}

割られる数≧割る数(両方整数) 小数点切り上げ中

#include <stdio.h> /* division, if(dividend >= divisor) */
#include <stdlib.h>

int divi(int a, int b)
{
    int i;
    for (i = 0; a > 0; i++)
        a -= b;
    return i;
}

int main(int argc, char *argv[])
{
    int a = atoi(argv[1]), b = atoi(argv[2]);
    (b != 0) ? (printf("%d", divi(a, b))) : (printf("error: zero divisior"));
}

乗算

#include <stdio.h> /* multiply */
#include <stdlib.h>

int mtp(int a, int b)
{
    int i, num = 0;
    for (i = 0; i < b; i++)
        num += a;
    return num;
}

int main(int argc, char *argv[])
{
    int a = atoi(argv[1]), b = atoi(argv[2]);
    printf("%d", mtp(a, b));
}

参考文献

いやでも楽しめる算数 (講談社文庫)

いやでも楽しめる算数 (講談社文庫)