2017-12-02 10 views
0

私は一連のコード化の課題に取り組んでいます。その一環として、リスト内の2つの数字を均等に割り切れるものにする必要があります。この基準を満たす数字は1セットだけです。別の番号で完全に割り切れる順序で最初の番号を検索

これは私が今持っている機能

let spreadsheet (s: string) = 
    s.Split([|"\r\n"|], StringSplitOptions.RemoveEmptyEntries) 
    |> Seq.map (fun(d: string) -> d.Split([|' '|], StringSplitOptions.RemoveEmptyEntries) |> Seq.map Int32.Parse) 

let fourthChallenge() = 
    // In the real code, this reads from a file. That part works fine though. 
    let input = spreadsheet "5 9 2 8\r\n9 4 7 3\r\n3 8 6 5" 
    let firstEvenlyDivisable number data = data |> Seq.collect /number |> Seq.find (fun x -> box x :? int) 
    let rowChecksums = input |> Seq.map (fun (row: seq<int>) -> Seq.iteri (fun i n -> firstEvenlyDivisable n (Seq.skip i row))) 
    Seq.sum rowChecksums 

である私が今抱えている問題は、firstEvenlyDivisableは、私が期待するseq<int> -> unitの代わりseq<int> -> intのようだということです。

データがSeq.collect /numberから出るときは、seq<unit>と思われますが、なぜその理由がわかりません。

+0

問題の追跡に役立つようにタイプ注釈を追加することをおすすめします。 – Foole

+0

@Foole Yup、 'iteri'はシーケンスを返しません。私は完全にそれと思った。私は実際に 'mapi'が必要でした。 –

答えて

1

問題は、Seq.iteriが生成されたシーケンスを返さないということです。プロジェクト関数が実行された後にシーケンスを返すには、mapiが必要です。

Seq.mapiの第2引数として明示的にrowを渡す必要があります。

これはコードの動作バージョンです。

let fourthChallenge() = 
    let input = spreadsheet (readChallengeInput 3) 
    let firstEvenlyDivisable number (data: seq<int>) = data |> Seq.map (fun (i: int) -> i/number) |> Seq.find (fun x -> box x :? int) 
    let rowChecksums = input |> Seq.collect (fun (row: seq<int>) -> Seq.mapi (fun i n -> firstEvenlyDivisable n (Seq.skip i row)) row) 
    Seq.sum rowChecksums 
関連する問題