F# で Project Euler Problem 4 その3
昨日の続き
いげ太氏から、「Scala で言う flatMap 相当が、F# では collect として定義されていますので、List.collect id で平坦化できますよ。」
とコメントを頂いたので使ってみる。
> [1..9] - |> List.map(fun i -> [i..9] |> List.map(fun j -> (i, j))) - ;; val it : (int * int) list list = [[(1, 1); (1, 2); (1, 3); (1, 4); (1, 5); (1, 6); (1, 7); (1, 8); (1, 9)]; [(2, 2); (2, 3); (2, 4); (2, 5); (2, 6); (2, 7); (2, 8); (2, 9)]; [(3, 3); (3, 4); (3, 5); (3, 6); (3, 7); (3, 8); (3, 9)]; [(4, 4); (4, 5); (4, 6); (4, 7); (4, 8); (4, 9)]; [(5, 5); (5, 6); (5, 7); (5, 8); (5, 9)]; [(6, 6); (6, 7); (6, 8); (6, 9)]; [(7, 7); (7, 8); (7, 9)]; [(8, 8); (8, 9)]; [(9, 9)]]
> - [1..9] - |> List.map(fun i -> [i..9] |> List.map(fun j -> (i, j))) - |> List.collect id - ;; val it : (int * int) list = [(1, 1); (1, 2); (1, 3); (1, 4); (1, 5); (1, 6); (1, 7); (1, 8); (1, 9); (2, 2); (2, 3); (2, 4); (2, 5); (2, 6); (2, 7); (2, 8); (2, 9); (3, 3); (3, 4); (3, 5); (3, 6); (3, 7); (3, 8); (3, 9); (4, 4); (4, 5); (4, 6); (4, 7); (4, 8); (4, 9); (5, 5); (5, 6); (5, 7); (5, 8); (5, 9); (6, 6); (6, 7); (6, 8); (6, 9); (7, 7); (7, 8); (7, 9); (8, 8); (8, 9); (9, 9)]
> - [10..99] - |> List.map(fun i -> [i..99] |> List.map(fun j -> (i, j))) - |> List.collect id - |> List.filter(fun (i, j) -> i % 11 = 0 || j % 11 = 0) - ;; val it : (int * int) list = [(10, 11); (10, 22); (10, 33); (10, 44); (10, 55); (10, 66); (10, 77); (10, 88); (10, 99); (11, 11); (11, 12); (11, 13); (11, 14); (11, 15); (11, 16); (11, 17); (11, 18); (11, 19); (11, 20); (11, 21); (11, 22); (11, 23); (11, 24); (11, 25); (11, 26); (11, 27); (11, 28); (11, 29); (11, 30); (11, 31); (11, 32); (11, 33); (11, 34); (11, 35); (11, 36); (11, 37); (11, 38); (11, 39); (11, 40); (11, 41); (11, 42); (11, 43); (11, 44); (11, 45); (11, 46); (11, 47); (11, 48); (11, 49); (11, 50); (11, 51); (11, 52); (11, 53); (11, 54); (11, 55); (11, 56); (11, 57); (11, 58); (11, 59); (11, 60); (11, 61); (11, 62); (11, 63); (11, 64); (11, 65); (11, 66); (11, 67); (11, 68); (11, 69); (11, 70); (11, 71); (11, 72); (11, 73); (11, 74); (11, 75); (11, 76); (11, 77); (11, 78); (11, 79); (11, 80); (11, 81); (11, 82); (11, 83); (11, 84); (11, 85); (11, 86); (11, 87); (11, 88); (11, 89); (11, 90); (11, 91); (11, 92); (11, 93); (11, 94); (11, 95); (11, 96); (11, 97); (11, 98); (11, 99); (12, 22); (12, 33); ...]
> - [10..99] - |> List.map(fun i -> [i..99] |> List.map(fun j -> (i, j))) - |> List.collect id - |> List.filter(fun (i, j) -> i % 11 = 0 || j % 11 = 0) - |> List.map(fun (i, j) -> i * j) - ;; val it : int list = [110; 220; 330; 440; 550; 660; 770; 880; 990; 121; 132; 143; 154; 165; 176; 187; 198; 209; 220; 231; 242; 253; 264; 275; 286; 297; 308; 319; 330; 341; 352; 363; 374; 385; 396; 407; 418; 429; 440; 451; 462; 473; 484; 495; 506; 517; 528; 539; 550; 561; 572; 583; 594; 605; 616; 627; 638; 649; 660; 671; 682; 693; 704; 715; 726; 737; 748; 759; 770; 781; 792; 803; 814; 825; 836; 847; 858; 869; 880; 891; 902; 913; 924; 935; 946; 957; 968; 979; 990; 1001; 1012; 1023; 1034; 1045; 1056; 1067; 1078; 1089; 264; 396; ...]
> - [10..99] - |> List.map(fun i -> [i..99] |> List.map(fun j -> (i, j))) - |> List.collect id - |> List.filter(fun (i, j) -> i % 11 = 0 || j % 11 = 0) - |> List.map(fun (i, j) -> i * j) - |> List.filter(fun n -> n.ToString().ToCharArray() = Array.rev(n.ToString().ToCharArray())) - ;; val it : int list = [121; 242; 363; 484; 616; 737; 858; 979; 1001; 858; 1001; 616; 1881; 484; 616; 858; 2002; 2112; 1771; 2112; 858; 2002; 2772; 2552; 2112; 1221; 1551; 1881; 2112; 2442; 2772; 3003; 2992; 2772; 2442; 3663; 3003; 2772; 2112; 2332; 2552; 2772; 2992; 4004; 4224; 4554; 4224; 3773; 4004; 4664; 5005; 5115; 5225; 5335; 5445; 4774; 4224; 6336; 5005; 4554; 4884; 6006; 6336; 6336; 7227; 5775; 6006; 6776; 7007; 8118; 8008; 8448; 9009]
> - [10..99] - |> List.map(fun i -> [i..99] |> List.map(fun j -> (i, j))) - |> List.collect id - |> List.filter(fun (i, j) -> i % 11 = 0 || j % 11 = 0) - |> List.map(fun (i, j) -> i * j) - |> List.filter(fun n -> n.ToString().ToCharArray() = Array.rev(n.ToString().ToCharArray())) - |> List.max - ;; val it : int = 9009
> - [100..999] - |> List.map(fun i -> [i..999] |> List.map(fun j -> (i, j))) - |> List.collect id - |> List.filter(fun (i, j) -> i % 11 = 0 || j % 11 = 0) - |> List.map(fun (i, j) -> i * j) - |> List.filter(fun n -> n.ToString().ToCharArray() = Array.rev(n.ToString().ToCharArray())) - |> List.max - ;; val it : int = 906609
VBScript版と同様なロジックでも実装してみる
F#には break がないので苦労したが、こちらの記事を参考にさせていただいた。
> exception ForBreak of int;; exception ForBreak of int > try - for i in [99.. -1..10] do - for j in [0..1] do - let mutable x = i - let mutable y = i - j - let mutable f = true - while f do - if (x % 11 = 0 || y % 11 = 0 ) then - let n = x * y - let a = n.ToString().ToCharArray() - if Array.rev(a) = a then - printf "%d * %d = %d\n" x y n - raise (ForBreak 0) - x <- x + 1 - y <- y - 1 - if x > 99 then f <- false - with _ -> () - ;; 99 * 91 = 9009 val it : unit = ()
> try - for i in [999.. -1..100] do - for j in [0..1] do - let mutable x = i - let mutable y = i - j - let mutable f = true - while f do - if (x % 11 = 0 || y % 11 = 0 ) then - let n = x * y - let a = n.ToString().ToCharArray() - if Array.rev(a) = a then - printf "%d * %d = %d\n" x y n - raise (ForBreak 0) - x <- x + 1 - y <- y - 1 - if x > 999 then f <- false - with _ -> () - ;; 993 * 913 = 906609 val it : unit = ()