Основная причина, по которой я публикую этот ответ, заключается в том, что я не могу оставить использование eval
в предыдущем ответе без достойной альтернативы
Вот небольшая функция, чтобы проверить это для любого заданного (целого) n
:
isFact = @(n) n==sum(factorial(int2str(n)-'0'));
Пояснение:
int2str(n)-'0'
: "отрубить цифры"
sum(factorial(...))
: «сложить факториал цифр вместе»
n==...
: «сравнить с исходным числом»
Теперь вы можете включить его в цикл, чтобы найти все числа от 1 до maxInt
:
maxInt = 100000; % just for the example
solution = false(1,maxInt); % preallocating memory
for k = 1:maxInt
solution(k) = isFact(k);
end
find(solution) % find all the TRUE indices
Результат:
ans =
1 2 145 40585
Цикл выше был написан, чтобы быть простым. Если вы ищете дополнительную эффективность и гибкость (например, не проверяете все числа от 1 до maxInt
и не проверяете массив в любой форме), вы можете изменить его на:
% generating a set of random numbers with no repetitions:
Vec2Check = unique(randi(1000,1,1000)); % you can change that to any array
for k = 1:numel(Vec2Check)
if isFact(Vec2Check(k))
Vec2Check(k) = Vec2Check(k)+0.1;
end
end
solution = Vec2Check(Vec2Check>round(Vec2Check))-0.1
Добавление 0.1 служит «флагом», который отмечает числа, которые isFact
возвращает для них true
. Затем мы извлекаем их, сравнивая вектор с округленной версией.
Вы даже можете использовать однострочное решение:
solution = nonzeros(arrayfun(@(n) n.*(n==sum(factorial(int2str(n)-'0'))),Vec2Check))