MATLAB taking hours to solve an equation - matlab

I've been trying to solve an equation composed of matrices. MATLAB has run it for almost two hours now and nothing. It's supposed to multiply some 8x8 matrices and invert one 8x8 matrix. Should it take this long? I'm using an I7 8th gen 2.20 running at 4ghz, 16 gb and RTX 2060.
Code (the final line is where MATLAB is taking so long):
%% Modelagem do conversor SEPIC-Zeta em espaço de estados
%% Declarando variáveis simbólicas:
% Variáveis com o índice "_" são derivadas de primeira ordem.
% RL1, RL2, RL3 e RL4 são as resistências série dos indutores.
% RseC1, RseC2, RseC3 e RseC4 são as resistências série dos capacitores.
Vi = sym('Vi');
C1 = sym('C1');
C2 = sym('C2');
C3 = sym('C3');
C4 = sym('C4');
L1 = sym('L1');
L2 = sym('L2');
L3 = sym('L3');
L4 = sym('L4');
VC1 = sym('VC1');
VC2 = sym('VC2');
VC3 = sym('VC3');
VC4 = sym('VC4');
VC1_ = sym('VC1_');
VC2_ = sym('VC2_');
VC3_ = sym('VC3_');
VC4_ = sym('VC4_');
IL1 = sym('IL1');
IL2 = sym('IL2');
IL3 = sym('IL3');
IL4 = sym('IL4');
IL1_ = sym('IL1_');
IL2_ = sym('IL2_');
IL3_ = sym('IL3_');
IL4_ = sym('IL4_');
RL1 = sym('RL1');
RL2 = sym('RL2');
RL3 = sym('RL3');
RL4 = sym('RL4');
RseC1 = sym('RseC1');
RseC2 = sym('RseC2');
RseC3 = sym('RseC3');
RseC4 = sym('RseC4');
Ro = sym('Ro');
D = sym('D');
s = sym('s');
%% Determinando as matrizes de coeficientes do conversor em t = [0, DTs]:
% Equações LKT no conversor:
eqn11 = IL1_ - (-RL1*IL1 + Vi)/L1 == 0;
eqn21 = IL2_ - ((RseC1 - RL2)*IL2 - VC1)/L2 == 0;
eqn31 = IL3_ - (VC2 + (RseC2 - RL3)*IL3 + RseC2*IL4)/L3 == 0;
eqn41 = IL4_ - ((-VC3 + RseC2*C2*VC2_ - (RseC3 + RL4)*IL4 + Ro*C4*VC4_ + VC2)/L4) == 0;
eqn51 = VC1_ - (Vi - RL1*IL1 + L1*IL1_ + VC1 - L2*IL2_)/C1*(RseC1 - RL2) == 0;
eqn61 = VC2_ - (-RseC1*IL2 - VC1 - RL2*IL2 - L2*IL2_ + VC2 + L3*IL3_ + RL3*IL3)/(C2*RseC2) == 0;
eqn71 = VC3_ - (Ro*IL4 - Ro*C4*VC4_ - VC3 - L4*IL4_ + L3*IL3_ + RL3*IL3 - RL4*IL4)/(C3*RseC3) == 0;
eqn81 = VC4_ - (Ro*IL4 - VC4)/(C4*(RseC4 + Ro)) == 0;
% Solucionando o sistema de equações lineares:
sol1 = solve([eqn11, eqn21, eqn31, eqn41, eqn51, eqn61, eqn71, eqn81], [IL1_, IL2_, IL3_, IL4_, VC1_, VC2_, VC3_, VC4_]);
% Separando as matrizes A e B dos coeficientes:
system_A1 = [sol1.IL1_ == IL1_, sol1.IL2_ == IL2_, sol1.IL3_ == IL3_, sol1.IL4_ == IL4_,...
sol1.VC1_ == VC1_, sol1.VC2_ == VC2_, sol1.VC3_ == VC3_, sol1.VC4_ == VC4_];
vars1 = [ IL1, IL2, IL3, IL4, VC1, VC2, VC3, VC4 ];
vars21 = [ Vi ];
% Definindo as matrizes A1, B1, C1 e D1:
A1 = equationsToMatrix(system_A1,vars1);
B1 = equationsToMatrix(system_A1,vars21);
C1_ = [ 0; 0; 0; RseC4*Ro/(RseC4 + Ro); 0; 0; 0; Ro/(RseC4 + Ro) ];
D1 = 0;
%% Deterninando as matrizes dos coeficientes em t = [DTs, Ts]:
eqn12 = IL1_ - (-Vi + IL1*(RseC1 - RL1) + VC1 + RL2*IL2 + L2*IL2_)/L1 == 0;
eqn22 = IL2_ - (RseC2*IL1 + IL2*(-RL2 + RseC2) + VC2)/L2 == 0;
eqn32 = IL3_ - (-VC3 -RL3*IL3 - RseC3*IL3)/L3 == 0;
eqn42 = IL4_ - ((IL4*RL4 - Ro*IL4 - Ro*C4*VC4_)/L4) == 0;
eqn52 = VC1_ - (Vi - RseC1*IL1 - L1*IL1_ - VC1 + RL2*IL2 + L2*IL2_)/C1*(RseC1 + RseC2 - RL1) == 0;
eqn62 = VC2_ - (RL2*IL2 + L2*IL2_ - VC2)/(C2*RseC2) == 0;
eqn72 = VC3_ - (-Ro*IL4 - Ro*C4*VC4_ - VC3 + L4*IL4_ - L3*IL3_ + RL4*IL4)/(C3*(RL3 + RseC3)) == 0;
eqn82 = VC4_ - (Ro*IL4 - VC4)/(C4*(RseC4 - Ro)) == 0;
% Solucionando o sistema de equações lineares:
sol2 = solve([eqn12, eqn22, eqn32, eqn42, eqn52, eqn62, eqn72, eqn82], [IL1_, IL2_, IL3_, IL4_, VC1_, VC2_, VC3_, VC4_]);
% Separando as matrizes A e B dos coeficientes:
system_A2 = [sol2.IL1_ == IL1_, sol2.IL2_ == IL2_, sol2.IL3_ == IL3_, sol2.IL4_ == IL4_,...
sol2.VC1_ == VC1_, sol2.VC2_ == VC2_, sol2.VC3_ == VC3_, sol2.VC4_ == VC4_];
vars2 = [ IL1, IL2, IL3, IL4, VC1, VC2, VC3, VC4 ];
vars22 = [ Vi ];
% Definindo as matrizes A2, B2, C2 e D2:
A2 = equationsToMatrix(system_A2,vars2);
B2 = equationsToMatrix(system_A2,vars22);
C2_ = [ 0; 0; 0; RseC4*Ro/(RseC4 - Ro); 0; 0; 0; -Ro/(RseC4 - Ro) ];
D2 = 0;
%% Equacionamento para o espaço de estados médio:
A = simplify(A1*D + A2*(1-D));
B = simplify(B1*D + B2*(1-D));
C = simplify(C1_*D + C2_*(1-D));
D = simplify(D1*D + D2*(1-D));
X = simplify(-inv(A)*B*Vi);
I = eye(8);
Tp = C*inv(s*I - A)*((A1-A2)*X + (B1-B2)*Vi)+(C1-C2)*X;

Without understanding the math in detail I can see that it slows at line 108 X = simplify(-inv(A)*B*Vi); rather than the last line, but I haven't been running it that long <1min. Try to utilize A\b instead of inv(A)*b which takes much more time.

Related

Pillow new RGB screen not generating

I built a test program using import PIL.imagedraw etc etc and was able to use the draw.line command to draw various lines. All good. In a new program I added new code which built a matrix list of x/y/z points (and cosine/sine expressions with math.lib), an input command for some variables, and then the draw.line command as in the previous code, but now the RGB window is not showing at all. The program doesn’t end and gives no errors. (Pythonista on iOS iPad Pro)
The test program, a noob attempt at perspective projection (which works as expected):
import PIL.ImageDraw as ImageDraw,PIL.Image as Image, PIL.ImageShow as ImageShow
im = Image.new("RGB", (1200,800))
draw = ImageDraw.Draw(im)
GL_z = 0
PP_y = 0
SP_x = 300
SP_y = -400
SP_z = 600
org=600
answer=0
width=100
depth=500
height=500
SP_z1=SP_z+height
px_1 = org
py_1 = org
px_2 = org+90
py_2 = 50 + org
px_3 = -160 + org
py_3 = 550 + org
px_4 = -250 + org
py_4 = 500+org
while answer==0:
SP_z1=SP_z-height
px1_1 = ((px_1 - SP_x)/(py_1 - SP_y))*(py_1 - PP_y)
px1_2 = ((px_2 - SP_x)/(py_2 - SP_y))*(py_2 - PP_y)
px1_3 = ((px_3 - SP_x)/(py_3 - SP_y))*(py_3 - PP_y)
px1_4 = ((px_4 - SP_x)/(py_4 - SP_y))*(py_4 - PP_y)
py1_1 = ((SP_z-GL_z)/(py_1-SP_y))*(py_1-PP_y)
py1_2 = ((SP_z-GL_z)/(py_2-SP_y))*(py_2-PP_y)
py1_3 = ((SP_z-GL_z)/(py_3-SP_y))*(py_3-PP_y)
py1_4 = ((SP_z-GL_z)/(py_4-SP_y))*(py_4-PP_y)
py1_5 = ((SP_z1-GL_z)/(py_1-SP_y))*(py_1-PP_y)
py1_6 = ((SP_z1-GL_z)/(py_2-SP_y))*(py_2-PP_y)
py1_7 = ((SP_z1-GL_z)/(py_3-SP_y))*(py_3-PP_y)
py1_8 = ((SP_z1-GL_z)/(py_4-SP_y))*(py_4-PP_y)
px1_1old = px1_1
px1_2old = px1_2
px1_3old = px1_3
px1_4old = px1_4
py1_1old = py1_1
py1_2old = py1_2
py1_3old = py1_3
py1_4old = py1_4
py1_5old = py1_5
py1_6old = py1_6
py1_7old = py1_7
py1_8old = py1_8
SP_yold = SP_y
draw.line((0,SP_y,1200,SP_y),fill=(255,255,255))
draw.line((px1_1,py1_1,px1_2,py1_2),fill=(0,0,255))
draw.line((px1_2,py1_2,px1_3,py1_3),fill=(0,255,0))
draw.line((px1_3,py1_3,px1_4,py1_4),fill=(255,255,255))
draw.line((px1_4,py1_4,px1_1,py1_1),fill=(100,255,0))
draw.line((px1_1,py1_1,px1_1,py1_5),fill=(255,255,255))
draw.line((px1_1,py1_5,px1_2,py1_6),fill=(255,255,255))
draw.line((px1_2,py1_6,px1_3,py1_7),fill=(255,255,255))
draw.line((px1_3,py1_7,px1_4,py1_8),fill=(255,255,255))
draw.line((px1_4,py1_8,px1_4,py1_4),fill=(150,150,0))
#draw.line((px1_1,py1_1,px1_2,py1_2),fill=(255,255,255))
#draw.line((px1_2,py1_2,px1_3,py1_3),fill=(255,255,255))
#draw.line((px1_3,py1_3,px1_4,py1_4),fill=(255,255,255))
#draw.line((px1_4,py1_4,px1_1,py1_1),fill=(255,255,255))
im.show()
move = input("''")
if move == "w":
SP_y += 50
if move == "s":
SP_x -= 50
if move == "z":
SP_y -= 50
if move == "a":
SP_x += 50
if move == "-":
SP_z -= 50
if move == "=":
SP_z += 50
draw.line((0,SP_yold,1200,SP_yold),fill=(0,0,0))
draw.line((px1_1old,py1_1old,px1_2old,py1_2old),fill=(0,0,0))
draw.line((px1_2old,py1_2old,px1_3old,py1_3old),fill=(0,0,0))
draw.line((px1_3old,py1_3old,px1_4old,py1_4old),fill=(0,0,0))
draw.line((px1_4old,py1_4old,px1_1old,py1_1old),fill=(0,0,0))
draw.line((px1_1old,py1_1old,px1_1old,py1_5old),fill=(0,0,0))
draw.line((px1_1old,py1_5old,px1_2old,py1_6old),fill=(0,0,0))
draw.line((px1_2old,py1_6old,px1_3old,py1_7old),fill=(0,0,0))
draw.line((px1_3old,py1_7old,px1_4old,py1_8old),fill=(0,0,0))
draw.line((px1_4old,py1_8old,px1_4old,py1_4old),fill=(0,0,0))
And this is the code that refuses to draw anything:
import math
import decimal
decimal.getcontext().prec = 6
import PIL.ImageDraw as ImageDraw,PIL.Image as Image, PIL.ImageShow as ImageShow
im = Image.new("RGB", (1200,800))
draw = ImageDraw.Draw(im)
PP_y = 0
SP_x = 300
SP_y = -400
SP_z = 600
org=600
answer=0
dims=[]
for i in range (1, 5):
dim = int(input())
dims.append(dim)
dims[3] = (dims[3]*math.pi)/180
obj1 = [[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15],[16,17,18],[19,20,21],[22,23,24]]
y1 = [0,0,0,0,0,0,0,0]
y2 = [0,0,0,0,0,0,0,0]
y3 = [0,0,0,0,0,0,0,0]
x1 = [0,0,0,0,0,0,0,0]
z1 = [0,0,0,0,0,0,0,0]
ymod = [0,0,0,0,0,0,0,0]
xmod = [0,0,0,0,0,0,0,0]
obj1[0]=[0,0,0]
obj1[1]=[dims[0] * math.cos(dims[3]),dims[0] * math.sin(dims[3]),0]
obj1[2]=[obj1[1][0] - (dims[1] * math.sin(dims[3])),obj1[1][1] + (dims[1] * math.cos(dims[3])),0]
obj1[3]=[dims[1] * math.sin(dims[3]),dims[1] * math.cos(dims[3]),0]
obj1[4]=[0,0,dims[2]]
obj1[5]=[dims[0] * math.cos(dims[3]),dims[0] * math.sin(dims[3]),dims[2]]
obj1[6]=[obj1[1][0] - (dims[1] * math.sin(dims[3])),obj1[1][1] + (dims[1] * math.cos(dims[3])),dims[2]]
obj1[7]=[dims[1] * math.sin(dims[3]),dims[1] * math.cos(dims[3]),dims[2]]
for i in range (0,7):
y1[i]=obj1[i][1]-PP_y
y2[i]=obj1[i][1]-SP_y
y3[i]=y1[i]/y2[i]
x1[i]=obj1[i][0]-SP_y
z1[i]=obj1[i][2]-SP_z
obj1[i][0]=obj1[i][0] - (x1[i] * y3[i])
obj1[i][2]=obj1[i][2] - (z1[i] * y3[i])
#print(dims)
#print(obj1)
#print(y1,y2,y3,x1,z1,xmod,ymod)
while (True):
draw.line((obj1[0][0],obj1[0][2],obj1[1][0],obj1[1][2]),fill=(255,255,255))
Ah found the error, left out im.show(). Pretty fundamental…
reference
https://pillow.readthedocs.io/en/stable/reference/Image.html

Pinescript Array saying index is out of bounds when I am checking the size first?

Pinescript array, checking to see if array size is minimal needed, yet it is display this error enter image description here
Here is the code I am refering:
if confirmedTriangle and array.size(triangle_price)>4 and array.size(triangle_index)>4
for i = 0 to 3
//Slope
xIndexDis = array.get(triangle_index, 0) - array.get(triangle_index, 4)// : na
yPriceDis = array.get(triangle_price, 0) - array.get(triangle_price, 4)// : na
xIndexDis2 = array.get(triangle_index, 3) - array.get(triangle_index, 1)// : na
yPriceDis2 = array.get(triangle_price, 3) - array.get(triangle_price, 1)// : na
m = yPriceDis / xIndexDis //Gradient for bottom line
m2 = yPriceDis2 / xIndexDis2 // Gradient for top line
x1 = array.get(triangle_index, i)-testLength
y1 = array.get(triangle_price, i)
x2 = array.get(triangle_index, i+1)-testLength
y2 = array.get(triangle_price, i+1)
array.push(tri_array, line.new(x1,y1,x2,y2, color=color.white))
xa1 = array.get(triangle_index,4)
xa2 = array.get(triangle_index,0)
xb1 = array.get(triangle_index,3)
xb2 = array.get(triangle_index,1)
ya1 = array.get(triangle_price,4)
ya2 = array.get(triangle_price,0)
yb1 = array.get(triangle_price,3)
yb2 = array.get(triangle_price,1)
label.new(bar_index, high+atr, text="Xa1 = " + str.tostring(xa1) + " / Ya1 = " + str.tostring(ya1) + "\n Xa2 = " + str.tostring(xa2) + " / Ya2 = " + str.tostring(ya2) + "\nXb1 = " + str.tostring(xb1) + " / Yb1 = " + str.tostring(yb1) + "\n Xb2 = " + str.tostring(xb2) + " / Yb2 = " + str.tostring(yb2))
I don't get any errors on sometimeframes but the majority do present the same error,
Found the issues,
I assigned array.size(triangle_price) to a variable
e.g. arraySize = array.size(triangle_price)
In confirmedTriangle I was checking if arraySize>4, but the array size had been changed since that check
Simple fix was just to remove "arraySize = array.size(triangle_price)" and use array.size(triangle_price) in each check

How to find the first value of Bollinger Bands when bar open

Actually, the Bollinger Bands code is:
//#version=4
study(title="AAAA", shorttitle="AAAA", overlay=true)
len = 5
multi = 2
bb5med = sma(close, len)
devBB5 = mult2 * stdev(close, len)
bb5top = bb5med + devBB5
bb5bot = bb5med - devBB5
I would want to find the first value of those 3 lines when the new bar comes, means, when close==open.
Also, I need it to work when I change the len to 20, 50 and/or when I change the multi to 3
Please help me. Thank you.
//#version=5
indicator("BB Open", overlay = true)
len = input.int(20)
mult = input.float(2.000)
basis = (math.sum(close, len - 1)[1] + open) / len
float dev_sum = 0.0
for i = 1 to len - 1
dev_sum += math.pow(basis - close[i], 2)
dev_sum += math.pow(basis - open, 2)
stdev = math.sqrt(dev_sum / len)
up = basis + stdev * mult
dn = basis - stdev * mult
plot(basis, color = color.yellow)
plot(up)
plot(dn)
Function :
f_BBopen(_close, _open, _len, _mult) =>
_basis = (math.sum(_close, _len - 1)[1] + _open) / _len
float _dev_sum = 0.0
for i = 1 to _len - 1
_dev_sum += math.pow(_basis - _close[i], 2)
_dev_sum += math.pow(_basis - _open, 2)
_stdev = math.sqrt(_dev_sum / _len)
_up = _basis + _stdev * _mult
_dn = _basis - _stdev * _mult
[_basis, _up, _dn]
[basis, up, dn] = f_BBopen(close, open, len, mult)

Simple cryptographic puzzle [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I'm looking for a way to solve this crypt arithmetic problem of:
ROBERT + GERALD = DONALD
and potentially others as well, where each letter represents a digit.
How would you go about solving this by hand and how does that relate to solving it programmatically?
Thank you in advance
You can actually work this out as a sum:
robert
+ gerald
------
= donald
and use basic mathematical knowledge.
For example, there's no carry possible in the right column (6) and we have T + D = D. That means T must be zero.
Similarly, for column 5, there's no carry from column 6 and R + L = L means R is zero as well, and no carry to column 4.
Same with column 4, E + A = A so E is zero.
So we now have:
0ob000
+ g00ald
------
= donald
From there, we can infer from columns 3 and 1 that b==n and g==d and they (along with o/a/l/d) can be any value since every digit is being added to zero so there is no chance of carry anywhere. So let's just make them all one:
011000
+ 100111
------
= 111111
In fact, you could make them all zero and end up with 000000 + 000000 = 000000.
But that's hardly programming related, so let's make it so:
#include <stdio.h>
int main (void) {
int robert, gerald, donald;
for (int r = 0; r < 10; r++) {
for (int o = 0; o < 10; o++) {
for (int b = 0; b < 10; b++) {
for (int e = 0; e < 10; e++) {
for (int t = 0; t < 10; t++) {
for (int g = 0; g < 10; g++) {
for (int a = 0; a < 10; a++) {
for (int l = 0; l < 10; l++) {
for (int d = 0; d < 10; d++) {
for (int n = 0; n < 10; n++) {
robert = r * 100000 + o * 10000 + b * 1000 + e * 100 + r * 10 + t;
gerald = g * 100000 + e * 10000 + r * 1000 + a * 100 + l * 10 + d;
donald = d * 100000 + o * 10000 + n * 1000 + a * 100 + l * 10 + d;
if (robert + gerald == donald) {
printf (" %06d\n", robert);
printf ("+ %06d\n", gerald);
printf (" ------\n");
printf ("= %06d\n", donald);
printf ("........\n");
}
}
}
}
}
}
}
}
}
}
}
return 0;
}
That will give you a whole host of solutions.
And, before you complain that you cannot have repeated digits, there is no solution if that's the case, since mathematically both T and R must be zero, as shown in the original reasoning above. And you can prove this empirically with:
#include <stdio.h>
int main (void) {
int robert, gerald, donald;
for (int r = 0; r < 10; r++) {
for (int o = 0; o < 10; o++) {
if (o==r) continue;
for (int b = 0; b < 10; b++) {
if ((b==r) || (b==o)) continue;
for (int e = 0; e < 10; e++) {
if ((e==r) || (e==o) || (e==b)) continue;
for (int t = 0; t < 10; t++) {
if ((t==r) || (t==o) || (t==b) || (t==e)) continue;
for (int g = 0; g < 10; g++) {
if ((g==r) || (g==o) || (g==b) || (g==e) || (g==t)) continue;
for (int a = 0; a < 10; a++) {
if ((a==r) || (a==o) || (a==b) || (a==e) || (a==t) || (a==g)) continue;
for (int l = 0; l < 10; l++) {
if ((l==r) || (l==o) || (l==b) || (l==e) || (l==t) || (l==g) || (l==a)) continue;
for (int d = 0; d < 10; d++) {
if ((d==r) || (d==o) || (d==b) || (d==e) || (d==t) || (d==g) || (d==a) || (d==l)) continue;
for (int n = 0; n < 10; n++) {
if ((n==r) || (n==o) || (n==b) || (n==e) || (n==t) || (n==g) || (n==a) || (n==l) || (n==d)) continue;
robert = r * 100000 + o * 10000 + b * 1000 + e * 100 + r * 10 + t;
gerald = g * 100000 + e * 10000 + r * 1000 + a * 100 + l * 10 + d;
donald = d * 100000 + o * 10000 + n * 1000 + a * 100 + l * 10 + d;
if (robert + gerald == donald) {
printf (" %06d\n", robert);
printf ("+ %06d\n", gerald);
printf (" ------\n");
printf ("= %06d\n", donald);
printf ("........\n");
}
}
}
}
}
}
}
}
}
}
}
return 0;
}
which outputs no solutions.
Now DONALD + GERALD = ROBERT, that's a different matter but you can solve that simply by modifying the code above slightly, making the if statement into:
if (donald + gerald == robert) {
printf (" %06d\n", donald);
printf ("+ %06d\n", gerald);
printf (" ------\n");
printf ("= %06d\n", robert);
printf ("........\n");
}
and you get the single solution:
526485
+ 197485
------
= 723970

form a number using consecutive numbers

I was puzzled with one of the question in Microsoft interview which is as given below:
A function should accept a range( 3 - 21 ) and it should print all the consecutive numbers combinations to form each number as given below:
3 = 1+2
5 = 2+3
6 = 1+2+3
7 = 3+4
9 = 4+5
10 = 1+2+3+4
11 = 5+6
12 = 3+4+5
13 = 6+7
14 = 2+3+4+5
15 = 1+2+3+4+5
17 = 8+9
18 = 5+6+7
19 = 9+10
20 = 2+3+4+5+6
21 = 10+11
21 = 1+2+3+4+5+6
could you please help me in forming this sequence in C#?
Thanks,
Mahesh
So here is a straightforward/naive answer (in C++, and not tested; but you should be able to translate). It uses the fact that
1 + 2 + ... + n = n(n+1)/2,
which you have probably seen before. There are lots of easy optimisations that can be made here which I have omitted for clarity.
void WriteAsSums (int n)
{
for (int i = 0; i < n; i++)
{
for (int j = i; j < n; j++)
{
if (n = (j * (j+1) - i * (i+1))/2) // then n = (i+1) + (i+2) + ... + (j-1) + j
{
std::cout << n << " = ";
for (int k = i + 1; k <= j; k++)
{
std::cout << k;
if (k != j) // this is not the interesting bit
std::cout << std::endl;
else
std::cout << " + ";
}
}
}
}
}
This is some pseudo code to find all the combinations if any exists:
function consecutive_numbers(n, m)
list = [] // empty list
list.push_back(m)
while m != n
if m > n
first = list.remove_first
m -= first
else
last = list.last_element
if last <= 1
return []
end
list.push_back(last - 1)
m += last - 1
end
end
return list
end
function all_consecutive_numbers(n)
m = n / 2 + 1
a = consecutive_numbers(n, m)
while a != []
print_combination(n, a)
m = a.first - 1
a = consecutive_numbers(n, m)
end
end
function print_combination(n, a)
print(n + " = ")
print(a.remove_first)
foreach element in a
print(" + " + element)
end
print("\n")
end
A call to all_consecutive_numbers(21) would print:
21 = 11 + 10
21 = 8 + 7 + 6
21 = 6 + 5 + 4 + 3 + 2 + 1
I tested it in ruby (code here) and it seems to work. I'm sure the basic idea could easily be implemented in C# as well.
I like this problem. Here is a slick and slightly mysterious O(n) solution:
void DisplaySum (int n, int a, int b)
{
std::cout << n << " = ";
for (int i = a; i < b; i++) std::cout << i << " + ";
std::cout << b;
}
void WriteAsSums (int n)
{
N = 2*n;
for (int i = 1; i < N; i++)
{
if (~(N%i))
{
int j = N/i;
if (j+i%2)
{
int a = (j+i-1)/2;
int b = (j-i+1)/2;
if (a>0 & a<b) // exclude trivial & negative solutions
DisplaySum(n,a,b);
}
}
}
}
Here's something in Groovy, you should be able to understand what's going on. It's not the most efficient code and doesn't create the answers in the order you cite in your question (you seem to be missing some though) but it might give you a start.
def f(a,b) {
for (i in a..b) {
for (j in 1..i/2) {
def (sum, str, k) = [ 0, "", j ]
while (sum < i) {
sum += k
str += "+$k"
k++
}
if (sum == i) println "$i=${str[1..-1]}"
}
}
}
Output for f(3,21) is:
3=1+2
5=2+3
6=1+2+3
7=3+4
9=2+3+4
9=4+5
10=1+2+3+4
11=5+6
12=3+4+5
13=6+7
14=2+3+4+5
15=1+2+3+4+5
15=4+5+6
15=7+8
17=8+9
18=3+4+5+6
18=5+6+7
19=9+10
20=2+3+4+5+6
21=1+2+3+4+5+6
21=6+7+8
21=10+11
Hope this helps. It kind of conforms to the tenet of doing the simplest thing that could possibly work.
if we slice a into 2 digit, then a = b + (b+1) = 2*b + (0+1)
if we slice a into 3 digit, then a = b + (b+1) + (b+2) = 3*b + (0+1+2)
...
if we slice a into n digit, then a = b + (b+1) +...+ (b+n) = nb + (0+1+n-1)
the last result is a = nb + n*(n-1)/2, a,b,n are all ints.
so O(N) Algorithm is:
void seq_sum(int a)
{
// start from 2 digits
int n=2;
while(1)
{
int value = a-n*(n-1)/2;
if(value < 0)
break;
// meet the quotation we deduct
if( value%n == 0 )
{
int b=value/n;
// omit the print stage
print("......");
}
n++;
}
}