はじめに
@gin_135 さんの「Project Eulerをシェル芸で解いてみる」シリーズが大変面白いです.
大抵は @gin_135 さんの Qiita 投稿, @eban さんの別解 on ブログ, @MasWag さんの別解 on Twitter を楽しく読ませていただき, 読んだだけで分からないものは, 手元で再現などして楽しんでいますが, 方針として大きく異なる別解を思いついたものについて, 自分のエントリを立てようと思います.
「Project Euler」の解説, 問題文の引用などは省略します.
本エントリは Problem 1 (問題原文, 問題文日本語訳) の解答です.
方針
他の問題 (Project Euler のというだけでなく, 現実の) にも共通で使える汎用演算について, 別途スクリプトを用意し, これをパイプで繋げます.
本題は, 数列に対し 3 または 5 の倍数を「濾過」し, 和算で「畳み込み」すれば良いので,
濾過スクリプトと左畳み込みスクリプトを用意します.
濾過
# !/bin/sh
f=$1
while read line
do
set "$line"
if `eval $f`
then
echo $line
fi
done
を filter
として保存し, PATH に含まれるディレクトリに保存 (または保存したディレクトリを PATH に追加), 実行パーミションを与えてあるとします.
解説は「濾過 in シェル」にあります.
左畳み込み
# !/bin/sh
f=$1
i=$2
if [ "X$i" = "X" ]
then
read i
fi
while read line
do
set "$i" "$line"
i=`eval $f`
done
echo $i
を reduce
として保存し, PATH に含まれるディレクトリに保存 (または保存したディレクトリを PATH に追加), 実行パーミションを与えてあるとします.
解説は「左畳み込み in シェル」にあります.
例題解答
10未満の自然数のうち, 3 か 5 の倍数 (3 か 5 で割り切れる) 数の合計は 23 になります.
$ seq 9 | filter '[ `expr $1 % 3` -eq 0 -o `expr $1 % 5` -eq 0 ]' | reduce 'expr $1 + $2'
23
本題解答
例題同様
$ seq 999 | filter '[ `expr $1 % 3` -eq 0 -o `expr $1 % 5` -eq 0 ]' | reduce 'expr $1 + $2'
とします.
参考
@gin_135 さんの解答「Project Eulerをシェル芸で解いてみる(Problem 1)」
@eban さんの解答「Project Euler Problem 1 #シェル芸 - jarp」