Комментарии 33
Тогда уж нужно вводить проверку на >0. Я бы сделал просто n<2
0! = 1
. Факториал определён на множестве неотрицательных целых чисел.
Так себе ошибка, никакая. Факториал нуля Вы когда в последний раз вычисляли по необходимости?
Но если функция на одном из допустимых значений ввода работает не верно, и даже более того - уходит в бесконечную рекурсию, то это неправильная функция, так не должно быть. Функция должна работать корректно на всём пространстве допустимых значений. "Классическое", чуть оптимизированное решение всё же такое: if n == 0 or n == 1: return 1
Ну да, или n < 2 как выше писали. Тогда уж и отрицательные значения не должны вызывать бесконечную рекурсию, и в принципе, если не решаем реальную задачу, а предполагаем, что ввод никак не ограничен, и на дробные числа надо проверять, и на строки с массивами.... В этом случае и решение Академии точно так-же "неверное". На отрицательных числах уходит в бесконечную рекурсию. Это не аргумент.
Нет, отрицательные числа не являются допустимыми для этой функции. Должна выдаваться ошибка и, например, питон действительно в итоге даст ошибку превышения глубины рекурсии. ) Это не очень правильно всё-равно. По-хорошему в начале функции нужно проверять условие n >= 0
и если оно не выполняется бросать исключение ValueError
:
exception ValueError
Raised when an operation or function receives an argument that has the right type but an inappropriate value, and the situation is not described by a more precise exception such as IndexError.
Биномиальный коэффициент C(n, k) = n! / (k! * (n - k)!). Вычисляется для 0 <= k <= n. На краях вылезают факториалы нуля.
Тем не менее, на всех n, которые встречаются в реальности, функции выдают одинаковый результат, можете сами позапускать на n>19. Я пока до 40 дошел.
Вычислите C(5, 5) например.
С этим случаем согласен, мой вариант не верен. А вот в условиях этой задачи верен. Нарисуйте параллельные линии искривленном пространстве - они пересекутся. Это ведь не обозначает, что фраза "параллельные линии не пересекаются" не верна? Вот и Вы вытащили моё решение за пределы задачи.
Просто примите, что такие задачки всегда идут вместе с тестами, которые обязательно проверяют граничные и экстремальные условия. Если вы напишете решение, которое работает только в типовых условиях, а всякие приколы не тянет, то вас любой сайт с задачками на этом зарубит обязательно. Привыкайте.
У меня богатый опыт в CodeWars, уже привык, не в этом был смысл публикации, а в том, что в рамах задачи оба варианта корректные, а если выходить за рамки задачи, оба варианта некорректные. Такие задачи просто недопустимо использовать для обучения новичков.
если в условии не указана область определения n - то ни одно из решений не является верным...
если там указано что n : 0, 1, 2, ... - то верным будет вариант с if == 0 return 1;
а если там сказано, что n - это натуральное число - то верным будут оба решения
пограничные условия очень важны
В статье есть картинка с полным условием задачи, прям самая первая из паблика по питону. Не указана, конечно, никакая область определения.
Формулировать так задачи: "исправить" — конечно же нельзя. Тогда уж надо указать, какой именно результат ожидается как "правильный". Может быть цель задачи — нагрузочное тестирование процессора или переполнение стека?
Вообще говоря, коль скоро исходная функция всегда возвращает ноль, то "исправление" это:
def factorial(n):
return 0
Кто его знает, может быть цель именно такая?
для начала, кто вообще не в ФП ЯП реализует факториал рекурсивно?
Посчитайте Y(5, 5) = n! / (k! * (n - k - 1)! и "верный" алгоритм тоже уйдет в бесконечный цикл.
Доопределите (-1)!
. Это сделает выражение вычислимым. Код надо будет дополнить для минус единицы (или для любых отрицательных целых?) и можно будет вычислить Y(5, 5)
.
Ну вот уж не думал, что Вы серьезно не понимаете, о чем я говорю. Давайте вспомните на секундочку, что тут не филиал StackOverflow и суть ваших претензий к моей статье. Статья была том, что Яндекс Академики, привлекая людей на обучение не смогли в рекурсию в тестовом задании: оба варианта ответа, в рамках задачи, давали идентичный результат и правильный вариант рекурсии, которая не уходила бы в бесконечный цикл, в ответах отсутствовал. А Вы придирались к определению факториала.
Мне кажется, вы недостаточно проверили. проверка до 40! явно недостаточна. С какого момента там наверняка возникнут расхождения. Стоит продолжить вашу работу.
Хммм ну вы просто съэкономили умножение на 1
В Wiki https://ru.wikipedia.org/wiki/Факториал написано;
Для n=0 принимается в качестве соглашения, что 0!=1 и представлено в рекурентной формуле
Просто ответ оказался ответ эквивалентным. (Тут такое знает ли студент о точном определении факториала, может и нет)
Ровно также можно сравнивать с функцией
func fact(n: int) -> int {
If n == 0 || n == 1 return 1
If n == 2 return 2
If n == 3 return 6
If n == 4 return 24
If n == 5 return 120
——
}
PS. нас на олимпиаде был такой случай где вместо логики кто-то на листочке или калькуляторе вычислил решение и выводил ответ из 5 контрольных - 3 оказались верными хотя внутри были ifы
Кстати задание если интересно :
Дано клавиатура телефона, номера телефонов состоят из 7 цифр, ты вводишь 1 цифру и тебе выводят сколько номеров могут начинаться с этой цифры при условии что следущая цифра может быть выбрана из позиции хода шахматного короля. К примеру 1 = 120
> К примеру 1 = 120
семизначных номеров, начинающихся с 1, у которых следующая цифра 2,4,5 всего 120? Как минимум цифра с 5-ю нулями должна быть. 1200000 до 1299999, 1400000 до 1499999, 1500000 до 1599999. 300000 штук вроде.
Извините шахматного коня(КОНЯ), буквой Г (чего я короля написал)..... и 120. я для примера не помню точно какое число было,
но я к чему так как это зеркальное то 1, 3, 7, 9 - получается имели одинаковый ответ. а из 5 вообще 0
в итоге 5 ответов из 10 мы знаем из коробки без вычислений -что одни и накидали
if (n==1 || n==3 || n==7 || n==9) print(124)
if n == 5 print(0)
что вроде и верно но неспортивно, а у проверяющих был 1 котнрольный сет данных и из 5 попыток 3 оказались верными
Академия Яндекса. Мы в рекурсии случайно