open System // method 1: Найти количество делителей числа, не делящихся на 3 let countDivisorsNotDivisibleByThree (n: int) = let rec countDivisors current count = if current > n then count else // является ли текущее число делителем n и не делится ли оно на 3 let newCount = if n % current = 0 && current % 3 <> 0 then count + 1 else count countDivisors (current + 1) newCount if n <= 0 then 0 else countDivisors 1 0 // method 2: Найти минимальную нечетную цифру числа let findMinOddDigit (n: int) = let rec findMin number minDigit = if number = 0 then minDigit else let digit = number % 10 let newMin = if digit % 2 <> 0 && (minDigit = -1 || digit < minDigit) then digit else minDigit findMin (number / 10) newMin if n < 0 then findMin (abs n) -1 else findMin n -1 // общие вспомогательные функции 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 getDigits n = let rec extractDigits (num: int) (acc: int list) = if num = 0 then if acc.IsEmpty then [0] else acc else extractDigits (num / 10) ((num % 10) :: acc) extractDigits (abs n) [] let sumDigits n = let rec sumDigitsRec num acc = if num = 0 then acc else sumDigitsRec (num / 10) (acc + num % 10) sumDigitsRec (abs n) 0 let productDigits n = let rec productDigitsRec num acc = if num = 0 then if acc = 1 && n <> 0 then 0 else acc else productDigitsRec (num / 10) (acc * (num % 10)) productDigitsRec (abs n) 1 // method 3: Найти сумму всех делителей числа, взаимно простых с суммой цифр числа и не взаимно простых с произведением цифр числа let sumSpecialDivisors (n: int) = if n <= 0 then 0 else let digitSum = sumDigits n let digitProduct = productDigits n // Функция для проверки условия для делителя let isSpecialDivisor divisor = n % divisor = 0 && areCoprime divisor digitSum && not (areCoprime divisor digitProduct) // Рекурсивная функция для суммирования делителей let rec sumDivisors current acc = if current > n then acc else let newAcc = if isSpecialDivisor current then acc + current else acc sumDivisors (current + 1) newAcc sumDivisors 1 0 // test method 1 let testCountDivisorsNotDivisibleByThree () = let testCases = [1; 3; 6; 9; 10; 12; 15; 20; 30] printfn "Тестирование метода 1: Количество делителей числа, не делящихся на 3" for n in testCases do let divisors = [1..n] |> List.filter (fun i -> n % i = 0) let divisorsNotDivByThree = divisors |> List.filter (fun i -> i % 3 <> 0) let expected = divisorsNotDivByThree.Length let result = countDivisorsNotDivisibleByThree n printfn "n = %d:" n printfn " Все делители: %A" divisors printfn " Делители, не делящиеся на 3: %A" divisorsNotDivByThree printfn " Результат: %d (ожидаемый: %d) - %s" result expected (if result = expected then "OK" else "ОШИБКА") printfn "" // method test 2 let testFindMinOddDigit () = let testCases = [0; 2; 8; 13; 25; 42; 123; 456; 789; 2468; 1359; 12345] printfn "Тестирование метода 2: Минимальная нечетная цифра числа" for n in testCases do let digits = n.ToString() |> Seq.map (fun c -> int c - int '0') |> Seq.toList let oddDigits = digits |> List.filter (fun d -> d % 2 <> 0) let expected = if oddDigits.IsEmpty then -1 else List.min oddDigits let result = findMinOddDigit n printfn "n = %d:" n printfn " Цифры: %A" digits printfn " Нечетные цифры: %A" oddDigits printfn " Минимальная нечетная цифра: %d (ожидаемая: %d) - %s" result expected (if result = expected then "OK" else "ОШИБКА") printfn "" // method test 3 let testSumSpecialDivisors () = let testCases = [10; 12; 15; 20; 30; 36; 48; 56; 72; 96] printfn "Тестирование метода 3: Сумма особых делителей числа" for n in testCases do let digits = getDigits n let digitsSum = sumDigits n let digitsProduct = productDigits n let divisors = [1..n] |> List.filter (fun i -> n % i = 0) let specialDivisors = divisors |> List.filter (fun d -> areCoprime d digitsSum && not (areCoprime d digitsProduct)) let expected = List.sum specialDivisors let result = sumSpecialDivisors n printfn "n = %d:" n printfn " Цифры: %A" digits printfn " Сумма цифр: %d" digitsSum printfn " Произведение цифр: %d" digitsProduct printfn " Все делители: %A" divisors printfn " Особые делители: %A" specialDivisors printfn " Результат: %d (ожидаемый: %d) - %s" result expected (if result = expected then "OK" else "ОШИБКА") printfn "" [] let main argv = Console.OutputEncoding <- Text.Encoding.UTF8 printfn "Задание 16. Вариант № 5." printfn "Метод 1: Найти количество делителей числа, не делящихся на 3." printfn "Метод 2: Найти минимальную нечетную цифру числа." printfn "Метод 3: Найти сумму всех делителей числа, взаимно простых с суммой цифр числа и не взаимно простых с произведением цифр числа.\n" printfn "=== Тестирование Метода 1 ===" testCountDivisorsNotDivisibleByThree() printfn "=== Тестирование Метода 2 ===" testFindMinOddDigit() printfn "=== Тестирование Метода 3 ===" testSumSpecialDivisors() printfn "Интерактивный режим:" let rec processUserInput () = printfn "Выберите метод:" printfn "1 - Количество делителей числа, не делящихся на 3" printfn "2 - Минимальная нечетная цифра числа" printfn "3 - Сумма особых делителей числа" printfn "q - Выход" printf "Ваш выбор: " match Console.ReadLine().ToLower() with | "1" -> printf "Введите число: " match Int32.TryParse(Console.ReadLine()) with | true, n when n > 0 -> let result = countDivisorsNotDivisibleByThree n let divisors = [1..n] |> List.filter (fun i -> n % i = 0) let divisorsNotDivByThree = divisors |> List.filter (fun i -> i % 3 <> 0) printfn "Число: %d" n printfn "Все делители: %A" divisors printfn "Делители, не делящиеся на 3: %A" divisorsNotDivByThree printfn "Количество делителей, не делящихся на 3: %d" result printfn "" | _ -> printfn "Некорректный ввод. Пожалуйста, введите положительное целое число.\n" processUserInput () | "2" -> printf "Введите число: " match Int32.TryParse(Console.ReadLine()) with | true, n -> let result = findMinOddDigit n printfn "Число: %d" n let digits = (abs n).ToString() |> Seq.map (fun c -> int c - int '0') |> Seq.toList let oddDigits = digits |> List.filter (fun d -> d % 2 <> 0) printfn "Цифры: %A" digits printfn "Нечетные цифры: %A" oddDigits if result = -1 then printfn "В числе нет нечетных цифр." else printfn "Минимальная нечетная цифра: %d" result printfn "" | _ -> printfn "Некорректный ввод. Пожалуйста, введите целое число.\n" processUserInput () | "3" -> printf "Введите число: " match Int32.TryParse(Console.ReadLine()) with | true, n when n > 0 -> let result = sumSpecialDivisors n let digits = getDigits n let digitsSum = sumDigits n let digitsProduct = productDigits n let divisors = [1..n] |> List.filter (fun i -> n % i = 0) let specialDivisors = divisors |> List.filter (fun d -> areCoprime d digitsSum && not (areCoprime d digitsProduct)) printfn "Число: %d" n printfn "Цифры: %A" digits printfn "Сумма цифр: %d" digitsSum printfn "Произведение цифр: %d" digitsProduct printfn "Все делители: %A" divisors printfn "Особые делители: %A" specialDivisors printfn "Сумма особых делителей: %d" result printfn "" | _ -> printfn "Некорректный ввод. Пожалуйста, введите положительное целое число.\n" processUserInput () | "q" | "quit" | "exit" -> () | _ -> printfn "Некорректный выбор. Пожалуйста, выберите 1, 2, 3 или q." processUserInput () processUserInput () 0