From 18d937fe7e0255a93cd120c375aaa74e1b44dc1c Mon Sep 17 00:00:00 2001 From: Artem-Darius Weber Date: Thu, 17 Apr 2025 17:39:33 +0300 Subject: [PATCH] =?UTF-8?q?(lab=205)=20feat:=20task-15:=20=D0=94=D0=BE?= =?UTF-8?q?=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D1=84=D1=83=D0=BD?= =?UTF-8?q?=D0=BA=D1=86=D0=B8=D1=8F=20=D0=BE=D0=B1=D1=85=D0=BE=D0=B4=D0=B0?= =?UTF-8?q?=20=D0=B2=D0=B7=D0=B0=D0=B8=D0=BC=D0=BD=D0=BE=20=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D1=8B=D1=85=20=D1=87=D0=B8=D1=81=D0=B5=D0=BB?= =?UTF-8?q?=20=D1=81=20=D1=83=D1=81=D0=BB=D0=BE=D0=B2=D0=B8=D0=B5=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- compose.yaml | 9 + .../ConditionalCoprimeTraversal.fsproj | 13 ++ lab 5/ConditionalCoprimeTraversal/Program.fs | 156 ++++++++++++++++++ lab 5/Makefile | 54 +++++- 4 files changed, 230 insertions(+), 2 deletions(-) create mode 100644 lab 5/ConditionalCoprimeTraversal/ConditionalCoprimeTraversal.fsproj create mode 100644 lab 5/ConditionalCoprimeTraversal/Program.fs diff --git a/compose.yaml b/compose.yaml index 0747068..07b0eeb 100644 --- a/compose.yaml +++ b/compose.yaml @@ -134,4 +134,13 @@ services: volumes: - ./lab 5/EulerFunction:/app stdin_open: true + tty: true + + lab5-conditional-coprime: + build: + context: ./lab 5/ConditionalCoprimeTraversal + dockerfile: ../../Individual Task 1/Dockerfile + volumes: + - ./lab 5/ConditionalCoprimeTraversal:/app + stdin_open: true tty: true \ No newline at end of file diff --git a/lab 5/ConditionalCoprimeTraversal/ConditionalCoprimeTraversal.fsproj b/lab 5/ConditionalCoprimeTraversal/ConditionalCoprimeTraversal.fsproj new file mode 100644 index 0000000..19ba711 --- /dev/null +++ b/lab 5/ConditionalCoprimeTraversal/ConditionalCoprimeTraversal.fsproj @@ -0,0 +1,13 @@ + + + + Exe + net7.0 + ConditionalCoprimeTraversal + + + + + + + \ No newline at end of file diff --git a/lab 5/ConditionalCoprimeTraversal/Program.fs b/lab 5/ConditionalCoprimeTraversal/Program.fs new file mode 100644 index 0000000..6f6bb43 --- /dev/null +++ b/lab 5/ConditionalCoprimeTraversal/Program.fs @@ -0,0 +1,156 @@ +open System + +let rec gcd a b = + if b = 0 then abs a + else gcd b (a % b) + +let areCoprime a b = + gcd a b = 1 + +let traverseCoprime (n: int) (operation: int -> int -> int) (initialValue: int) = + [1..n] + |> List.filter (fun i -> areCoprime n i) + |> List.fold operation initialValue + +let traverseCoprimeWithCondition (n: int) (condition: int -> bool) (operation: int -> int -> int) (initialValue: int) = + [1..n] + |> List.filter (fun i -> areCoprime n i && condition i) + |> List.fold operation initialValue + +let eulerFunction (n: int) = + let countOperation _ acc = acc + 1 + traverseCoprime n countOperation 0 + +let conditionalEulerFunction (n: int) (condition: int -> bool) = + [1..n] + |> List.filter (fun i -> areCoprime n i && condition i) + |> List.length + +let isPrime x = + if x <= 1 then false + elif x <= 3 then true + elif x % 2 = 0 || x % 3 = 0 then false + else + let sqrtX = int(sqrt(float x)) + let possibleFactors = [5..6..sqrtX] |> List.collect (fun i -> [i; i + 2]) + not (possibleFactors |> List.exists (fun i -> x % i = 0)) + +let testTraverseCoprimeWithCondition () = + printfn "Тестирование функции обхода взаимно простых чисел с условием:" + + let testCases = [10; 12; 15; 20; 30] + + for n in testCases do + let testConditions = [ + ("Четные числа", fun x -> x % 2 = 0); + ("Нечетные числа", fun x -> x % 2 <> 0); + ("Числа, делящиеся на 3", fun x -> x % 3 = 0); + ("Простые числа", isPrime); + ("Числа > n/2", fun x -> x > n/2); + ] + + printfn "Для числа n = %d:" n + + let allCoprimes = [1..n] |> List.filter (fun i -> areCoprime n i) + printfn " Все взаимно простые числа: %A" allCoprimes + + for (conditionName, condition) in testConditions do + let filteredCoprimes = allCoprimes |> List.filter condition + + let sum = traverseCoprimeWithCondition n condition (fun a b -> a + b) 0 + let expectedSum = List.sum filteredCoprimes + + let product = traverseCoprimeWithCondition n condition (fun a b -> a * b) 1 + let expectedProduct = List.fold (fun acc x -> acc * x) 1 filteredCoprimes + + let count = conditionalEulerFunction n condition + let expectedCount = List.length filteredCoprimes + + printfn " Условие: %s" conditionName + printfn " Отфильтрованные взаимно простые числа: %A" filteredCoprimes + + printfn " Сумма: %d (ожидаемая: %d) - %s" + sum expectedSum + (if sum = expectedSum then "OK" else "ОШИБКА") + + printfn " Произведение: %d (ожидаемое: %d) - %s" + product expectedProduct + (if product = expectedProduct then "OK" else "ОШИБКА") + + printfn " Количество (условная функция Эйлера): %d (ожидаемое: %d) - %s" + count expectedCount + (if count = expectedCount then "OK" else "ОШИБКА") + + printfn "" + +[] +let main argv = + Console.OutputEncoding <- Text.Encoding.UTF8 + + printfn "Задание 15. Функция обхода взаимно простых чисел с условием." + printfn "" + + testTraverseCoprimeWithCondition() + + printfn "Интерактивный режим:" + + let rec processUserInput () = + printf "Введите число для вычисления условной функции Эйлера (или 'q' для выхода): " + let input = Console.ReadLine() + + match input.ToLower() with + | "q" | "quit" | "exit" -> () + | _ -> + match Int32.TryParse(input) with + | true, n when n > 0 -> + printfn "Выберите условие:" + printfn "1 - Только четные числа" + printfn "2 - Только нечетные числа" + printfn "3 - Только числа, делящиеся на 3" + printfn "4 - Только простые числа" + printfn "5 - Только числа > n/2" + printfn "6 - Свое условие (x > a)" + + printf "Ваш выбор: " + let conditionChoice = Console.ReadLine() + + let condition = + match conditionChoice with + | "1" -> (fun x -> x % 2 = 0), "четные числа" + | "2" -> (fun x -> x % 2 <> 0), "нечетные числа" + | "3" -> (fun x -> x % 3 = 0), "числа, делящиеся на 3" + | "4" -> (isPrime, "простые числа") + | "5" -> (fun x -> x > n/2), $"числа > {n/2}" + | "6" -> + printf "Введите значение a для условия (x > a): " + match Int32.TryParse(Console.ReadLine()) with + | true, a -> (fun x -> x > a), $"числа > {a}" + | _ -> (fun _ -> true), "все числа" + | _ -> (fun _ -> true), "все числа" + + let (condFunc, condName) = condition + + let coprimes = [1..n] |> List.filter (fun i -> areCoprime n i) + let filteredCoprimes = coprimes |> List.filter condFunc + + let result = conditionalEulerFunction n condFunc + + printfn "\nРезультаты для n = %d с условием: %s" n condName + printfn " Все взаимно простые числа: %A" coprimes + printfn " Отфильтрованные взаимно простые числа: %A" filteredCoprimes + printfn " Условная функция Эйлера φ'(%d) = %d" n result + + let sum = traverseCoprimeWithCondition n condFunc (fun a b -> a + b) 0 + printfn " Сумма: %d" sum + + let product = traverseCoprimeWithCondition n condFunc (fun a b -> a * b) 1 + printfn " Произведение: %d" product + + printfn "" + processUserInput () + | _ -> + printfn " Некорректный ввод. Пожалуйста, введите положительное целое число.\n" + processUserInput () + + processUserInput () + 0 \ No newline at end of file diff --git a/lab 5/Makefile b/lab 5/Makefile index ab3a0b5..9792fd1 100755 --- a/lab 5/Makefile +++ b/lab 5/Makefile @@ -1,4 +1,4 @@ -.PHONY: run build clean quadratic circle numbers recursion factory traverse lambda conditional examples +.PHONY: run build clean quadratic circle numbers recursion factory traverse lambda conditional examples favoritelang favoritelangfp mutuallyprimetraversal eulerfunction conditionalcoprimetraversal # HelloWorld run: @@ -100,4 +100,54 @@ build-examples: cd NumberExamples && dotnet build clean-examples: - cd NumberExamples && dotnet clean \ No newline at end of file + cd NumberExamples && dotnet clean + +# FavoriteLang +favoritelang: + cd FavoriteLang && dotnet run --project FavoriteLang.fsproj + +build-favoritelang: + cd FavoriteLang && dotnet build + +clean-favoritelang: + cd FavoriteLang && dotnet clean + +# FavoriteLangFP +favoritelangfp: + cd FavoriteLangFP && dotnet run --project FavoriteLangFP.fsproj + +build-favoritelangfp: + cd FavoriteLangFP && dotnet build + +clean-favoritelangfp: + cd FavoriteLangFP && dotnet clean + +# MutuallyPrimeTraversal +mutuallyprimetraversal: + cd MutuallyPrimeTraversal && dotnet run --project MutuallyPrimeTraversal.fsproj + +build-mutuallyprimetraversal: + cd MutuallyPrimeTraversal && dotnet build + +clean-mutuallyprimetraversal: + cd MutuallyPrimeTraversal && dotnet clean + +# EulerFunction +eulerfunction: + cd EulerFunction && dotnet run --project EulerFunction.fsproj + +build-eulerfunction: + cd EulerFunction && dotnet build + +clean-eulerfunction: + cd EulerFunction && dotnet clean + +# ConditionalCoprimeTraversal +conditionalcoprimetraversal: + cd ConditionalCoprimeTraversal && dotnet run --project ConditionalCoprimeTraversal.fsproj + +build-conditionalcoprimetraversal: + cd ConditionalCoprimeTraversal && dotnet build + +clean-conditionalcoprimetraversal: + cd ConditionalCoprimeTraversal && dotnet clean \ No newline at end of file