文字列で十字を表示する

文字列で+を表示する DouKaku? にインスパイヤされて、awk で作ってみました。

この「十字」にこだわるつもりはなかったので、後で何か使えそうな部分は関数化をしてみました。 また、エスケープシーケンスで文字を配置しています。

#! /usr/local/bin/nawk -f
# cross.awk
# 十字に文字を並べる
# usage: nawk -f cross.awk str

BEGIN {
    str = ARGV[1];

    clear();

    print_str_at(str,          1 * length(str) + 1, 1,                   "h");
    print_str_at(rev_str(str), 1 * length(str) + 2, 1,                   "v");
    print_str_at(str,          2 * length(str) + 2, 0,                   "v");
    print_str_at(str,          1,                   1 * length(str) + 1, "h");
    print_str_at(str,          2 * length(str) + 1, 1 * length(str) + 1, "h");
    print_str_at(rev_str(str), 2,                   1 * length(str) + 1, "v");
    print_str_at(str,          3 * length(str) + 2, 1 * length(str),     "v");
    print_str_at(rev_str(str), 2,                   2 * length(str) + 1, "h");
    print_str_at(rev_str(str), 2 * length(str) + 2, 2 * length(str) + 1, "h");
    print_str_at(rev_str(str), 1 * length(str) + 2, 2 * length(str) + 1, "v");
    print_str_at(str,          2 * length(str) + 2, 2 * length(str),     "v");
    print_str_at(rev_str(str), 1 * length(str) + 2, 3 * length(str) + 1, "h");
}

# rev_str():    文字列を逆順で表示する
#   in:     文字列 str
#   out:    文字列 str の逆順文字列
function rev_str(str,    i, ret_str) {
    for (i = length(str); i >= 1; i--) {
        ret_str = ret_str substr(str, i, 1);
    }

    return ret_str;
}

# print_str_at():   文字列を特定の場所から縦または横に表示する
#   in:     文字列 str
#           初期座標 init_x, init_y
#           方向 dir ("v" or "h")
function print_str_at(str, init_x, init_y, dir,    i, j) {
    if (dir == "h") {
        for (i = init_x; i <= length(str) + init_x; i++) {
            print_at(substr(str, ++j, 1), init_x + j, init_y);
        }
    }

    if (dir == "v") {
        for (i = init_y; i <= length(str) + init_y; i++) {
            print_at(substr(str, ++j, 1), init_x, init_y + j);
        }
    }
}

# clear():  画面をクリアする
function clear() {
    printf("\033[H\033[2J");
}

# print_at():   文字を特定の座標に表示する
#   in:     文字列 str
#           座標 x, y (左上が 0, 0)
function print_at(str, x, y) {
    printf("\033[%d;%dH%s\n", y, x, str);
}

本問題に特化するのであれば、時計回りに右・右・左の順で 13 個連接したものを折り曲げれば良いのでしょうが、多分後で見ると何をやるプログラムだったか分からなくなってしまいそうです。

実行してみます。

$ nawk -f cross.awk 1
  11
 1111
 1111
  11

$ nawk -f cross.awk 12
   121
   2 2
 121 121
 2     2
 121 121
   2 2
   121

$ nawk -f cross.awk 'sed&awk'
        sed&awks
        k      e
        w      d
        a      &
        &      a
        d      w
        e      k
 sed&awks      sed&awks
 k                    e
 w                    d
 a                    &
 &                    a
 d                    w
 e                    k
 skwa&des      skwa&des
        k      e
        w      d
        a      &
        &      a
        d      w
        e      k
        skwa&des

tag_nawk.png tag_nawk.png tag_nawk.png tag_nawk.png