查找等于其阶乘之和的所有数字

时间:2019-01-10 17:40:58

标签: matlab

如何查找所有数字(例如145 = 1!+ 4!+ 5!= 1 + 24 + 120 =145。)  用MATLAB等于这些数字的阶乘之和?

我想砍掉数字,将数字的阶乘加在一起,然后将其与原始数字进行比较。如果阶乘和等于原始数字,则此数字在解决方案中,并且必须保留。我无法编码我的想法,该如何编码?这是真的? 谢谢

2 个答案:

答案 0 :(得分:4)

我发布此答案的主要原因是,在没有合适的替代方案的情况下,我不能在previous answer中使用eval

这是一个小功能,可用于检查任何给定的(整数)n

isFact = @(n) n==sum(factorial(int2str(n)-'0'));

说明:

  1. int2str(n)-'0':“截断数字”
  2. sum(factorial(...)):“将数字的阶乘相加”
  3. 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))

答案 1 :(得分:2)

以下代码片段最多可以找到1000个满足此条件的数字。

numbers = [];
for i=1:1000
  number_char = int2str(i);
  sum = 0;
  for j=1:length(number_char)
   sum = sum+ factorial(eval(number_char(j)));
  end
  if (sum == i)
     numbers(end+1) = i;
  end
end
disp(numbers)

这应该产生:

1  2  145 

请注意,如果(log10(n)+1)* 9!小于n,则没有满足大于n的条件的数字。