Vimで投稿してみる
できたかな
今日やったことのまとめ
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
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&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}" }SKSの申し子 on Twitter: "@wakuteka 今更だけど,「ループの回数だけアスタリスクを表示」はこんな感じで行けるかも(Ruby). 10.times { |num| puts "#{num} #{'*' * num}" }"
rubyだとこれでおkだと教えていただきました。
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; }
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)); }
参考文献
- 作者: 清水義範
- 出版社/メーカー: 講談社
- 発売日: 2004/12
- メディア: 文庫
- クリック: 23回
- この商品を含むブログ (34件) を見る
103日目 第4章 逆ポーランド記法型電卓プログラム
本文のソースを参考に、とりあえずわかるところまでやってみた。
//main() MAXOP, NUMBER // getop() NUMBER // getch() // !isdigit() <ctype.h> // ungetch() BUFSIZE // !atof() <stdlib.h> // push() MAXVAL // pop() // !printf() <stdio.h> #include<ctype.h> #include<stdio.h> #include<stdlib.h> #include<math.h> // Ex.4-5 #define MAXOP 100 #define NUMBER '0' #define BUFSIZE 100 #define MAXVAL 100 int getop(char []); int getch(void); void ungetch(int); void push(double); double pop(void); main() { int type; double op2; char s[MAXOP]; while((type=getop(s)) != EOF) { switch (type) { case NUMBER: push(atof(s)); break; case '+': push(pop() + pop()); break; case '-': op2 = pop(); push(pop() - op2); break; case '*': push(pop()*pop()); break; case '/': op2 = pop(); if(op2 != 0.0) push(pop() / op2); else printf("error: zero divisor\n"); break; case 's': push(sin(pop())); break; case 'e': push(exp(pop())); break; case 'p': op2 = pop(); push(pow(pop(), op2)); break; case '\n': // answer printf("\tans:%.8g\n", pop()); break; default: printf("error: unknown command %s\n", s); break; } } return 0; } int getop(char s[]) { int i, c; while ((s[0] = c = getch()) == ' ' || c == '\t') ; // 読み込んだ文字が空白かタブだったら何もしない s[1] = '\0'; if(!isdigit(c) && c != '.') return c; // 数字でも小数点でもなければそれを返す i = 0; if (isdigit(c)) while (isdigit(s[++i] = c = getch())) ; // 読み込んだ値が数字だったら、何もしないで次の値も読み込んで配列に格納 if (c == '.') while (isdigit(s[++i] = c = getch())) ; // 読み込んだ値が小数点だったら、何もしないで次の値も読み込んで配列に格納 s[i] = '\0'; if (c != EOF) ungetch(c); // EOFを吐き出す return NUMBER; } char buf[BUFSIZE]; int bufp = 0; int getch(void) { return (bufp > 0) ? buf[--bufp] : getchar(); } void ungetch(int c) { if (bufp >= BUFSIZE) printf("ungetch: too many characters\n"); else buf[bufp++] = c; } int sp = 0; double val[MAXVAL]; void push(double f) { if (sp < MAXVAL) val[sp++] = f; else printf("error: stack full, can't push %g\n", f); } double pop(void) { if (sp > 0) return val[--sp]; else { printf("error: stack empty\n"); return 0.0; } }
ruby複利計算のお題をCでやってみた
そこでRubyKaigi2008 Golfコンペなるものがあったので自重しないで参加してみたよ。
日本 Ruby 会議 2008 - RubyKaigi2008 Golfコンペ
…Cで。
回数:初期値:パーセント の形で入力して複利計算の結果を表示しろ。(ただし計算途中の小数点は切り捨て)
anarchy golfの146番目の問題。
難易度はそんなに高くない、らしい。
とりあえず覚えたばっかのコマンドライン引数使ってみるか。
要求された使用とちょっと違うがとりあえずここまでしかできません><
#include<stdio.h> #include<stdlib.h> #include<math.h> main(int argc, char *argv[]) { int i, k = atoi(argv[1]); double j = atoi(argv[2]); for(i = 0; i < k; i++) printf("%.0f\n", j); { j = floor(j*(100+atoi(argv[3]))/100 } }
floor関数はじめて使った。