はじめに
この記事は以下の記事の続きです。
Project EulerでF#の勉強をしました
(Problem1~3編)
(Problem4~5編)
手元でしか動かしていないので、間違いがあったら指摘を頂けると喜びます。
Problem 6
最初の10個の自然数について, その二乗の和は,
1^2 + 2^2 + ... + 10^2 = 385
最初の10個の自然数について, その和の二乗は,
(1 + 2 + ... + 10)^2 = 3025
これらの数の差は 3025 - 385 = 2640 となる.
同様にして, x最初の100個の自然数について二乗の和と和の二乗の差を求めよ.
let target = [1..100]
let Problem6 =
(pown (List.sum target) 2) //和の二乗
- ((List.map (fun x -> (pown x 2)) target) |> List.sum) //二乗の和
//val Problem6 : int = 25164150
突然明らかに難易度が下がりましたね・・・あまり言うことがない・・・。
ところで投稿用にコードをまとめる際、
自作関数を使うのをやめてmapとsumを重ねたらVSCodeのリファクタリング機能にツッコミを入れられました。
(List.sumBy (fun x -> (pown x 2)) target) //二乗の和
こうとも書けるみたいですね。「各要素に処理したやつ足し合わせるで」ということらしい。
やはりメソッドを覚えなければなりませんね・・・。メソッドとか言うと怒られそう。
Problem 7
素数を小さい方から6つ並べると 2, 3, 5, 7, 11, 13 であり, 6番目の素数は 13 である.
10 001 番目の素数を求めよ.
let target = 10001
let makePrimeListFromLength maxLen =
let rec inMakePrimeListFromLength (pList:int list) x = //primeList,判定対象x
match pList.Length with
| n when n = maxLen -> pList
| _ ->
if List.forall (fun y ->(x % y) <> 0) pList then
inMakePrimeListFromLength (pList@[x]) (x+1)
else
inMakePrimeListFromLength pList (x+1)
inMakePrimeListFromLength [2] 3
let Problem7 = makePrimeListFromLength target |> List.item(target-1)
//val Problem7 : int = 104743
要素数のほうから素数リストを求めました。(makePrimeListFromLength)
ロジック的にはそれほど大した事はないと思います。if分岐らへんがエラトステネスの篩です。
この問題を解いている最中に知ったんですが、
Listでも配列みたいにアクセスする方法(item)が備え付けで存在するんですね。(ただし当然ながら計算量は異なる)
それから書き方の話題ですが、letしたリストのプロパティにアクセスする場合、
let hogelist = [1..100]
hogelist.Item 50
hogelist |> List.item(50)
どちらのほうが好ましいんだろうなあ、とか。(今回でいうと4行目のLengthと最終行のitem)
List.itemの方が関数型的か・・・? という気はします。hogelist.Itemの方はインスタンス的な生え方に見える。
あと、例を挙げるに当たって今気づきましたが、sumとかはList.sumしか無いみたいですね。
有識者の方がおられましたらご意見を汲みたいところです。個人的には後者を使いそうです。長いけど。
おわり
以上です。小出しですみません。(Problem8がやたらゴツい)
Problem10まで続きます。(投稿したらリンクを貼りに来ます。→来ました)
(Problem6~7編)
(Problem8~10編)
ご指導してくださる方がいらっしゃれば、よろしくお願い致します。