076 C - たくさんの数式

解説

文字列がもっと長いと気になってはくるものの, (末尾再帰ではない)再帰でさっと書いてしまえばいいでしょう. HaskellではfoldMなどで豪快な処理が書けるものの, (今の私のF#の腕前では)シンプルな移植ができないのも理由の一つです.

計算用の再帰関数は次のように実装できます.

1
2
3
  let rec frec a y = function
    | [] -> a+y
    | x::xs -> frec (a+y) x xs + frec a (y*10L + x) xs

入力の文字列を一桁数値のリストに変換する処理は次のように書けます.

1
  let ys = S |> Seq.map (fun c -> int64 c - int64 '0') |> Seq.toList

ここで1を単にint64 cだけにすると49Lが返ってきてはまり倒します. 上のようにint64 '0'を引いて整数として1Lが返るようにするか, c |> string |> int64のように文字列にしてからint64を通しましょう. 例を見るとわかるようにInt32の範囲を飛び越えるため, オーバーフロー対策でInt64を使うのは必須です.

その他

逐次計算していくのではなく, いったん文字列から必要な数を切り出す(ベキ集合を作る)タイプの実装でHaskellコードを見ると, replicateMを使ってブーリアンのベキ集合を使ってどの文字を取ってくるか判定しています. Reference.fsxreplicateMベキ集合で検索すれば対応する関数のリスト版実装があります. これを参考にHaskellコードの移植を考えてもいいでしょう.