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.

219 lines
8.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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)))
[<EntryPoint>]
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