I am facing the issue regarding ALGOL program - algol

begin
% computes factorial n iteratively %
integer procedure factorial( integer value n ) ;
if n < 2
then 1
else begin
integer f;
f := 2;
for i := 3 until n do f := f * i;
f
end factorial ;
for t := 0 until 10 do write( "factorial: ", t, factorial( t ) );
end.
I have compiled the code but everytime its saying the error. See
$a68g main.alg
5 then 1
1
a68g: syntax error: 1: possibly a missing or erroneous separator nearby.
9 for i := 3 until n do f := f * i;
1
a68g: syntax error: 1: possibly a missing or erroneous separator nearby.
13 for t := 0 until 10 do write( "factorial: ", t, factorial( t ) );
1
a68g: syntax error: 1: possibly a missing or erroneous separator nearby.

You are using an Algol 68 compiler, but the code is not written in Algol 68.
Algol 60 and Algol 68 are different languages with different syntax.
You would need to translate your code to algol 68 to use a68g or find an algol 6o compiler.

Try marst... " MARST is an Algol-to-C translator. It automatically translates programs written on the algorithmic language Algol 60 to the C programming language. "

If you were to code this in Algol 68, a possible solution could be
BEGIN FOR t TO 10
DO OP F = (INT n) INT: (n < 1 | 1 | n * F (n - 1));
print ((F t, new line))
OD
END

Related

Solving Equations with (wx)Maxima: Control stack exhausted

Solving Equations with (wx)Maxima: Control stack exhausted
I'm trying to solve equations with (wx)Maxima: formulate the equation, then let it insert the variables and solve the equation for the missing variable. But I'm having a hard time. Somehow it's having problems in the last line:
Control stack exhausted (no more space for function call frames).
This is probably due to heavily nested or infinitely recursive function
calls, or a tail call that SBCL cannot or has not optimized away.
That's my code:
kill(all);
load(physical_constants);
load(unit);
setunits([kg,m,s,N]);
showtime: false;
α: 30*%pi/180;
/*α: 30*°;*/
masse: 1000*kg;
g: 9.80665*m/(s*s);
b: 0.3*m;
B: 0.5*m;
L: 0.1*m;
F_g: masse*g;
F_H: masse * g;
kill(S, x);
S: solve(0=F_H-2*x*sin(α), x);
S: assoc(x, S);
kill(H, x);
H: solve(0=-F_g+2*x, x);
H: assoc(x, H);
kill(Ly, x);
Ly: solve(tan(α)=x/(B/2), x);
Ly: assoc(x, Ly);
kill(FN, x);
FN: solve(0=H*B/2-x*(L+Ly)+S*sin(α)*B/2+S*cos(α)*Ly, x);
FN: assoc(x, FN);
If I calculate it "directly", it works though:
kill(all);
load(physical_constants);
load(unit);
setunits([kg,m,s,N]);
showtime: false;
kill(FN, x);
FN: solve([α=30*%pi/180, H=196133/40*N,
B=0.5*m, L=0.1*m,
Ly=sqrt(3)/12*m, S=196133/20*N,
0=H*B/2-x*(L+Ly)+S*sin(α)*B/2+S*cos(α)*Ly],
[x, α, H, B, L, Ly, S]);
FN: assoc(x, FN[1]);
FN: float(FN);
(FN) 1934473685/128529*N
Unfortunately the unit package has not been updated in some time. I'll suggest to use instead the package ezunits, in which dimensional quantities are represented with a back quote. To solve equations, try dimensionally which goes through some gyrations to help other functions with dimensional quantities, e.g. dimensionally (solve (...)). (Note that dimensionally isn't documented, I'm sorry for the shortcoming.)
I've modified your program a little to remove some unneeded stuff and also to use rational numbers instead of floats; Maxima is generally more comfortable with rationals and integers than with floats. Here is the program:
linel: 65 $
load(ezunits) $
α: 30*%pi/180;
masse: 1000`kg;
g: rationalize(9.80665)`m/(s*s);
b: 3/10`m;
B: 5/10`m;
L: 1/10`m;
F_g: masse*g;
F_H: masse * g;
S: dimensionally (solve(0=F_H-2*x*sin(α), x));
S: assoc(x, S);
Ly: dimensionally (solve(tan(α)=x/(B/2), x));
Ly: assoc(x, Ly);
FN: dimensionally (solve(0=H*B/2-x*(L+Ly)+S*sin(α)*B/2+S*cos(α)*Ly, x));
FN: assoc(x, FN);
subst (x = S, F_H-2*x*sin(α));
subst (x = Ly, tan(α)=x/(B/2));
subst (x = FN, H*B/2-x*(L+Ly)+S*sin(α)*B/2+S*cos(α)*Ly);
ratsimp (expand (%));
and here is the output I get. Note that I substituted the solutions back into the equations to verify them. It looks like it worked as expected.
(%i2) linel:65
(%i3) load(ezunits)
(%i4) α:(30*%pi)/180
%pi
(%o4) ---
6
(%i5) masse:1000 ` kg
(%o5) 1000 ` kg
(%i6) g:rationalize(9.80665) ` m/(s*s)
5520653160719109 m
(%o6) ---------------- ` --
562949953421312 2
s
(%i7) b:3/10 ` m
3
(%o7) -- ` m
10
(%i8) B:5/10 ` m
1
(%o8) - ` m
2
(%i9) L:1/10 ` m
1
(%o9) -- ` m
10
(%i10) F_g:masse*g
690081645089888625 kg m
(%o10) ------------------ ` ----
70368744177664 2
s
(%i11) F_H:masse*g
690081645089888625 kg m
(%o11) ------------------ ` ----
70368744177664 2
s
(%i12) S:dimensionally(solve(0 = F_H-2*x*sin(α),x))
690081645089888625 kg m
(%o12) [x = ------------------ ` ----]
70368744177664 2
s
(%i13) S:assoc(x,S)
690081645089888625 kg m
(%o13) ------------------ ` ----
70368744177664 2
s
(%i14) Ly:dimensionally(solve(tan(α) = x/(B/2),x))
1
(%o14) [x = --------- ` m]
4 sqrt(3)
(%i15) Ly:assoc(x,Ly)
1
(%o15) --------- ` m
4 sqrt(3)
(%i16) FN:dimensionally(solve(0 = (H*B)/2-x*(L+Ly)
+(S*sin(α)*B)/2
+S*cos(α)*Ly,x))
1 1
(%o16) [x = (----------------------------------------- ` --)
140737488355328 sqrt(3) + 351843720888320 2
s
2
(351843720888320 sqrt(3) H ` s
3/2
+ 1150136075149814375 3 ` kg m)]
(%i17) FN:assoc(x,FN)
1 1
(%o17) (----------------------------------------- ` --)
140737488355328 sqrt(3) + 351843720888320 2
s
2
(351843720888320 sqrt(3) H ` s
3/2
+ 1150136075149814375 3 ` kg m)
(%i18) subst(x = S,F_H-2*x*sin(α))
kg m
(%o18) 0 ` ----
2
s
(%i19) subst(x = Ly,tan(α) = x/(B/2))
1 1
(%o19) ------- = -------
sqrt(3) sqrt(3)
(%i20) subst(x = FN,(H*B)/2-x*(L+Ly)+(S*sin(α)*B)/2+S*cos(α)*Ly)
1 1
(- ---------) - --
4 sqrt(3) 10 1
(%o20) ((----------------------------------------- ` --)
140737488355328 sqrt(3) + 351843720888320 2
s
2
(351843720888320 sqrt(3) H ` s
3/2 H
+ 1150136075149814375 3 ` kg m) + -) ` m
4
2
690081645089888625 kg m
+ ------------------ ` -----
281474976710656 2
s
(%i21) ratsimp(expand(%))
2
kg m
(%o21) 0 ` -----
2
s
EDIT. About converting kg*m/s^2 to N, you can apply the double back quote operator. For example:
(%i25) F_g `` N
690081645089888625
(%o25) ------------------ ` N
70368744177664
By the way, to convert back to floats, you can apply float:
(%i26) float(%)
(%o26) 9806.649999999998 ` N
Converting FN to N is a little more involved, since it's a more complex expression, especially because of H which doesn't have units attached to it yet. Some inspection seems to show the units of H must be kg*m/s^2. I'll apply declare_units to say that's what are the units of H. Then I'll convert FN to N.
(%i27) declare_units(H,(kg*m)/s^2)
kg m
(%o27) ----
2
s
(%i28) FN `` N
351843720888320 sqrt(3) qty(H)
(%o28) (-----------------------------------------
140737488355328 sqrt(3) + 351843720888320
3/2
1150136075149814375 3
+ -----------------------------------------) ` N
140737488355328 sqrt(3) + 351843720888320
(%i29) float(%)
(%o29) (1.023174629940149 qty(H) + 10033.91548470256) ` N
The notation qty(H) represents the unspecified quantity of H. One could also just subst(H = 100 ` kg*m/s^2, FN) (or any quantity, not just 100) and go from there.

Substitute variable?

I'm trying to substitute L with Lα:
f(x) := c * (x + L);
c: L;
f(x), L: Lα;
I expected the output:
Lα * (x + Lα)
instead I got
L * (x + Lα)
Maybe I should define f(x) instead?
kill(all);
define(
f(x),
c * (x + L)
);
c: L;
f(x), L: Lα;
Nope — same result.
Do I substitute L for Lα in a wrong way?
Edit:
Turns out it is expected behaviour, as maxima evavluates expression only once. One can impose "infinite evaluation" via the flag infeval:
f(x), L: La, infeval;
=> La*(x + La)
Another solution is to use subst instead:
subst(
Lα, L, f(x)
);
(source)
You need to add an extra eval step to make this work:
f(x) := c * (x + L);
c: L;
f(x), L: Lα, eval;
Output:
Lα (x + Lα)
Use subst instead of ev.
(%i1) f(x) := c * (x + L)$
(%i2) c: L$
(%i3) subst(L=La,f(x));
(%o3) La (x + La)
But keep in mind that the function continues to be c*(x+L). The symbol c has been bound to L and if you then bind the symbol L to La, c will continue to be bound to L and not to La. Maxima variables work as in Lisp, which might be different to what you are used to in other languages.

creating multiple variables/lists/functions via a loop (Maxima)

below I have listed some ways to create variables/lists/functions via a for loop in Maxima,
but how, via a for loop, to do:
f1(x) := x^1$
f2(x) := x^2$
f3(x) := x^3$
example code:
for i : 1 thru 10 do
(x : concat ('a, i), x :: i)$
[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10];
for i : 1 thru 3 do
(x : concat ('L, i), x :: [(3*i)-2,(3*i)-1,3*i])$
[L1, L2, L3];
/* good, but not quite what I want to do */
for i : 1 thru 3 do
f[i](x) := x^i$
[f[1](2), f[2](2), f[3](2)];
/* is there a way, via a for loop, to create */
f1(x) := x^1$
f2(x) := x^2$
f3(x) := x^3$
[f1(2), f2(2), f3(2)];
EDIT: further code:
/* is there a way, via a for loop, to create */
f(x) := x^1$
g(x) := x^2$
h(x) := x^3$
[f(2), g(2), h(2)];
for tmp1 : 1 thru 10 do
(tmp2 : parse_string(ascii(96+tmp1)), tmp2 :: tmp1)$
[a, b, c, d, e, f, g, h, i, j];
for tmp1 : 1 thru 10 do
(tmp2 : concat(parse_string(ascii(96+tmp1)), tmp1), tmp2 :: tmp1)$
[a1, b2, c3, d4, e5, f6, g7, h8, i9, j10];
EDIT 2: original problems solved (any code improvements/simplifications welcome):
for i : 1 thru 3 do
eval_string(concat("f", i, "(x) := x^", i))$
[f1(2), f2(2), f3(2)];
for i : 1 thru 3 do
eval_string(concat(ascii(96+5+i), "(x) := x^", i))$
[f(2), g(2), h(2)];
sum:0$
for i : 1 thru 3 do
sum:sum + eval_string(concat("f", i, "(2)"))$
sum;
sum:0$
for i : 1 thru 3 do
sum:sum + eval_string(concat(ascii(96+5+i), "(2)"))$
sum;
What is your larger goal here? In general using subscripted symbols e.g. a[1] instead of a1 is to be preferred. When you define a subscripted function, you only define it once, not for every value of the subscript. E.g.
(%i1) f[i](x) := x^i $
(%i2) [f[1], f[2], f[3]];
2 3
(%o2) [lambda([x], x), lambda([x], x ), lambda([x], x )]
(%i3) [f[1](u), f[2](v), f[3](w)];
2 3
(%o3) [u, v , w ]
If that doesn't work for you, maybe you can explain about what you're trying to achieve.
I have collected here, various ways of creating multiple variables/lists/functions via a loop in Maxima,
as an answer to the question, '[f1(2), f2(2), f3(2)]' explicitly answers the original question:
for i : 1 thru 10 do
(x : concat ('a, i), x :: i)$
[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10];
for i : 1 thru 3 do
(x : concat ('L, i), x :: [(3*i)-2,(3*i)-1,3*i])$
[L1, L2, L3];
for tmp1 : 1 thru 10 do
(tmp2 : parse_string(ascii(96+tmp1)), tmp2 :: tmp1)$
[a, b, c, d, e, f, g, h, i, j];
for tmp1 : 1 thru 10 do
(tmp2 : concat(parse_string(ascii(96+tmp1)), tmp1), tmp2 :: tmp1)$
[a1, b2, c3, d4, e5, f6, g7, h8, i9, j10];
for i : 1 thru 3 do
eval_string(concat("f", i, "(x) := x^", i))$
[f1(2), f2(2), f3(2)];
for i : 1 thru 3 do
eval_string(concat(ascii(96+5+i), "(x) := x^", i))$
[f(2), g(2), h(2)];
f[i](x) := x^i$
[f[1], f[2], f[3]];
[f[1](2), f[2](2), f[3](2)];
[f[1](u), f[2](v), f[3](w)];

How many times does the for-loop run?

How many times does the for-loop run?
done <- false
n <- 0
while (n < a-1) and (done = false)
done <- true
for m <- a downto n
if list[m] < list[m - 1] then
tmp <- list[m]
list[m] <- list[m-1]
list[m - 1] <- tmp
done <- false
n <- n + 1
return list
In the worst case, is the answer (n ^ 2 + n) / 2 correct?. Does the while-loop run n+1 times?
If downto includes the value of n, then:
It will run for ((a+1)+a+(a-1)+(a-2)+...+1) times in the worst case. This equals ((a+1)*(a+2))/2.
If downto does not include the value of n, then:
It will run for (a+(a-1)+(a-2)+...+1) times in the worst case. This equals (a*(a+1))/2.
In both cases, the while loop will run a times.

Algorithm to add two digits to the end of a number to calculate a specific modulus?

So, lets say I have a number 123456. 123456 % 97 = 72. How can I determine what two digits need to be added to the end of 123456 such that the new number % 97 = 1? Note--it must always be two digits.
For example, 12345676 % 97 = 1. In this case, I need to add the digits "76" to the end of the number.
(This is for IBAN number calculation.)
x = 123456
x = x * 100
newX = x + 1 + 97 - (x % 97)
Edit: put the 100 in the wrong place
You calc the modulo of 12345600 to 97 and add (97 - that + 1) to that number.
So you get what RoBorg explained whay cleaner above :)
This is the equation that that you need
X = Y -(Number*100 mod y) - 1
where:
Number = 123456
Y = 97
X the number you need
Let’s say we have to receive the number containing 12 digits.
Step 1:
Write any random number of 10 digits, i.e. 2 digits less than needed, e.g. 1234567890 – this is X
Step 2:
X * 100 = 123456789000.
‘123456789000’ - this is Y
Step 3:
Y / 97 = '1272750402.061856'.
'06' – this is Z
Step 4:
97 – Z + 1 = 92.
'92' – this is W
Step 5:
Final Deal Number is X followed by W, i.e. '123456789092'
Examples of accepted numbers:
100000000093
100000000190
100000000287
Etc.
Modulo arithmetic is really not that different from regular arithmetic. The key to solving the kind of problem that you're having is to realize that what you would normally do to solve that problem is still valid (in what follows, any mention of number means integer number):
Say you have
15 + x = 20
The way that you solve this is by realizing that the inverse of 15 under regular addition is -15 then you can write (exploiting commutativity and associativity as we naturally do)
15 + x + (-15) = (15 + (-15)) + x = 0 + x = x = 20 + (-15) = 5
so that your answer is x = 5
Now on to your problem.
Say that N and M are known, and you're looking for x under addition modulo k:
( N + x ) mod k = M
First realize that
( N + x ) mod k = ( ( N mod k ) + ( x mod k ) ) mod k
and for the problem to make sense
M mod k = M
and
x mod k = x
so that by letting
N mod k = N_k
and
( a + b ) mod k = a +_k b
you have
N_k +_k x = M
which means that what you need is the inverse of N_k under +_k. This is actually pretty simple because the inverse under +_k is whatever satisfies this equation:
N_k +_k ("-N_k") = 0
which is actually pretty simple because for a number y such that 0 <= y < k
(y + (k - y)) mod k = k mod k = 0
so that
"-N_k" = (k-N_k)
and then
N_k +_k x +_k "-N_k" = N_k +_k "-N_k" +_k x = 0 +_k x = x = M +_k "-N_k" = M +_k ( k - N_k )
so that the solution to
( N + x ) mod k = M
is
x = ( M + ( k - ( N mod k ) ) ) mod k
and for your problem in particular
( 12345600 + x ) % 97 = 1
is solved by
x = ( 1 + ( 97 - ( 12345600 mod 97 ) ) ) mod 97 = 76
Do notice that the requirement that you solution always have two digits is built in as long as k < 100

Resources