P40 (**) Goldbach's conjecture.
2より大きい偶数を引数に取り、和がその値になる二つの素数を返す関数(ゴールドバッハの予想)を書く。引数が2または奇数の場合nilを返すようにした。
そうでなければその値までの素数リストを作り、その
first
との和が引数の値と一致するものを探す。あればそれらの二値を返し、なければ素数リストの
rest
から再度探すように再帰する。「リストの中から条件に合致する最初の要素を返す」という処理を
(first (drop-while #(...) ...))
としてみたが、Haskellの
find
のようにもっと簡単に書く方法があっただろうか。user=> (my-goldbach 28) (5 23) user=> (my-goldbach 7) nil
P41 (**) A list of Goldbach compositions.
先ほど作ったゴールドバッハ関数を利用して、値の範囲を引数として渡し、その範囲内の偶数に対して和がその値になる二つの素数を返す関数を書く。
また、第三引数を与えた場合、二素数のどちらもその値以上となるもののみ返すようにする。
まず値の範囲を
range
で作り、map
でmy-goldbach
の結果となる値と元の値のペアを作る。my-goldbach
の結果がnilでないもの(引数が2と奇数の場合)と第三引数以上のもののみフィルタして返すようにした。my-goldbach
が返す素数の二値は昇順となっているのが分かっているため、比較には
(>= (first g) l)
のみ行えば条件に合致しているとみなしてよい。
user=> (my-goldbach-list 9 20) ((10 (3 7)) (12 (5 7)) (14 (3 11)) (16 (3 13)) (18 (5 13)) (20 (3 17))) user=> (my-goldbach-list 1 2000 50) ((992 (73 919)) (1382 (61 1321)) (1856 (67 1789)) (1928 (61 1867)))