F # Codewars Integers: отдых два - PullRequest
1 голос
/ 11 июня 2019

Пытаясь решить задачу с помощью

кода

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 |]] Факт: []

Но на моем локальном ПК prod2Sum 4 5 20 1 возвращает правильный результат [[|75; 104|]; [|85; 96|]]

Главный вопрос, что я делаю неправильно?Как улучшить этот код?Спасибо!

1 Ответ

2 голосов
/ 11 июня 2019

Я точно не знаю, что не так с вашим кодом - чтобы помочь с этим, вам, вероятно, нужно объяснить больше о том, как он должен работать, - но я смог воспроизвести случай, для которого ваш код дает сбой.Если вы запустите вашу функцию 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

С этим вы сможете выяснить, какие другие тестовые случаи дают сбой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...