添加数字的数字,直到只剩下两个数字

时间:2015-02-13 05:47:45

标签: matlab

如何编写要解决的函数:

例如。如果数字是4237,那么解决方案

yields 4+2 2+3 3+7 
         6   5  10
then   6+5 5+10    yields
        11   15

1115的答案不是行向量[11,15]。

不应使用

whilefor

编辑。例如2.如果初始数字是21020,最终答案应该是77.应该是数字77而不是矢量[7,7]。

5 个答案:

答案 0 :(得分:2)

无循环解决方案:

%// input
a = 21020

%// convert number to array of digits
b = num2str(a)-48
%// or directly 
b = [2 1 0 2 0]

%// get antidiagonal of pascal matrix
v = diag(fliplr(pascal(numel(b)-1))).'

%// calculation
c = sum([b(1:end-1).*v; b(2:end).*v],2)

%// convert array of digits to number inspired by Luis Mendo
result = str2double(sprintf('%i',c))

循环解决方案:

%// calculation
for ii = 1:numel(b)-2; b = filter(ones(1,2),1,b); end

%// convert array of digits to number inspired by Luis Mendo
result = str2double(sprintf('%i',b(end-1:end)))

result =

     77

答案 1 :(得分:1)

我认为这可以满足您的需求。它确实使用循环。

x = 4237; %// input
x = dec2base(x,10)-'0';
for n = 1:numel(x)-2
    x = conv(x,[1 1],'valid');
end
y = str2num(sprintf('%i',x)); %// output

没有循环:您可以多次将[1 1]与自身进行卷积,然后将其与您的数字进行一次卷积。 [1 1]与其自身的N次卷积仅为binomial coefficients,可以使用gammaln函数轻松计算:

x = 4237; %// input
x = dec2base(x,10)-'0';
N = numel(x)-2;
coeffs = round(exp(gammaln(N+1)-gammaln(1:N+1)-gammaln(N+1:-1:1)));
x = conv(x,coeffs,'valid');
y = str2num(sprintf('%i',x)); %// output

答案 2 :(得分:1)

仅出于学术目的,我们可以看一下使用递归合并conv。这是受路易斯·门多和阿米特方法的启发。

换句话说:

function [final] = convertNum(x)    

    function [out] = helper(in)

        if numel(in) == 2
            out = in;
        else
            out = helper(conv(in, [1 1], 'valid'));
        end
    end
    digits = dec2base(x, 10) - '0';
    final_digits = helper(digits);
    final = str2num(sprintf('%i',final_digits));

end

convertNum是我们用来接受数字的函数,输出将是一个双元素向量,它在每一步产生成对元素的总和,直到剩下两个元素。

我们需要一个辅助函数,它将接受一个系数数组,其中该数组由输入数字的提取的单个数字组成convertNum,存储在x中。我们先做的是取我们的号码x并将数字转换成单独的数字(取自thewaywewalk,Luis Mendo和Amit)。接下来,我们调用辅助函数来计算我们的成对总和。

辅助函数以这样的方式运行:如果我们有一个长度不等于2 的输入数字,我们通过conv执行成对求和并使用它来进入我们的辅助函数。一旦输入只包含两个元素,这就是我们从辅助函数返回的内容,我们将这两个向量合并为一个数字。这就是我们最终回归用户的目的。

因此,使用x = 21020,我们得到:

final = convertNum(21020)

final = 

77

类似地:

final = convertNum(4237)

final = 

1115

答案 3 :(得分:0)

根据您的评论,您的号码似乎已经是矢量形式。因此你很亲密你只是错过了一个循环,例如,这个循环:

x = [4,2,3,7];

while numel(x) > 2
    x = x(1:end-1) + x(2:end);
end

结果是:

x =

    11    15

答案 4 :(得分:0)

使用Luis Mendo和Marcin的答案,给定的解决方案可以使用递归函数实现如下(不使用for或while):

function x=reduce(x)
  x = dec2base(x,10)-'0'; 
  x=calculate(x);
end
function y=calculate(z)
  if(numel(z)>2)
    y=calculate(z(1:end-1)+z(2:end));
  else
    y=z;
  end
end