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