BBS-BBS/48

トップ 差分 一覧 Farm ソース 検索 ヘルプ RSS ログイン

キミならどう書く 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}}