open System let vowels = set ['a'; 'e'; 'i'; 'o'; 'u'; 'A'; 'E'; 'I'; 'O'; 'U'; 'а'; 'е'; 'и'; 'о'; 'у'; 'ы'; 'э'; 'ю'; 'я'; 'А'; 'Е'; 'И'; 'О'; 'У'; 'Ы'; 'Э'; 'Ю'; 'Я'] let isVowel c = vowels.Contains(c) let isConsonant c = Char.IsLetter(c) && not (isVowel c) let englishFrequency = Map.ofList [ ('a', 8.12); ('b', 1.49); ('c', 2.78); ('d', 4.25); ('e', 12.02); ('f', 2.23); ('g', 2.02); ('h', 6.09); ('i', 6.97); ('j', 0.15); ('k', 0.77); ('l', 4.03); ('m', 2.41); ('n', 6.75); ('o', 7.51); ('p', 1.93); ('q', 0.10); ('r', 5.99); ('s', 6.33); ('t', 9.06); ('u', 2.76); ('v', 0.98); ('w', 2.36); ('x', 0.15); ('y', 1.97); ('z', 0.07) ] let sortByCriteria1 (strings: string[]) = strings |> Array.sortBy (fun str -> let chars = str.ToCharArray() let vowelCount = chars |> Array.filter isVowel |> Array.length let consonantCount = chars |> Array.filter isConsonant |> Array.length let vowelAvg = if vowelCount > 0 then float vowelCount / float str.Length else 0.0 let consonantAvg = if consonantCount > 0 then float consonantCount / float str.Length else 0.0 abs (consonantAvg - vowelAvg)) let sortByCriteria2 (strings: string[]) = strings |> Array.sortBy (fun str -> let chars = str.ToCharArray() let avgAscii = chars |> Array.map (fun c -> float (int c)) |> Array.average avgAscii) let sortByCriteria3 (strings: string[]) = strings |> Array.sortBy (fun str -> let chars = str.ToCharArray() let charCounts = chars |> Array.countBy id |> Map.ofArray let mostFrequentChar, maxCount = charCounts |> Map.toArray |> Array.maxBy snd let stringFreq = float maxCount / float str.Length let alphabetFreq = match englishFrequency.TryFind (Char.ToLower mostFrequentChar) with | Some freq -> freq / 100.0 | None -> 0.01 abs (stringFreq - alphabetFreq)) let sortByCriteria4 (strings: string[]) = if strings.Length = 0 then strings else let firstStringAvgAscii = strings.[0].ToCharArray() |> Array.map (fun c -> float (int c)) |> Array.average strings |> Array.sortBy (fun str -> let avgAscii = str.ToCharArray() |> Array.map (fun c -> float (int c)) |> Array.average (avgAscii - firstStringAvgAscii) ** 2.0) let sortByCriteria5 (strings: string[]) = strings |> Array.sortBy (fun str -> let chars = str.ToCharArray() let charCounts = chars |> Array.countBy id |> Map.ofArray let mostFrequentChar, maxCount = charCounts |> Map.toArray |> Array.maxBy snd let stringFreq = float maxCount / float str.Length let expectedFreq = match englishFrequency.TryFind (Char.ToLower mostFrequentChar) with | Some freq -> freq / 100.0 | None -> 0.01 (stringFreq - expectedFreq) ** 2.0) let sortByCriteria6 (strings: string[]) = let mutable sortedStrings = [] let mutable remainingStrings = List.ofArray strings while not remainingStrings.IsEmpty do let medianIndex = remainingStrings.Length / 2 let sortedRemaining = remainingStrings |> List.sortBy (fun s -> s.Length) let medianString = sortedRemaining.[medianIndex] sortedStrings <- medianString :: sortedStrings remainingStrings <- remainingStrings |> List.filter (fun s -> s <> medianString) sortedStrings |> List.rev |> List.toArray let sortByCriteria7 (strings: string[]) = strings |> Array.sortBy (fun str -> let chars = str.ToCharArray() let mutable vcCount = 0 let mutable cvCount = 0 for i in 0 .. chars.Length - 2 do if isVowel chars.[i] && isConsonant chars.[i + 1] then vcCount <- vcCount + 1 elif isConsonant chars.[i] && isVowel chars.[i + 1] then cvCount <- cvCount + 1 abs (vcCount - cvCount)) let sortByCriteria8 (strings: string[]) = strings |> Array.sortBy (fun str -> let chars = str.ToCharArray() let avgAscii = chars |> Array.map (fun c -> float (int c)) |> Array.average let maxTripletAvg = if chars.Length < 3 then avgAscii else [| 0 .. chars.Length - 3 |] |> Array.map (fun i -> [| chars.[i]; chars.[i + 1]; chars.[i + 2] |] |> Array.map (fun c -> float (int c)) |> Array.average) |> Array.max (avgAscii - maxTripletAvg) ** 2.0) let sortByCriteria9 (strings: string[]) = strings |> Array.sortBy (fun str -> let chars = str.ToCharArray() let maxAscii = chars |> Array.map (fun c -> float (int c)) |> Array.max let mirrorDifferences = if chars.Length <= 1 then [| 0.0 |] else [| 0 .. chars.Length / 2 - 1 |] |> Array.map (fun i -> let leftChar = chars.[i] let rightChar = chars.[chars.Length - 1 - i] abs (float (int leftChar) - float (int rightChar))) let avgMirrorDiff = if mirrorDifferences.Length > 0 then Array.average mirrorDifferences else 0.0 (maxAscii - avgMirrorDiff) ** 2.0) let sortByCriteria10 (strings: string[]) = strings |> Array.sortBy (fun str -> let chars = str.ToCharArray() let mutable mirrorTripletCount = 0 for i in 0 .. chars.Length - 3 do if chars.[i] = chars.[i + 2] then mirrorTripletCount <- mirrorTripletCount + 1 float mirrorTripletCount / float (max 1 (chars.Length - 2))) [] let main argv = printfn "Задание 20: Сортировка строк по различным критериям" printfn "==================================================\n" let testStrings = [| "hello world" "programming" "algorithm" "data structure" "functional" "imperative" "recursion" "iteration" "ada" "abcba" |] printfn "Исходные строки:" testStrings |> Array.iteri (fun i str -> printfn " %d. %s" (i + 1) str) printfn "" printfn "1. Сортировка по разности между средним количеством согласных и гласных:" let sorted1 = sortByCriteria1 testStrings sorted1 |> Array.iteri (fun i str -> printfn " %d. %s" (i + 1) str) printfn "" printfn "2. Сортировка по среднему весу ASCII-кода символов:" let sorted2 = sortByCriteria2 testStrings sorted2 |> Array.iteri (fun i str -> printfn " %d. %s" (i + 1) str) printfn "" printfn "3. Сортировка по разности частоты наиболее частого символа:" let sorted3 = sortByCriteria3 testStrings sorted3 |> Array.iteri (fun i str -> printfn " %d. %s" (i + 1) str) printfn "" printfn "4. Сортировка по квадратичному отклонению ASCII от первой строки:" let sorted4 = sortByCriteria4 testStrings sorted4 |> Array.iteri (fun i str -> printfn " %d. %s" (i + 1) str) printfn "" printfn "5. Сортировка по квадратичному отклонению частоты от языковой частоты:" let sorted5 = sortByCriteria5 testStrings sorted5 |> Array.iteri (fun i str -> printfn " %d. %s" (i + 1) str) printfn "" printfn "6. Сортировка по медианному значению с удалением:" let sorted6 = sortByCriteria6 testStrings sorted6 |> Array.iteri (fun i str -> printfn " %d. %s" (i + 1) str) printfn "" printfn "7. Сортировка по разности сочетаний гласная-согласная и согласная-гласная:" let sorted7 = sortByCriteria7 testStrings sorted7 |> Array.iteri (fun i str -> printfn " %d. %s" (i + 1) str) printfn "" printfn "8. Сортировка по квадратичному отклонению среднего ASCII от максимального тройки:" let sorted8 = sortByCriteria8 testStrings sorted8 |> Array.iteri (fun i str -> printfn " %d. %s" (i + 1) str) printfn "" printfn "9. Сортировка по квадратичному отклонению максимального ASCII от зеркальных пар:" let sorted9 = sortByCriteria9 testStrings sorted9 |> Array.iteri (fun i str -> printfn " %d. %s" (i + 1) str) printfn "" printfn "10. Сортировка по среднему количеству зеркальных троек:" let sorted10 = sortByCriteria10 testStrings sorted10 |> Array.iteri (fun i str -> printfn " %d. %s" (i + 1) str) 0