Post Reply 
Programming Challenge!
02-19-2017, 10:35 PM (This post was last modified: 02-19-2017 11:00 PM by toml_12953.)
Post: #1
Programming Challenge!
My job was to convert old-style BASIC programs to the Prime's HPPL.
Below is an example from Problems for Computer Solution by Stephen J. Rogowski. It is a classic example of spaghetti code that I converted to work on the Prime. Just so you don't think I'm trying to get someone here to do my work for me, I will post another message with my solution. If you want to do the mental exercise, don't look at the solution post before trying the conversion yourself! That would spoil the fun!

Tom L

Code:
10 DIM X(126),K(2)
20 DEF FNA(X,Y,Z)=X*SIN(Y*0.01745329)*Z-16*Z^2
30 PRINT "INPUT MUZZLE VELOCITY (FT/SEC) AND ANGLE (DEGREES)"
40 LET F2=0
50 INPUT M,A
60 LET X(0)=0
70 FOR T=0.2 TO 25 STEP 0.2
80 LET L=INT(5*T+0.001)
90 LET X(L)=FNA(M,A,T)
100 IF X(L)<0 THEN GOTO 150
110 IF X(L)-X(L-1)<=0 AND F2=0 THEN GOTO 250 ELSE GOTO 350
120 LET K(1)=X(L-2)
130 LET W4=T-0.4+J
140 GOTO 280
150 LET W=L-1
160 FOR J=0.01 TO 0.2 STEP 0.01
170 LET K(1)=FNA(M,A,T-0.2+J)
180 IF K(1)<0 THEN GOTO 200
190 NEXT J
200 PRINT "MAXIMUM HEIGHT IS ";K1;" FEET"
210 LET Y=M*COS(A*0.01745329)*(T-0.2+J-0.01)
220 PRINT "RANGE IS ";Y;" FEET"
230 PRINT "TOTAL TIME AIRBORNE IS ";T+J-0.01;" SECONDS"
240 GOTO 360
250 IF X(L-1)-X(L-2)<X(L)-X(L-1) THEN GOTO 120
260 LET K(1)=X(L-1)
270 LET W4=T-0.2+J
280 LET F2=1
290 FOR J=0.01 TO 0.2 STEP 0.01
300 LET K(2)=FNA(M,A,W4)
310 IF K(1)-K(2)<=0 THEN GOTO 340
320 LET K(1)=K(2)
330 NEXT J
340 LET K1=MAX(K(1),K(2))
350 NEXT T
360 IF K1+10>60 THEN GOTO 470 ELSE LET M1=1
370 FOR D=1 TO 62
380 PRINT TAB(11);"+";
390 NEXT D
395 PRINT
400 PRINT "0";TAB(11);"+"
410 FOR N=1 TO W
420 PRINT 0.2*N*M*COS(A*0.01745329);TAB(11);"+";TAB(X(N)*M1+11);"*"
430 NEXT N
440 PRINT "ANYMORE (YES OR NO)";
450 INPUT A$ 
460 IF UCASE$(A$)="YES" THEN GOTO 30 ELSE GOTO 500
470 LET M1=1/(INT(K1/60+1))
480 PRINT "SCALE OF HEIGHT IS 1 SPACE = ";1/M1;" FEET"
490 GOTO 370
500 END

Tom L
Cui bono?
Find all posts by this user
Quote this message in a reply
02-19-2017, 10:40 PM (This post was last modified: 02-19-2017 10:57 PM by toml_12953.)
Post: #2
RE: Programming Challenge! A Solution
Here's a solution to the problem that tries to keep as close to the original as possible. It uses the same variable names and techniques as the original. If you run the original in BASIC and the below HPPL program, you'll see that they give the same answers. I hope you had fun!

Tom L

Code:
FNA(X,Y,Z)
BEGIN
  RETURN X*SIN(Y*0.01745329)*Z-16*Z^2;
END;

EXPORT PROJECTILE()
BEGIN
  LOCAL X,K,F2,W4,K1,ANS,TMP,M1;
  X:=MAKELIST(0,C,0,126);K:=MAKELIST(0,C,0,2);
  PRINT();
  //REPEAT
    F2:=0;
    INPUT({M,A},"MUZZLE VELOCITY AND ANGLE",{"FT/SEC: ","DEGREES: "});
    X(1):=0;
    FOR T:=0.2 TO 25 STEP 0.2 DO
      L:=IP(5*T+0.001);
      X(L):=FNA(M,A,T);
      IF X(L)<0 THEN 
        BREAK;
      END;
      IF X(L)-X(L-1)<=0 AND F2=0 THEN
        IF X(L-1)-X(L-2)<X(L)-X(L-1) THEN 
          K(1):=X(L-2);
          W4:=T-0.4+J;
        ELSE
          K(1):=X(L-1);
          W4:=T-0.2+J;
        END;
        F2:=1;
        FOR J:=0.01 TO 0.2 STEP 0.01 DO
          K(2):=FNA(M,A,W4);
          IF K(1)-K(2)<=0 THEN 
            BREAK;
          END;
          K(1)=K(2);
        END;
        K1:=MAX(K(1),K(2));
      END;
    END;
    W:=L-1;
    FOR J:=0.01 TO 0.2 STEP 0.01 DO
      K(2):=FNA(M,A,T-0.2+J);
      IF K(2)<0 THEN 
        BREAK;
      END;  
    END;
    PRINT("MAXIMUM HEIGHT IS "+K1+" FEET");
    Y:=M*COS(A*0.01745329)*(T-0.2+J-0.01);
    PRINT("RANGE IS "+Y+" FEET");
    PRINT("TOTAL TIME AIRBORNE IS "+(T+J-0.01)+" SECONDS");
    IF K1+14>60 THEN 
      M1:=1/(IP(K1/60+1));
      PRINT("SCALE OF HEIGHT IS 1 SPACE = "+1/M1+" FEET");
    ELSE 
      M1:=1;
    END;
    TMP:=TAB(14);
    FOR D:=1 TO 30 DO
      TMP:=TMP+"+";
    END;
    PRINT(TMP);
    PRINT("0"+TAB(14)+"+");
    FOR N:=1 TO W DO  
      PRINT(STRING(0.2*N*M*COS(A*0.01745329),2,4)+" +"+TAB(X(N)*M1)+"*");
    END;
    //INPUT({{ANS,[2]}},"ANYMORE (YES OR NO)?"); 
  //UNTIL UPPER(ANS) == "NO";

END;

Here's the TAB Function:
Code:
EXPORT TAB(X)
BEGIN
  LOCAL I,T;
  T:="";
  FOR I:=1 TO X DO
    T:=T+" ";
  END;
  RETURN T;
END;

Tom L
Cui bono?
Find all posts by this user
Quote this message in a reply
02-20-2017, 04:39 PM
Post: #3
RE: Programming Challenge!
After a quick glance at the BASIC code, I wondered if you may be better off looping on L from 1 to 125 (or 126?) and then calculating T to be T:=T+0.2; or T:=L/5. This avoids having to round off with IP().

Graph 3D | QPI | SolveSys
Find all posts by this user
Quote this message in a reply
02-20-2017, 10:52 PM (This post was last modified: 02-20-2017 10:55 PM by toml_12953.)
Post: #4
RE: Programming Challenge!
(02-20-2017 04:39 PM)Han Wrote:  After a quick glance at the BASIC code, I wondered if you may be better off looping on L from 1 to 125 (or 126?) and then calculating T to be T:=T+0.2; or T:=L/5. This avoids having to round off with IP().

That's true but since I was trying to stay as close as possible to the original, I opted to keep the same looping. I also wrote a much better version that uses an algebraic technique rather than this iterative solution. It's much shorter and more accurate but I didn't use it for the same reason as above.

Code:
FNH(V,T)
BEGIN
  RETURN -16*T^2+V*T;
END;

EXPORT PROJECTILE()
BEGIN
  PRINT();
  LOCAL VERT,HORIZ,T2,MAXHT,SCALE,AIRTIME,RANGE,HEIGHT;
  LOCAL DIST,V0,HEIGHT,OMODE;
  OMODE:=HAngle; //Save current angle mode
  HAngle:=1; // Set degree mode
  INPUT({V0,A},"MUZZLE VELOCITY AND ANGLE",{"V FT/SEC: ","A DEGREES: "});
  VERT:=V0*SIN(A);
  HORIZ:=V0*COS(A);
  T2:=VERT/32.1740485564;
  MAXHT:=FNH(VERT,T2);
  SCALE:=IP(MAXHT/60+1);
  AIRTIME:=T2*2;
  RANGE:=HORIZ*AIRTIME;
  PRINT("MAXIMUM HEIGHT IS "+MAXHT);
  PRINT("RANGE IS "+RANGE);
  PRINT("TOTAL TIME AIRBORNE IS "+AIRTIME+" SECONDS");
  PRINT("SCALE OF HEIGHT IS 1 SPACE = "+SCALE+" FEET");
  PRINT(TAB(14)+"++++++++++++++++++++++++++++++");
  PRINT(TAB(9)+"0   +");
  T:=0.2;
  REPEAT
    HEIGHT:=FNH(VERT,T);
    DIST:=HORIZ*T;
    PRINT(ROUND(DIST,4)+" +"+TAB(HEIGHT/SCALE)+"*");
    T:=T+AIRTIME/26;
  UNTIL FNH(VERT,T)<0;

  HAngle:=OMODE; // Reset original angle mode

END;

Tom L

Tom L
Cui bono?
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)