f=lambda n,k=1:k/n or n*f(n,k+1)+k*f(n-1,k)
Попробуйте онлайн!
Другой подход
С тех пор, как я опубликовал эту проблему, я пытался найти рекурсивное решение этой проблемы. Хотя мне не удалось использовать ничего, кроме ручки и бумаги, мне удалось превратить формулу в гольф в практическую проблему - по крайней мере, для некоторых практических определений - которая упростила анализ.
Представьте себе игровое шоу с k + m кандидатами, которое работает следующим образом.
В первом раунде все кандидаты должны выполнить определенную задачу как можно быстрее. В K кандидаты которые выполняют задачу быстрее всего выиграть 1 K $ (один kilodollar) каждый и продвижение в 3 -м раунде.
Во втором раунде m оставшихся кандидатов получают второй шанс присоединиться к другому k . Каждому кандидату задают вопрос. Если они ответят на вопрос правильно, они выиграют 1 k $ и перейдут к 3 раунду. Однако, если они не ответят на вопрос, они будут исключены из игры. Это означает, что в третьем раунде будет от k до k + m кандидатов, в зависимости от того, сколько из них сможет ответить на их вопросы.
3-й тур состоит из m конкурсов, похожих на 1-й. В каждом конкурсе участники должны выполнить определенную задачу. В отличие от 1 тура, только один кандидат получает приз, но все кандидаты получают право участвовать в следующем конкурсе. Каждый конкурс платит вдвое больше, чем конкурс до него; первый платит 2 k $, а последний 2 m k $ .
Обратите внимание, что, поскольку все призы являются степенями двух, знание того, сколько призовых денег заработал кандидат, означает, что мы знаем, продвинулись ли они в 3-й раунд и в каком из конкурсов 3-го тура они выиграли.
Предположим, вы смотрите игровое шоу, и первый тур уже завершен, поэтому вы знаете, какие k кандидатов уже достигли третьего раунда и какие m кандидатов все еще застряли во втором раунде. Каким образом можно распределить оставшиеся призовые деньги?
После того, как мы знаем , какой из второго раунда м кандидатов выдвигали в 3 -м раунде, легко рассчитать возможные результаты для этого конкретного сценария. Если J кандидатов заранее, есть к + J всего кандидатов в 3 -м раунде, и , таким образом , к + J возможные результаты для каждого конкурса. Если в третьем раунде будет m индивидуальных соревнований, это даст (k + j) m результатов для всех m соревнований.
Теперь j может принимать любое значение от 0 до m , в зависимости от того, какие кандидаты правильно ответят в раунде 2. Для каждого фиксированного значения j есть m C j различных комбинаций j кандидатов, которые могли бы перейти в раунд 3. Если мы вызовем Общее количество возможных результатов для k раунда 3 кандидатов и m раунда 2 кандидатов g (m, k) , мы получаем следующую формулу.
Если мы исправим k = 1 , мы получим следующий частный случай, который составляет наш новый подход к решению исходной задачи.
Рекурсивная формула
Теперь предположим , что вы заснули во время рекламы после того, как 1 -м раунде, и проснулся как раз вовремя , чтобы увидеть , кто выиграл последний конкурс круглого 3 и , таким образом , главный приз 2 м K $ . У вас нет никакой другой информации, даже того, сколько призовых денег в итоге выиграл кандидат. Как можно распределить оставшиеся призовые деньги?
Если победителем стал один из m кандидатов во 2- м туре, мы уже сейчас должны были перейти в 3-й тур . Таким образом, у нас фактически есть k + 1 кандидатов в 3 раунде, но только m - 1 кандидатов в раунде 2. Так как мы знаем победителя последнего конкурса, есть только m - 1 конкурсы с неопределенными результатами, поэтому есть g (m - 1, к + 1) возможные результаты.
Если победителем является один из k кандидатов, пропустивших раунд 2, расчет становится немного сложнее. Как и прежде, осталось только m - 1 тур , но теперь у нас все еще есть k кандидатов в 3 туре и m кандидатов в 2 туре. Так как количество кандидатов в раунде 2 и количество конкурсов в раунде 3 разные, возможные результаты не могут рассчитываться с помощью простого вызова g . Тем не менее, после первого тура 2 кандидата ответили - правильно или нет - количество кандидатов в 2 раунде еще раз соответствует m - 1 раунду 3 конкурса. Если кандидат выдвигается, есть k + 1 раунд 3 кандидата и, таким образом, g (m - 1, k + 1)возможные результаты; если кандидат исключен, число кандидатов в 3 раунде остается на уровне k, и возможны g (m - 1, k) результатов. Поскольку кандидат продвигается или нет, существует g (m - 1, k + 1) + g (m - 1, k) возможных результатов, объединяющих эти два случая.
Теперь, если мы добавим потенциальные результаты для всех k + m кандидатов, которые могли бы выиграть главный приз, результат должен соответствовать g (m, k) . Есть m участников раунда 2, которые приводят к g (m - 1, k + 1) потенциальным результатам каждый, и участники k раунда 3, которые приводят к g (m - 1, k + 1) + g (m - 1, k) из них. Подводя итог, мы получаем следующую идентичность.
Вместе с базовым корпусом
Эти две формулы полностью характеризуют функцию g .
Реализация гольфа
В то время как
g=lambda m,k=1:0**m or(m+k)*g(m-1,k+1)+k*g(m-1,k)
(49 байтов, 0**m
дает 1 раз m падает до 0 ) или даже
g=lambda m,k=1:m<1 or(m+k)*g(m-1,k+1)+k*g(m-1,k)
(48 байтов, возвращает True вместо 1 ) будут правильными решениями, все еще есть байты, которые нужно сохранить.
Если мы определим функцию f, которая принимает число n кандидатов в 1 раунд вместо числа m кандидатов в 2 раунд в качестве первого аргумента, т.е.
мы получаем рекурсивную формулу
с базовым случаем
Наконец, мы имеем
поэтому реализация Python
f=lambda n,k=1:k/n or n*f(n,k+1)+k*f(n-1,k)
( k/n
дает 1 раз при n = k ) решает задачу под рукой с индексированием на основе 1.