2015-02-13 1 views
-3

как написать функцию для решения:Добавление цифр номера до тех пор, пока не останется только два числа

Для примера. если номер 4237, раствор

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

1115 является ответом не вектор-строка [11,15].

while или for не должен использоваться.

Отредактировано. Например, 2. Если начальное число равно 21020, окончательный ответ должен быть 77. Должен быть номер 77, а не вектор [7,7].

+0

Что вы trined? – Marcin

+0

Я попробовал sums = x (1: end-1) + x (2: end), но это только начальная сумма. Мне нужно заставить его работать до двух оставшихся номеров. – timrow

ответ

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 
+0

У нас была такая же идея :-) –

+0

@ LuisMendo да, но все же: ваш и мой не ведут к '3122' для' 21020' – thewaywewalk

+0

Извините, окончательный ответ должен быть 77 для начального номера 21020. – timrow

0

На основе ваших комментариев кажется, что ваш номер уже в векторной форме. таким образом, вы были близки. Вы были только недостающие петли, как, например, этот:

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

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

Результат:

x = 

    11 15 
+0

Это дает неправильный ответ. Например, если x = 21020, окончательный ответ должен быть 1115 не 3122. – timrow

+0

Это дает правильный ответ, но не описывает всю картину. Осталось только вернуть «х» обратно в один номер. Учитывая, что 'x' является вектором двух элементов, задание должно заключаться в объединении этих двух в один номер. – rayryeng

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] с собой несколько раз, а затем скручиваться, что когда-то с цифрами. Свертку N-складка [1 1] с самим собой просто 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 
+0

Я предпочитаю 'conv' over'filter', поскольку он автоматически сокращает вектор. +1 – thewaywewalk

+0

Исправление. Я допустил ошибку. Окончательный ответ должен быть 77, если начальный номер 21020. – timrow

+0

Ваше решение 'conv' идеально. Чтобы избежать использования петель, я использовал этот принцип с рекурсией. Рекурсия технически не является циклом, и я написал ответ. Спасибо, что позволил мне сгибать мышцы с рекурсией! – rayryeng

0

Используя ответы от Luis Mendo и Marcin, данное решение может быть реализовано с помощью рекурсивной функции следующим образом (без использования для или во время):

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 
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 и преобразуем цифры в отдельные номера (взяты из проспекта Луиса Мендо и Амита). Затем мы вызываем вспомогательную функцию для вычисления нашей парной суммы.

Вспомогательная функция работает таким образом, где, если мы имеем входное число, длина которого не равно 2, мы выполняем парную сумму с помощью conv и использовать эту функцию, чтобы рекурсия в нашу вспомогательной функцию. Когда вход состоит только из двух элементов, это то, что мы возвращаем из вспомогательной функции, мы берем эти два вектора и объединяем их в одно число. Это то, что мы наконец возвращаем к пользователю.

Таким образом, работа с x = 21020, мы получаем:

final = convertNum(21020) 

final = 

77 

Аналогично:

final = convertNum(4237) 

final = 

1115 
Смежные вопросы