Bashシェルで「1000 以下の回文素数で最大のものを示せ」を問いてみる

2023-03-27Bash

はじめに

前回のエントリ素数をワンライナーで求める というネタをやりました。

もともと、今日のエントリを解くための前置きだったのでした。
課題はこちらのサイトから拝借しました。

今日問いてみようと思っている内容は、タイトル通りなのですが、ちょっとわかりにくいので解説しておきます。

  • 回文数 : 逆さに読んでも内容が変わらない数。( 例 1、 11、 121 )
  • 回文素数 : 回文数であり、かつ素数。 ( 例 2、 11、 101 )

1000 以下回文素数 で最大のものを求めてみたいと思います。

検証環境

$ uname -moi
x86_64 x86_64 GNU/Linux

$ bash -version | head -n 1
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)

前回のおさらい : 素数を求めるワンライナー

1 から 1000 までの素数をワンライナーで列挙してみます。

$ factor {1..1000} | awk 'NF==2 { print $2 }'
2
3
5
7
11
(省略)
971
977
983
991
997

解説は前回のエントリを参照ください。シェルなら簡単ですね。

素数の内、回文であるもののみを出力する

素数がわかったので、この内回文のみを抽出してみます。

ここからはいい方法が思い浮かばなかったので、地道にループ処理を記述してみます。

  1. while コマンドで読み込む
  2. REPLY という変数に格納されるため、読み込んだ文字列 $REPLY と 順序を rev でじっくり返した値を比較
  3. 等しかったら echo で出力する

実行結果は以下のとおりです。

$ factor {1..1000} | awk 'NF==2 { print $2 }' | while read -r; do [[ $REPLY == $(echo $REPLY | rev) ]] && echo $REPLY; done
2
3
5
7
11
101
131
151
181
191
313
353
373
383
727
757
787
797
919
929

最期の1行だけを出力

後は最期の1行だけが欲しいため、 tail -n 1 でフィルタします。

$ factor {1..1000} | awk 'NF==2 { print $2 }' | while read -r; do [[ $REPLY == $(echo $REPLY | rev) ]] && echo $REPLY; done | tail -n 1
929

ひとこと

昔はこれをGroovyという言語でときました。
いつの間にかシェルが指に馴染む人間になってしまった。

2023-03-27Bash