ONLY DO WHAT ONLY YOU CAN DO

こけたら立ちなはれ 立ったら歩きなはれ

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 = ()