BBS-BBS/48
キミならどう書く 2.0 - ROUND 3 - まとめ - さいとう (2006年09月03日 00時34分08秒)
まずは普通に書いてみる。
キミならどう書く 2.0 - ROUND 3 - にあるサンプルの * の個数と異なるが、以下のようにしてできる。少し無駄を多めに作っているけど、これでほぼ完成である。
#! /usr/bin/gawk -f
#=====================================================================
# http://ll.jus.or.jp/2006/blog/doukaku3
# キミならどう書く 2.0 - ROUND 3 -
#---------------------------------------------------------------------
# たとえば以下のようなものです.
#
#% ./graph 2 5 9
# 2/ 16 : *****
# 5/ 16 : ************
# 9/ 16 : ********************
#
# このプログラムでは最大の数値に対応する '*' の数を 20 とし,与えられた
# 数値に応じた数の '*' を出力しています.
#=====================================================================
BEGIN {
#===================================================================
# バーの最大値
if ( max_bar == "" ) {
max_bar = 20;
}
#===================================================================
# 必要な ARGV だけ抽出
for ( i = 1; i <= ARGC - 1; i++ ) {
data[i] = ARGV[i];
num_data++;
}
for ( i = 1; i <= num_data; i++ ) {
printf( "%3d/%3d : %s\n", data[i], get_sum( data ), \
bar( data[i], data ) );
}
}
#=====================================================================
# 配列中の最大値を見つける
function get_max( arr, i, max ) {
for ( i in arr ) {
if ( arr[i] > max ) {
max = arr[i];
}
}
return max;
}
#=====================================================================
# 配列の総和を求める
function get_sum( arr, i, sum ) {
for ( i in arr ) {
sum += arr[i];
}
return sum;
}
#=====================================================================
# "*" の文字列を得る
function bar( num, arr, num_star, i, bar_star ) {
num_star = int( num / get_max( arr ) * max_bar );
for ( i = 1; i <= num_star; i++ ) {
bar_star = sprintf( "%s*", bar_star );
}
return bar_star;
}
実行結果
実行結果は以下のとおり。
$ gawk -f graph.awk 2 5 9 2/ 16 : **** 5/ 16 : *********** 9/ 16 : ********************
変数 max_bar で最大のバーの長さを可変にしてある。
$ gawk -v max_bar=60 -f graph.awk 2 5 9 2/ 16 : ************* 5/ 16 : ********************************* 9/ 16 : ************************************************************
Collatz 予想の 97 を描画させてみる
右のグラフはキミならどう書く 2.0 - ROUND 2 - まとめで OOo で描画させたものであり、これを描画させてみることにする。
まず、collatz.awk を用意。(以前のものと異なっています。)
#! /usr/bin/gawk -f
BEGIN {
if ( ARGV[1] == "" ) {
max = 100;
} else {
max = ARGV[1];
}
count = 0;
max_num = 0;
collatz( max );
}
function collatz( num ) {
printf( "%d ", num );
if ( max_num < num ) {
max_num = num;
}
if ( num == 1 ) {
result = 1;
count++;
printf( "\n" );
} else {
if ( num % 2 == 0 ) {
result = collatz( num / 2 );
} else {
result = collatz( 3 * num + 1 );
}
count++;
}
return result;
}
graph.awk の printf() 関数の桁数を 5 桁にして、以下のように実行します。引数として値を与えるので、以下のような書式になります。
$ gawk -v max_bar=60 -f graph.awk `gawk -f collatz.awk 97`
97/103254 :
292/103254 : *
146/103254 :
73/103254 :
220/103254 : *
110/103254 :
55/103254 :
166/103254 : *
83/103254 :
250/103254 : *
125/103254 :
376/103254 : **
188/103254 : *
94/103254 :
47/103254 :
142/103254 :
71/103254 :
214/103254 : *
107/103254 :
322/103254 : **
161/103254 : *
484/103254 : ***
242/103254 : *
121/103254 :
364/103254 : **
182/103254 : *
91/103254 :
274/103254 : *
137/103254 :
412/103254 : **
206/103254 : *
103/103254 :
310/103254 : **
155/103254 : *
466/103254 : ***
233/103254 : *
700/103254 : ****
350/103254 : **
175/103254 : *
526/103254 : ***
263/103254 : *
790/103254 : *****
395/103254 : **
1186/103254 : *******
593/103254 : ***
1780/103254 : ***********
890/103254 : *****
445/103254 : **
1336/103254 : ********
668/103254 : ****
334/103254 : **
167/103254 : *
502/103254 : ***
251/103254 : *
754/103254 : ****
377/103254 : **
1132/103254 : *******
566/103254 : ***
283/103254 : *
850/103254 : *****
425/103254 : **
1276/103254 : ********
638/103254 : ****
319/103254 : **
958/103254 : ******
479/103254 : ***
1438/103254 : *********
719/103254 : ****
2158/103254 : **************
1079/103254 : *******
3238/103254 : *********************
1619/103254 : **********
4858/103254 : *******************************
2429/103254 : ***************
7288/103254 : ***********************************************
3644/103254 : ***********************
1822/103254 : ***********
911/103254 : *****
2734/103254 : *****************
1367/103254 : ********
4102/103254 : **************************
2051/103254 : *************
6154/103254 : ***************************************
3077/103254 : *******************
9232/103254 : ************************************************************
4616/103254 : ******************************
2308/103254 : ***************
1154/103254 : *******
577/103254 : ***
1732/103254 : ***********
866/103254 : *****
433/103254 : **
1300/103254 : ********
650/103254 : ****
325/103254 : **
976/103254 : ******
488/103254 : ***
244/103254 : *
122/103254 :
61/103254 :
184/103254 : *
92/103254 :
46/103254 :
23/103254 :
70/103254 :
35/103254 :
106/103254 :
53/103254 :
160/103254 : *
80/103254 :
40/103254 :
20/103254 :
10/103254 :
5/103254 :
16/103254 :
8/103254 :
4/103254 :
2/103254 :
1/103254 :
と、時計方向に 90 度回転したものができました。
まとめ
今回はサラリと流してみたいが、本来はこのグラフを転置させて同じような上下のバーグラフを描画したかったのだが、意外に難しいのとあまり本質ではないことから、ここで終わりとします。
コメント
{{comment multi|w}}