プログラミングAWK 演習問題3-6

3-5 で横方向の調整をしたので、今度は縦方向の調整に挑戦。

2008-01-07追記

100 だけ例外扱いになっちゃうけど、こんな感じかな。

BEGIN{
    width=50
    hight=15
}

{
    x[int($1/(100/hight))]++
    if ( max < x[int($1/(100/hight))] )
        max = x[int($1/(100/hight))]
}

END {
    for ( i=0; i<hight; i++)
        printf(" %2d - %2d: %2d %s\n", i*(100/hight), (i+1)*(100/hight)-1, x[i], rep(x[i]*width/max, "*"))
    printf("100     : %2d %s\n", x[hight], rep(x[hight]*width/max, "*"))
}

function rep (n,s,  t){
    while ( n-- > 0)
        t = t s
    return t
}

解答では、具体的には書かれていないけど、データを 2 回読んで、まず範囲を決めてから割り振りし直す、ような処理が想定されてる。

上のだと、データの範囲を例題と同じで 0-100 に決めうちしてるんだけど、これに柔軟に対処しろってこと?

BEGIN{
    max_input=0
    max_width=50
    width=0
    bucket=12
}

{
    x[NR]=$1
    if ( max_input < x[NR] )
        max_input = x[NR]
}

END {
    for ( i=0; i<NR; i++){
      y[int(x[i]/(max_input/bucket))]++
      if (width < y[int(x[i]/(max_input/bucket))] )
          width = y[int(x[i]/(max_input/bucket))]
    }
    for ( i=0; i<bucket; i++)
        printf(" %2d - %2d: %2d %s\n", i*(max_input/bucket), (i+1)*(max_input/bucket)-1, y[i], rep(y[i]*max_width/width, "*"))
    printf("%3d     : %2d %s\n", max_input, y[bucket], rep(y[bucket]*max_width/width, "*"))
}

function rep (n,s,  t){
    while ( n-- > 0)
        t = t s
    return t
}

これでどうか。最大の数値だけルール外れるのが気持ち悪いけど、元のサンプルがこうだしなぁ。