diff --git a/lab6/Makefile b/lab6/Makefile index 93456b0..a90496f 100644 --- a/lab6/Makefile +++ b/lab6/Makefile @@ -1,4 +1,4 @@ -.PHONY: run build clean task1 build-task1 clean-task1 task2 build-task2 clean-task2 task3 build-task3 clean-task3 task4 build-task4 clean-task4 task5 build-task5 clean-task5 task6 build-task6 clean-task6 task7 build-task7 clean-task7 task8 build-task8 clean-task8 task9 build-task9 clean-task9 task10 build-task10 clean-task10 task16 build-task16 clean-task16 task17 build-task17 clean-task17 task18 build-task18 clean-task18 task19 build-task19 clean-task19 +.PHONY: run build clean task1 build-task1 clean-task1 task2 build-task2 clean-task2 task3 build-task3 clean-task3 task4 build-task4 clean-task4 task5 build-task5 clean-task5 task6 build-task6 clean-task6 task7 build-task7 clean-task7 task8 build-task8 clean-task8 task9 build-task9 clean-task9 task10 build-task10 clean-task10 task16 build-task16 clean-task16 task17 build-task17 clean-task17 task18 build-task18 clean-task18 task19 build-task19 clean-task19 task20 build-task20 clean-task20 # task1 run: @@ -151,3 +151,13 @@ build-task19: clean-task19: cd task19 && dotnet clean + +# task20 +task20: + cd task20 && dotnet run --project task20.fsproj + +build-task20: + cd task20 && dotnet build + +clean-task20: + cd task20 && dotnet clean diff --git a/lab6/task20/Program.fs b/lab6/task20/Program.fs new file mode 100644 index 0000000..06f7e9f --- /dev/null +++ b/lab6/task20/Program.fs @@ -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))) + +[] +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 \ No newline at end of file diff --git a/lab6/task20/task20.fsproj b/lab6/task20/task20.fsproj new file mode 100644 index 0000000..3befcdd --- /dev/null +++ b/lab6/task20/task20.fsproj @@ -0,0 +1,12 @@ + + + + Exe + net7.0 + + + + + + + \ No newline at end of file