(lab 5) feat: task-16-method-3: Добавлен метод нахождения суммы особых делителей числа

main
Artem-Darius Weber 3 weeks ago
parent 76879cebf0
commit 0ff00d9d25

@ -16,9 +16,8 @@ let countDivisorsNotDivisibleByThree (n: int) =
if n <= 0 then 0 else countDivisors 1 0
// Метод 2: Найти минимальную нечетную цифру числа
// method 2: Найти минимальную нечетную цифру числа
let findMinOddDigit (n: int) =
// Вспомогательная функция для поиска минимальной нечетной цифры с использованием хвостовой рекурсии
let rec findMin number minDigit =
if number = 0 then
minDigit
@ -35,8 +34,65 @@ let findMinOddDigit (n: int) =
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
// method test 1
// test method 1
let testCountDivisorsNotDivisibleByThree () =
let testCases = [1; 3; 6; 9; 10; 12; 15; 20; 30]
@ -80,13 +136,41 @@ let testFindMinOddDigit () =
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 ""
[<EntryPoint>]
let main argv =
Console.OutputEncoding <- Text.Encoding.UTF8
printfn "Задание 16. Вариант 5."
printfn "Метод 1: Найти количество делителей числа, не делящихся на 3."
printfn "Метод 2: Найти минимальную нечетную цифру числа.\n"
printfn "Метод 2: Найти минимальную нечетную цифру числа."
printfn "Метод 3: Найти сумму всех делителей числа, взаимно простых с суммой цифр числа и не взаимно простых с произведением цифр числа.\n"
printfn "=== Тестирование Метода 1 ==="
testCountDivisorsNotDivisibleByThree()
@ -94,11 +178,15 @@ let main argv =
printfn "=== Тестирование Метода 2 ==="
testFindMinOddDigit()
printfn "=== Тестирование Метода 3 ==="
testSumSpecialDivisors()
printfn "Интерактивный режим:"
let rec processUserInput () =
printfn "Выберите метод:"
printfn "1 - Количество делителей числа, не делящихся на 3"
printfn "2 - Минимальная нечетная цифра числа"
printfn "3 - Сумма особых делителей числа"
printfn "q - Выход"
printf "Ваш выбор: "
@ -150,9 +238,36 @@ let main argv =
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 или q."
printfn "Некорректный выбор. Пожалуйста, выберите 1, 2, 3 или q."
processUserInput ()
processUserInput ()

Loading…
Cancel
Save