You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
83 lines
2.8 KiB
83 lines
2.8 KiB
// For more information see https://aka.ms/fsharp-console-apps
|
|
open System.IO
|
|
|
|
module EulerProblem105 =
|
|
let parseInput (filePath: string) =
|
|
File.ReadAllLines(filePath)
|
|
|> Array.map (fun line ->
|
|
line.Split(',')
|
|
|> Array.map int
|
|
|> Array.toList)
|
|
|> Array.toList
|
|
|
|
let generateAllSubsets set =
|
|
let rec generateSubsetsAux acc remaining =
|
|
match remaining with
|
|
| [] -> acc
|
|
| x::xs ->
|
|
let newSubsets = List.map (fun subset -> x::subset) acc
|
|
generateSubsetsAux (acc @ newSubsets) xs
|
|
|
|
let allSubsets = generateSubsetsAux [[]] set
|
|
List.filter (fun subset -> not (List.isEmpty subset)) allSubsets
|
|
|
|
let checkPrefixSuffixRule (sortedSet: int list) =
|
|
let n = List.length sortedSet
|
|
|
|
let rec check k =
|
|
if k > n / 2 then true
|
|
else
|
|
let prefixSum = sortedSet |> List.take (k+1) |> List.sum
|
|
let suffixSum = sortedSet |> List.rev |> List.take k |> List.sum
|
|
|
|
if prefixSum <= suffixSum then false
|
|
else check (k+1)
|
|
|
|
check 1
|
|
|
|
let checkUniqueSums set =
|
|
let subsets = generateAllSubsets set
|
|
let sums = subsets |> List.map List.sum
|
|
let uniqueSums = sums |> Set.ofList
|
|
|
|
List.length sums = Set.count uniqueSums
|
|
|
|
let isSpecialSumSet set =
|
|
let sortedSet = List.sort set
|
|
checkPrefixSuffixRule sortedSet && checkUniqueSums sortedSet
|
|
|
|
let findAllSpecialSumSets sets =
|
|
sets
|
|
|> List.filter isSpecialSumSet
|
|
|
|
let sumSpecialSumSets specialSets =
|
|
specialSets
|
|
|> List.map List.sum
|
|
|> List.sum
|
|
|
|
let run filePath =
|
|
let sets = parseInput filePath
|
|
printfn "Загружено %d множеств" (List.length sets)
|
|
|
|
let testExample1 = sets |> List.head
|
|
let testExample2 = sets |> List.item 1
|
|
|
|
printfn "Проверка первого примера: %A" testExample1
|
|
printfn "Результат: %b (ожидается: false)" (isSpecialSumSet testExample1)
|
|
|
|
printfn "Проверка второго примера: %A" testExample2
|
|
printfn "Результат: %b (ожидается: true)" (isSpecialSumSet testExample2)
|
|
|
|
let specialSets = findAllSpecialSumSets sets
|
|
printfn "Найдено %d special sum sets" (List.length specialSets)
|
|
|
|
let result = sumSpecialSumSets specialSets
|
|
printfn "Окончательный ответ: %d" result
|
|
|
|
result
|
|
|
|
[<EntryPoint>]
|
|
let main argv =
|
|
let result = EulerProblem105.run "sets.txt"
|
|
0
|