|
|
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
|
|
|
|
|
|
// Метод 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
|
|
|
|
|
|
// method test 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 ""
|
|
|
|
|
|
[<EntryPoint>]
|
|
|
let main argv =
|
|
|
Console.OutputEncoding <- Text.Encoding.UTF8
|
|
|
|
|
|
printfn "Задание 16. Вариант № 5."
|
|
|
printfn "Метод 1: Найти количество делителей числа, не делящихся на 3."
|
|
|
printfn "Метод 2: Найти минимальную нечетную цифру числа.\n"
|
|
|
|
|
|
printfn "=== Тестирование Метода 1 ==="
|
|
|
testCountDivisorsNotDivisibleByThree()
|
|
|
|
|
|
printfn "=== Тестирование Метода 2 ==="
|
|
|
testFindMinOddDigit()
|
|
|
|
|
|
printfn "Интерактивный режим:"
|
|
|
let rec processUserInput () =
|
|
|
printfn "Выберите метод:"
|
|
|
printfn "1 - Количество делителей числа, не делящихся на 3"
|
|
|
printfn "2 - Минимальная нечетная цифра числа"
|
|
|
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 ()
|
|
|
|
|
|
| "q" | "quit" | "exit" -> ()
|
|
|
| _ ->
|
|
|
printfn "Некорректный выбор. Пожалуйста, выберите 1, 2 или q."
|
|
|
processUserInput ()
|
|
|
|
|
|
processUserInput ()
|
|
|
0 |