2013-10-08 53 views
2

A armstrong number是一個數字,它是它自己的數字 的總和,每個數字都增加到數字位數的冪。查找阿姆斯壯號的簡化代碼

如下所示尋找7位阿姆斯特朗號碼,使用bsxfun,因爲它是相當快的原因,我的代碼,但它只能接受3張操作數(Mathematica的類似功能Outer可以接受多個參數)。我怎樣才能讓我的代碼更緊湊?

tic 
m1=(1:9).^7; 
m=(0:9).^7; 
r1=bsxfun(@plus, m1', m); 
r2=bsxfun(@plus, r1, reshape(m,1,1,[])); 
r3=bsxfun(@plus, r2, reshape(m,1,1,1,[])); 
r4=bsxfun(@plus, r3, reshape(m,1,1,1,1,[])); 
r5=bsxfun(@plus, r4, reshape(m,1,1,1,1,1,[])); 
r6=bsxfun(@plus, r5, reshape(m,1,1,1,1,1,1,[])); 
r7= permute(r6, 7:-1:1); 
A=reshape((1e6:1e7-1), size(r7)); 
A(A==r7) 
toc 

(* 
ans = 

    1741725 
    4210818 
    9800817 
    9926315 
*) 
+0

爲什麼'。^ 7'?它不應該是'。^ 3'嗎? –

+1

@LuisMendo不,功率等於整數長度。 – mathe

+0

難道你不能用'm(:)'替換你所有'重塑(m,1,1,[])'的東西,然後就調用'r1''和'r2''等等。 – Dan

回答

2

您可以簡化代碼的方式有兩種:

  1. 您可以顛倒順序你計算權力的總和。這可以讓您在最後取消(昂貴)排列。

  2. 然後,您可以使用第一個中間值一次執行兩個總和。

  3. 您還可以在每一步中平坦化結果以避免維數更高的數組。這也可以讓你避免在最後重新塑造A.

  4. 您可以使用內聯函數來簡化表示法。

這導致:

tic 
m1=(1:9).^7; 
m=(0:9).^7; 
combine = @(x,y) reshape(bsxfun(@plus, x, y'),[],1); 
r2=combine(m, m); 
r4=combine(r2, r2); 
r6=combine(r4, r2); 
r7=combine(r6, m1')'; 
r7(r7 == (1e6:1e7-1))' 
toc 

你會發現這是顯著也更快。

您可以通過使用計算的整數次冪時使用同樣的伎倆讓這個普通的過N:

function a = andy(N) 
m1=uint32((1:9).^N); 
m=uint32((0:9)'.^N); 
k = uint32(N) - 1; 
result = uint32(0); 
combine = @(x,y) reshape(bsxfun(@plus, x, y'),[],1); 
while (1), 
    if (bitand(k, 1) ~= 0), result = combine(result,m); end 
    k = bitshift(k,-1); 
    if (k == 0), break, end 
    m = combine(m,m); 
end 
result = combine(result,m1')'; 
a = result(result == ((10^(N-1)):(10^N-1)))'; 

我全部轉換值uint32,這不僅是快20%,但是也讓我計算9位數字安德森:

>> tic,andy(9),toc 

ans = 

    146511208 
    472335975 
    534494836 
    912985153 

Elapsed time is 40.208217 seconds. 

計算的10位數字安德森將需要uint64,這超出了我的機器的存儲能力。

3

可以使用shiftdim代替reshape,把bsxfun在for循環中

m=(0:9).^7.'; 
r=(1:9).^7.'; 
for k=1:6, 
    m = shiftdim(m,-1); 
    r = bsxfun(@plus, r, m); 
end 
r= permute(r, 7:-1:1); 
A=reshape((1e6:1e7-1), size(r7)); 
A(A==r7) 
0

下面是一個不同的方式來做到這一點,相當緊湊,但仍然需要一些更新任意長度。但是,我想你無法計算許多不同長度的數字。

[X1, X2, X3, X4, X5, X6, X7] = ndgrid(0:9); 

V = X1.^7+ X2.^7+ X3.^7+ X4.^7+ X5.^7+ X6.^7+ X7.^7; 
W = X1*1e6+ X2*1e5+ X3*1e4+ X4*1e3+ X5*1e2+ X6*1e1+ X7; 
W(W==V&X1>0) 
+0

對於那些想到它的人:使用基於'num2str'的​​方法會慢得多。 –