Crunch this BASIC code

Basic and Machine Language

Moderator: Moderators

Post Reply
User avatar
Jeff-20
Denial Founder
Posts: 5761
Joined: Wed Dec 31, 1969 6:00 pm

Crunch this BASIC code

Post by Jeff-20 »

I wish I had spent more time paying attention in math class. In primary school, I was in gifted math, but by the time I made it to high school, I was too preoccupied with typical teenage angst. I went back to some of my old programs and found the code below.

I am trying now to crunch this function in BASIC. I want something speedy and memory efficient. My first draft shows my youthful indesretion. I was so objective driven back then...

Code: Select all

1 INPUT A
2 TI$= "000000"
10 IF A=9 THEN Y=Y+15: D=D-1
11 IF A=10 THEN Y=Y+300: D=D-10
12 IF A=11 THEN Y=Y-15: D=D+1
13 IF A=12 THEN Y=Y-300: D=D+10
14 PRINT TI, FRE(0), Y, D
Here's is my first revision:

Code: Select all

1 INPUT A
2 TI$= "000000"
10 T=10-A: IF ABS(T)=1 THEN Y=Y+15*T: D=D-T: GOTO 14
11 T=T+1: Y=Y+300*T: D=D-10*T
14 PRINT TI, FRE(0), Y, D
Of course, lines 1-2 and 14 are only to test the code; they don't need to be crunched.

This compression is slightly faster (TI=2 in the first draft, TI=1 in the second) and saves about 26 bytes.

I combined the four lines into two. Still, my current math skills suck. I know there should be a way to further crunch it (perhaps into one equation without losing speed or memory). Any suggestions? I am pulling a brain freeze at the moment.
High Scores, Links, and Jeff's Basic Games page.
carlsson
Class of '6502
Posts: 5516
Joined: Wed Mar 10, 2004 1:41 am

Post by carlsson »

I tried your original code, and at least in PAL VICE, it runs on one TI click. For better measurement, I put a loop around lines 10-13 that would perform the addition 100 times. A little depending on input, i.e. whether any of the IF statements will evaluate true, I get between 84 and 129 clicks in that loop.

I tried to rewrite the code as one formula, but it takes way much longer time to execute than the IF solution.. something along the lines of

O=SGN(INT(A/2)-A/2) : REM -1 for odd, 0 for even
E=O+1 : REM 0 for odd, 1 for even
S=SGN(A-10.5) : REM -1 for values <= 10, 1 for values >= 11
Y=Y+15*S*O+300*S*E : REM +/- 15 for odd, +/- 300 for even
D=D-1*S*O-10*S*E : REM Ditto, but negated constants

This would take around 260 clicks no matter input, i.e. more than twice the original program. For comparison, your supposedly improved version runs on a steady 126-127 clicks, which is a little bit better worst case than the code you wrote many years ago.
Anders Carlsson

Image Image Image Image Image
User avatar
Mike
Herr VC
Posts: 4901
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Post by Mike »

Hmm,

Code: Select all

1 DIMDY(3),DD(3):FORT=0TO3:READDY(T),DD(T):NEXT:DATA15,-1,300,-10,-15,1,-300,10
2 INPUT A
3 TI$="000000"
the main program reduces to:

Code: Select all

10 Y=Y+DY(A-9):D=D+DD(A-9)
and ends with:

Code: Select all

14 PRINT TI,FRE(0),Y,D
FRE(0) reports 3362 Bytes free (as opposed to your second solution with 3443 Bytes free). So I lose for space, but ... putting in the FOR loop:

Code: Select all

9 FORT=1TO100
11 NEXT
this one needs 75 clicks. Not too bad, I think.

Second try:

Code: Select all

10 S=A-9:Y=Y+(1-(SAND2))*(15+285*(SAND1)):D=D+((SAND2)-1)*(1+9*(SAND1))
FRE(0) reports 3447 Bytes free (4 Bytes more than yours. :) )
...putting in the FOR loop as above:

216 clicks.

Sigh. It all boils down to space vs. time, at least as long as you remain in BASIC. For clarity, your old solution wins anyway.

Michael
bbell
Vic 20 Hobbyist
Posts: 125
Joined: Thu Mar 10, 2005 7:43 am

Post by bbell »

Mike wrote:Hmm,

Code: Select all

1 DIMDY(3),DD(3):FORT=0TO3:READDY(T),DD(T):NEXT:DATA15,-1,300,-10,-15,1,-300,10
2 INPUT A
this one needs 75 clicks. Not too bad, I think.
You could save some space using an integer array to store your data:

Code: Select all

1 DIMY%(3),D%(3):FORT=0TO3:READD%(T),Y%(T):NEXT:DATA15,-1,300,-10,-15,1,-300,10
10 Y=Y+D%(A-9):D=D+D%(A-9)
This saves 15 bytes in my test, but doesn't change the speed significantly (I see only 3 extra cycles).
carlsson
Class of '6502
Posts: 5516
Joined: Wed Mar 10, 2004 1:41 am

Post by carlsson »

Clever thinking, guys! As they say, there is always more than one way to solve a programming problem, although people with very limited programming knowledge often doubt it. I would think 60-70 bytes are worth to sacrifice, if you in theory can make a routine go twice as fast.

However, we don't know if A will be allowed to be outside of the range 9 to 12. If so, the program will return ?BAD SUBSCRIPT for low values of A. It can be avoided with another IF statement:

10 IF A>=9 AND A<=12 THEN Y=Y+DY(A-9):D=D+DD(A-9)

However, this slows down the program:

Jeff's original: 84/129 clicks, ~3417 bytes free
Jeff's optimized: 126 clicks, ~3443 bytes free
Fixed FP: 49/~117 clicks, 3315 bytes free (w/ initializing D and Y)
Fixed INT: 49/~120 clicks, 3333 bytes free (w/ initializing D and Y)

The code below appears a bit obfuscated. I wanted to see if storing constants into memory rather than variable arrays would make any difference. I get the following stats: 50/~180 clicks, 3371 bytes free. Obviously a change for the worse.

Code: Select all

1 FOR T=0 TO 7:READ B:POKE 673+T,B:NEXT:DATA 21,40,19,0,9,0,11,20
2 INPUT A:D=0:Y=0
3 TI$="000000"
9 FOR I=1 TO 100
10 IF A>=9 AND A<=12 THEN Y=Y+PEEK(664+A)*15-300:D=D+PEEK(668+A)-10
13 NEXT
14 PRINT TI,FRE(0),Y,D
Anders Carlsson

Image Image Image Image Image
User avatar
Jeff-20
Denial Founder
Posts: 5761
Joined: Wed Dec 31, 1969 6:00 pm

Post by Jeff-20 »

I really love working with you guys.
I suppose (for me) memory will always be more important than speed in BASIC (even in a game).
High Scores, Links, and Jeff's Basic Games page.
carlsson
Class of '6502
Posts: 5516
Joined: Wed Mar 10, 2004 1:41 am

Post by carlsson »

So, the important question; will A ever fall outside the effective range? I understand the INPUT statement is a placeholder to get a value that would come from elsewhere. If A only has a few possible values, Mike/BBell's solution works unmodified and offers the memory for speed trade-off.
Anders Carlsson

Image Image Image Image Image
Post Reply