2

F# では、 game: (int*int) list minx、maxx、miny、maxy の各タプル ディメンションの最小値と最大値を計算したいと考えています。

このコードは機能しますが、少しぎこちないようです。

let minX (game: (int*int) list) =  game |> List.map (fun (x,y) -> x) |> Seq.min 
let maxX (game: (int*int) list) =  game |> List.map (fun (x,y) -> x) |> Seq.max 
let minY (game: (int*int) list) =  game |> List.map (fun (x,y) -> y) |> Seq.min 
let maxY (game: (int*int) list) =  game |> List.map (fun (x,y) -> y) |> Seq.max 

改善のヒントはありますか?

4

4 に答える 4

7
let minX game = List.minBy fst game |> fst
let maxX game = List.maxBy fst game |> fst
let minY game = List.minBy snd game |> snd
let maxY game = List.maxBy snd game |> snd
于 2012-11-26T10:41:19.633 に答える
5

ジョンのようですが、読みやすいです:

let game = [(1,4);(2,1)]
let minx, miny, maxx, maxy =
    let folder (mx,my,Mx,My) (ax,ay) = min mx ax, min my ay, max Mx ax, max My ay
    ((Int32.MaxValue, Int32.MaxValue, Int32.MinValue, Int32.MinValue), game) ||> List.fold folder
于 2012-11-26T12:21:49.903 に答える
3

あなたが持っているものを改善するために行うことができるいくつかの小さな変更があります:

  1. Seq.mapの代わりに使用List.mapして、新しいリストの作成を回避し、メモリ使用量を一定に保ちます
  2. ラムダの代わりに組み込みのfst/関数を使用するsnd
  3. game関数合成を使用してコードをより簡潔にすることができる唯一の引数であるため

最終的には次のようになります。

let minX = Seq.map fst >> Seq.min
let maxX = Seq.map fst >> Seq.max
let minY = Seq.map snd >> Seq.min
let maxY = Seq.map snd >> Seq.max

興味深いことに、これはパッドのソリューションよりもかなり高速であることがわかりました。10M 要素の場合、0.28 秒対 1.75 秒です。

于 2012-11-26T16:53:40.813 に答える
2

パッドの回答の折りたたみバージョン (1 つのリスト トラバーサルのみ)

let minx,miny,maxx,maxy =game |> List.fold (fun (mx,my,Mx,My) (ax,ay) -> 
    let nmx,nMx = if ax<mx then ax,Mx else if ax > Mx then mx,ax else mx,Mx
    let nmy,nMy = if ay<my then ay,My else if ay > My then my,ay else my,My
    nmx,nmy,nMx,nMy) (Int32.MaxValue,Int32.MaxValue,Int32.MinValue,Int32.MinValue)
于 2012-11-26T11:04:53.763 に答える