行のシャッフル
行のシャッフル - みずぴー日記にインスパイヤされているわけですが、ほぼ同時に同じようなネタを考えていました。 それは、あまり料理のレパートリーのない人がうまくごまかすために自分の作れる料理をシャッフルすることで偏ることなく料理を作れるのではないかということを考えていました。
さて、とりあえずシャッフルを行う関数ですが、今までに何度も出てきていますので、スクリプト自体は見慣れたものになっています。
#! /usr/local/bin/nawk -f
# shuffle_lines.awk
# 行をシャッフルする
# usage: nawk -f shuffle_lines.awk file[s]
{
line[NR] = $0;
}
END {
shuffle_array(line);
for (i = 1; i <= NR; i++) {
print line[i];
}
}
# 配列をシャッフルする
# in: 配列
# out: 元々の配列をシャフルされた配列に置換する
function shuffle_array(arr, num_arr, tmp, a, i, j) {
srand();
for (a in arr) {
num_arr++;
}
for (i = num_arr; i >= 1; i--) {
j = int((i + 1) * rand());
if (j == 0) {
j = 1;
}
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
seq コマンドで試してみましょう。
$ seq 10 | nawk -f shuffle_lines.awk 8 4 1 3 2 7 9 5 6 10
ここで以下のようなファイルを用意して、シャッフルをすると飽きのこない献立ができあがります。
$ cat dishes.txt カレーライス ハヤシライス パスタ 生姜焼き ラーメン おでん すき焼き 焼肉 麻婆豆腐 青椒肉糸 回鍋肉 肉野菜炒め 焼き魚 お刺身 $ nawk -f shuffle_lines.awk dishes.txt ハヤシライス パスタ 回鍋肉 肉野菜炒め すき焼き お刺身 おでん カレーライス 青椒肉糸 焼肉 ラーメン 焼き魚 生姜焼き 麻婆豆腐
そういえば、インスパイヤ元が一行野郎で書かれているので、awk でも一行野郎でシャッフルしてみます。
$ nawk '{a[NR]=$0}END{for(i in a)print a[i]}' dishes.txt
ハヤシライス
パスタ
生姜焼き
ラーメン
おでん
すき焼き
焼肉
麻婆豆腐
青椒肉糸
回鍋肉
肉野菜炒め
焼き魚
お刺身
カレーライス
awk の配列は連想配列で、呼び出す際にはインデックス順にならないため、それなりにシャッフルされるはずなのですが、あまりシャッフルされていませんでした。 残念。




