Я пытаюсь реализовать следующую повторяющуюся последовательность шагов, но с ограниченным успехом:

   (*
      Foreach element in fifth do
      sum elements in second filtered by matching characters in first and
      subtract elements in fourth filtered by matching characters in third

      // For Example: [|"ABC"|] -> 44.0 = (13.0 + 17.0 + 19.0) - (2.0 + 3.0)
      // For Example: [|"ABD"|] -> 46.0 = (13.0 + 17.0 + 23.0) - (2.0 + 5.0)
      // For Example: [|"ABE"|] -> 51.0 = (13.0 + 17.0 + 29.0) - (3.0 + 5.0)
      // For Example: [|"ACD"|] -> 46.0 = (13.0 + 19.0 + 23.0) - (2.0 + 7.0)
      // For Example: [|"ACE"|] -> 51.0 = (13.0 + 19.0 + 29.0) - (3.0 + 7.0)
      // For Example: [|"ADE"|] -> 53.0 = (13.0 + 23.0 + 29.0) - (5.0 + 7.0)
      // For Example: [|"BCD"|] -> 46.0 = (17.0 + 19.0 + 23.0) - (2.0 + 11.0)
      // For Example: [|"BCE"|] -> 51.0 = (17.0 + 19.0 + 29.0) - (3.0 + 11.0)
      // For Example: [|"BDE"|] -> 53.0 = (17.0 + 23.0 + 29.0) - (5.0 + 11.0)
      // For Example: [|"CDE"|] -> 53.0 = (19.0 + 23.0 + 29.0) - (7.0 + 11.0)
   *)

Это более сложная версия проблемы, с которой мне недавно помог @xuanduc987.

module SOQN =

   open System

   let first  = [|"A"; "B"; "C"; "D"; "E"; "F"; "G"; "H"; "I"; "J"|]
   let second = [|13.0; 17.0; 19.0; 23.0; 29.0; 0.0; 0.0; 0.0; 0.0; 0.0|]
   let third  = [|"ABCD"; "ABCE"; "ABDE"; "ACDE"; "BCDE"|]
   let fourth = [|2.0; 3.0; 5.0; 7.0; 11.0|]
   let fifth  = [|"ABC"; "ABD"; "ABE"; "ACD"; "ACE"; "ADE"; "BCD"; "BCE"; "BDE"; "CDE"|]

   let sixth = 
      [[for i in [0..fifth.Length - 1] do
         yield (sumFunc second first fifth.[i] - 
                subtractFunc third fourth fifth.[i])]]


   // Expected Result:  Sixth:  [| 44.0; 46.0; 51.0; 46.0; 51.0; 53.0; 46.0; 51.0; 53.0; 53.0 |]
0
matekus 15 Дек 2017 в 11:25

1 ответ

Лучший ответ

Как насчет этого?

let sixth = 
    Array.init fifth.Length (fun i ->        
        let f a b (g:string->bool) =
            Seq.zip a b 
            |> Seq.filter (fun (e,_) -> g e)
            |> Seq.map snd
            |> Seq.sum
        let x = f first second (fun e -> fifth.[i].Contains(e))
        let y = f third fourth (fun e -> Seq.forall (fun x -> e.Contains(x)) (Seq.map string fifth.[i]))
        x - y)

Это дает мне:

[|44.0; 46.0; 51.0; 46.0; 51.0; 53.0; 46.0; 51.0; 53.0; 53.0|]

Вы сказали

фильтруется по совпадающим символам в третьем

Но я думаю, что его следует отфильтровать, сопоставив символы ИЗ третьего, иначе я не получу 44, как вы описали.

1
Gus 15 Дек 2017 в 15:14