|
|
|
@ -0,0 +1,219 @@
|
|
|
|
|
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
|