「ワンライナーで九九の表を生成する」というシェル芸の問題は、多くの解法が存在し非常にいい問題なのではないかと感じました。
そこで、自分が今思いつく答えをいくつかメモしておこうと思います(今回は細かいコマンドの使い方は紹介しておりません)
ぜひ自分で考えた後にご覧ください!
[目次]
基本二重ループ
まずはシンプルに、以下のような2重 for ループで実装します
$ for i in {1..9}; do (for j in {1..9}; \ do printf "%2d " $(($i*$j)); done); echo ; done 1 2 3 4 5 6 7 8 9 2 4 6 8 10 12 14 16 18 3 6 9 12 15 18 21 24 27 4 8 12 16 20 24 28 32 36 5 10 15 20 25 30 35 40 45 6 12 18 24 30 36 42 48 54 7 14 21 28 35 42 49 56 63 8 16 24 32 40 48 56 64 72 9 18 27 36 45 54 63 72 81
(cf) while ループの練習
$ i=1; while [ $i -ne 10 ]; \ do (j=1; while [ $j -ne 10 ]; \ do printf "%2d " $(($i*$j)); \ j=$(($j+1)); done); printf "\n"; \ i=$(($i+1)); done
AWK のみ
上と同じように2重ループで実装を、AWKのみでおこないます
awk 'BEGIN{for( i=1;i<=9;i++ ){for( j=1;j<=9;j++ ){printf "%2d ",i*j}print " "}}'
python ワンライナー
python のワンライナーについては、こちらもご覧ください
$ python -c "[print(f'{i*j:2}') if i == 9 else print(f'{i*j:2}', end=' ') for j in range(1,10) for i in range(1,10)]"
for ループを使わない
ここでは echo のブレース展開を用いて 9 * 9 の組み合わせを作り出します。
ブレース展開とは
基本的な使い方は以下のようになります
# 基本 $ echo {1..10} 1 2 3 4 5 6 7 8 9 10 $ echo {a..e} a b c d e # 普通の文字と組み合わせ $ echo hoge{1..3} hoge1 hoge2 hoge3 # 複数のブレース展開 $ echo {1..2}{a..c} 1a 1b 1c 2a 2b 2c $ echo {1..2}{1..3} 11 12 13 21 22 23 # 数字における 0 埋め $ echo {04..10} 04 05 06 07 08 09 10
そこで今回は、{1..9}{1..9}
というブレース展開により必要な組み合わせを作り、それをうまく利用するという作戦を取ります
# awk の種類・バージョンによってはうまくいかないかも echo {1..9}{1..9} | tr ' ' '\n' |\ awk -F '' '{printf"%2s\n",$1*$2}' |\ paste -d ' ' - - - - - - - - -
上の awk の部分を、下の例では
- sed(23 ⇨ 2*3と変換)
- bc(2*3 ⇨ 6と評価)
- printf(全数字を2桁で表示)
の3ステップで行っています。
echo {1..9}{1..9} | tr ' ' '\n' | \ sed -E 's@([0-9])([0-9])@\1*\2@g' | \ bc | xargs printf "%2d\n" | paste -d ' ' - - - - - - - - -
おわりに
「九九の問題を作る」ということ1つとっても色々な解法があり、それがシェル芸の面白さだと思います。
他にも面白そうな問題があればまた紹介していきます!