Project Euler 36

http://projecteuler.net/index.php?section=problems&id=36


10進の回文数再帰的に出して、2進で回文数になるかを調べます。

パイプライン処理というのを使ってみました。例えば、数字のリストがあってリストを逆にして10進数にする処理というのは通常、

let to_number a = List.fold (fun x y -> x * 10 + y) 0 a
printfn "%d" (to_number (List.rev [1; 2; 3]))       // 321

こうですが、

printfn "%d" ([1; 2; 3] |> List.rev |> to_number)   // 321

とも書けます。データの流れが左から右になっています。
以前、Haskellに対する批判で思考の順序と書き方が逆、というのをどこかで見ました。そのような批判に対する答えがこれなのでしょうか。
ただ、これは単に慣れの問題のような気がします。Project Eulerでよく「〜の和を求めよ」という問題がありますが(この問題もそうでしたね)、Haskellだと、

sum (...)

と書きます。F#のパイプライン処理だと、

... |> Seq.sum

と「〜の和」というのと順序が一致しますね。
しかし、英語では「Find the sum of ...」となります。Haskellの順序ですね。思考の順序は人それぞれで、必ずしもパイプライン処理が自然というわけではないと思います。

let N = 6

let rec pow n e = if e = 0 then 1 else n * (pow n (e - 1))

let rec palindrome n zero_leading =
   if n = 1 then
      if zero_leading then seq { 0..9 } else seq { 1..9 }
   else if n = 2 then
      if zero_leading then seq { 0..11..99 } else seq { 11..11..99 }
   else
      let d = (pow 10 (n - 1)) + 1
      seq {
         for p in palindrome (n - 2) true do
            for q in d..d..d*9 -> p * 10 + q
      }

let rec binary n = if n = 0 then [] else (binary (n >>> 1)) @ [n &&& 1]
let to_number a = List.fold (fun x y -> x * 2 + y) 0 a
let is_palindromic_bin n =
   n = (n |> binary |> List.rev |> to_number)

let s = seq { for n in 1..N do for m in palindrome n false -> m }
printfn "%d" (Seq.sum (Seq.filter is_palindromic_bin s))