F#Codewars整数:娱乐二

时间:2019-06-10 22:15:53

标签: f#

尝试用

解决task

代码

open System

let rec distribute e = function
  | [] -> [[e]]
  | x::xs' as xs -> (e::xs)::[for xs in distribute e xs' -> x::xs]

let rec permute = function
  | [] -> [[]]
  | e::xs -> List.collect (distribute e) (permute xs)

let MoreRule (a: int) (b: int) (c: int) (d: int) = 
    let permutations = permute [a;b;c;d]
    let sums = permutations |> List.map(fun x -> x.[0]*x.[1] + x.[2]*x.[3])
    let diffs = permutations |> List.map(fun x -> x.[0]*x.[1] - x.[2]*x.[3])
    List.append sums diffs
    |> List.distinct
    |> List.filter(fun x -> x>0)
    |> List.sort

let factor number list = [
    for i in list do 
        let t = Math.Floor(Math.Sqrt((number-Math.Pow((float)i,2.0)))) |> int
        if (List.exists ((=)t) list) then 
            yield [|i;t|]
    ]

let prod2Sum (a: int) (b: int) (c: int) (d: int): int[] list = 
    let number = (float)(((a*a)+(b*b))*((c*c)+(d*d)))   
    let coefficients = MoreRule a b c d
    factor number coefficients
    |> List.map(fun arr -> if (arr.[0]>arr.[1]) then [|arr.[1];arr.[0]|] else [|arr.[0];arr.[1]|])
    |> List.distinct

单击页面上的“临时”按钮时,我会收到响应退出代码失败1

  

预期:[[| 75; 104 |]; [| 85; 96 |]]实际:[]

但是在我的本地PC prod2Sum 4 5 20 1上返回正确的结果[[|75; 104|]; [|85; 96|]]

主要问题是我在做什么错?如何改进此代码?谢谢!

1 个答案:

答案 0 :(得分:2)

我不完全知道您的代码出了什么问题-为了解决这个问题,您可能需要更多地解释它应该如何工作-但我能够复制代码失败的情况。如果您按以下方式运行prod2Sum函数,则它将返回一个空列表:

prod2Sum 1 20 -4 -5

CodeWars的预期结果是[[|75; 104|]; [|85; 96|]]。我没有弄清楚您的代码如何尝试解决该问题,但是一些实验表明,负值在MoreRule中被以下行过滤掉:

|> List.filter(fun x -> x > 0)

消除此错误并不完全有效-我得到了正确的数字,但有些数字是负数。在此示例中,用List.map abs代替它,但是对于其他一些输入则失败。

为便于记录,找出问题所在的简便方法是在prod2Sum函数中添加一些日志记录:

let prod2Sum (a: int) (b: int) (c: int) (d: int): int[] list = 
    let number = (float)(((a*a)+(b*b))*((c*c)+(d*d)))   
    let coefficients = MoreRule a b c d
    let res = 
        factor number coefficients
        |> List.map(fun arr -> if (arr.[0]>arr.[1]) then [|arr.[1];arr.[0]|] else [|arr.[0];arr.[1]|])
        |> List.distinct
    if res = [] then 
        printfn "%A" (a,b,c,d) // Log inputs for which we returned wrong result
    r

有了这个,您应该能够找出其他失败的测试用例。