しりとりをする

いちばん長いしりとり どう書く?org にインスパイヤされて awk でしりとりをさせてみます。 この URL のお題では「一番長いしりとり」ですが、普通にしりとりを行います。

「ん」で終わるか単語の候補がなくなるまでしりとりを行うため、再帰的に処理を行っています。

単語の一覧は以下のようにして準備しました。

$ wget http://www.ais.riec.tohoku.ac.jp/lab/wordlist/fam55_40.txt

$ nkf -w --overwrite fam55_40.txt

コードは以下のとおりですが、日本語を含む処理があるため、gawk 系のみの対応です。

#! /usr/local/bin/gawk -f
# shiritori.awk
# しりとりをします
# usage: gawk -f shiritori.awk file[s]

{
    for (i = 1; i <= NF; i++) {
        word[num++] = $i;
    }
}

END {
    srand();
    init = int(rand() * num) + 1;
    shiritori(word[init]);
}

# shiritori():  しりとりの結果を返す
#   in:     文字列 (str)
function shiritori(str,     start_char, end_char, new_str, is_found, i) {
    is_found = 0;
    start_char = substr(str, 1, 1);
    end_char   = substr(str, length(str), 1);
    printf("%s -> ", str);
    for (i in word) {
        if (word[i] == str) {
            word[i] = word[i] "_used";
        }
    }
    for (i in word) {
        if (substr(word[i], 1, 1) == end_char &&
            word[i] !~ /_used$/) {
            new_str = word[i];
            is_found = 1;
            printf("%s\n", new_str);
            break;
        }
    }
    if (is_found == 0) {
        print "";
        exit;
    } else {
        shiritori(new_str);
    }
}

実際にしりとりをさせてみましょう。

$ gawk -f shiritori.awk fam55_40.txt
ウワバリ -> リンカイ
リンカイ -> イキハジ
イキハジ -> ジュズダマ
ジュズダマ -> マヤカシ
マヤカシ -> シキリヤ
シキリヤ -> ヤマバト
ヤマバト -> トオボエ
トオボエ -> エリグリ
エリグリ -> リンカン
リンカン -> 

このようにしりとりができます。

tag_gawk.pngtag_gawk.png