patternModerate
Commodore-FizzBuzz
Viewed 0 times
commodorefizzbuzzstackoverflow
Problem
I felt nostalgic recently, and decided to install a Commodore-64 emulator. C-64 BASIC 2.0 is the first language I ever programmed in... some 20 years ago (yes, C-64 was already well beyond deprecated by then).
Implementing a simple fizzbuzz in such a limited language, and un-learning pretty much everything I learned in at least the last decade to write code in a procedural paradigm with
Here's the code - I limited the output to 15 values, so as to be able to see the full sequence on-screen.
Output:
This will sound very weird, but it's actually a pretty big concern with C-64 code, so don't laugh (ok, laugh, but it's not a joke): how's my line numbering?
I tried to write the code in such a way that it would be easy to extend into prompting the user for
I lost quite a lot of the language's capabilities over the years (the biggest challenge was really to stop thinking in terms
Implementing a simple fizzbuzz in such a limited language, and un-learning pretty much everything I learned in at least the last decade to write code in a procedural paradigm with
GOTO and line numbers, was much more fun (and tricky!) than I had imagined.Here's the code - I limited the output to 15 values, so as to be able to see the full sequence on-screen.
10 GOSUB 100
20 GOSUB 1000
99 END
100 REM CLEAR SCREEN
110 PRINT CHR$(147)
120 RETURN
200 REM MODULO
210 LET MOD% = V%-INT(V%/FB%)*FB%
220 RETURN
1000 REM INIT VARIABLES
1010 LET FIZZ$ = "FIZZ"
1011 LET BUZZ$ = "BUZZ"
1020 LET FIZZ% = 3
1021 LET BUZZ% = 5
1030 LET MIN% = 1
1031 LET MAX% = 15
1100 PRINT FIZZ$ + ":" + STR$(FIZZ%)
1101 PRINT BUZZ$ + ":" + STR(BUZZ%)
1102 PRINT FIZZ$ + BUZZ$ + ":" + STR$(FIZZ%*BUZZ%)
1105 PRINT
2000 REM ACTUAL FIZZBUZZ LOOP
2010 FOR X = MIN% TO MAX%
2015 LET RESULT% = STR$(X)
2020 LET FB% = FIZZ%*BUZZ%
2021 LET V% = X
2024 GOSUB 200
2025 IF MOD%=0 THEN LET RESULT$=FIZZ$+BUZZ$ : GOTO 2050
2030 LET FB% = FIZZ%
2031 GOSUB 200
2035 IF MOD%=0 THEN LET RESULT$=FIZZ$ : GOTO 2050
2040 LET FB% = BUZZ%
2041 GOSUB 200
2045 IF MOD%=0 THEN LET RESULT$=BUZZ$ : GOTO 2050
2050 PRINT RESULT$
2090 NEXT X
2099 RETURNOutput:
This will sound very weird, but it's actually a pretty big concern with C-64 code, so don't laugh (ok, laugh, but it's not a joke): how's my line numbering?
I tried to write the code in such a way that it would be easy to extend into prompting the user for
MIN% and MAX% values, but also for FIZZ% and BUZZ%; I was also concerned with implementing a "modulo" subroutine, since I knew that logic would have to be used in 3 places.I lost quite a lot of the language's capabilities over the years (the biggest challenge was really to stop thinking in terms
Solution
First off, thank you for reminding me of the good old days !
BUG alert
Well, it is not really a bug, but as you know the
but you are assigning the result of
So changing
Neither
The
Defining and calling a "function", will reduce some of your
So I would suggest to define 3 functions like so
Style is important in a procedurale language.
With the extensive use of
By adding an "empty"
Like so
EDIT
Take into account the very good hint by @psmears given in the comments
Another way to do this (which can look cleaner than a REM with no text) is to leave a line with just a ":" on it.
Using much more
Applying this would result in
the code lines which aren't used anymore or have been moved
btw, I didn't test the resulting program because the emulator won't let me load a file. Pasting code isn't working either. I tested the MOD stuff and it worked.
BUG alert
Well, it is not really a bug, but as you know the
% suffix indicates that the variable will be an integer2010 FOR X = MIN% TO MAX%
2015 LET RESULT% = STR$(X)
2020 LET FB% = FIZZ%*BUZZ%but you are assigning the result of
STR$() which is a string to it. Be happy that commodore basic just forgive such things.So changing
RESULT% to RESULT$ will help, but nevertheless this STR$() method is called to often because if the modulo returns 0 the value is overwritten. So placing this on the line above the PRINT RESULT$ will make it more shiny.Neither
FIZZ% nor BUZZ% will change so calling LET FB% = FIZZ%*BUZZ% inside the loop is a bad idea. This FB% variable should be declared and initialized where the other variables are declared and initialized.LETThe
LET comand to assign values to variables can be omitted because you can assign values to variables without it. In addition if you omit them you will save some memory and reduce the execution time.DEF FN and FNDefining and calling a "function", will reduce some of your
GOSUB calls and will make your code more pretty.So I would suggest to define 3 functions like so
5 DEF FN FIZZMOD(V) = V-INT(V/FIZZ%)*FIZZ%
6 DEF FN BUZZMOD(V) = V-INT(V/BUZZ%)*BUZZ%
7 DEF FN FBMOD(V) = V-INT(V/FB%)*FB%Style is important in a procedurale language.
With the extensive use of
GOTO and GOSUB it is very important to distinguish between the parts of the program.By adding an "empty"
REM in front and after the "defining" REM of a "sub" it is easier to grasp what it is about. It then looks like you would group logical parts by a new line which unfortunately can't be done by only a line number.Like so
200 REM
201 REM MODULO
202 REM
210 LET MOD% = V%-INT(V%/FB%)*FB%
220 RETURNEDIT
Take into account the very good hint by @psmears given in the comments
Another way to do this (which can look cleaner than a REM with no text) is to leave a line with just a ":" on it.
Using much more
REM statements at the top indicating what for instance GOSUB 100 will doApplying this would result in
1 REM GOSUB 100 > CLEAR SCREEN
2 REM GOSUB 1000 > INIT VARIABLES
3 REM GOSUB 1100 > FIZZ BUZZ
4 REM
5 DEF FN FIZZMOD(V) = V-INT(V/FIZZ%)*FIZZ%
6 DEF FN BUZZMOD(V) = V-INT(V/BUZZ%)*BUZZ%
7 DEF FN FBMOD(V) = V-INT(V/FB%)*FB%
9 REM
10 GOSUB 100
20 GOSUB 1000
30 GOSUB 1100
99 END
100 REM
101 REM CLEAR SCREEN
102 REM
110 PRINT CHR$(147)
120 RETURN
200 REM
1000 REM
1001 REM INIT VARIABLES
1002 REM
1010 FIZZ$ = "FIZZ"
1011 BUZZ$ = "BUZZ"
1020 FIZZ% = 3
1021 BUZZ% = 5
1022 FB% = FIZZ% * BUZZ%
1030 MIN% = 1
1031 MAX% = 15
1032 RETURN
1090 REM
1091 REM FIZZ BUZZ
1092 REM
1100 PRINT FIZZ$ + ":" + STR$(FIZZ%)
1101 PRINT BUZZ$ + ":" + STR(BUZZ%)
1102 PRINT FIZZ$ + BUZZ$ + ":" + STR$(FB%)
1105 PRINT
2000 REM ACTUAL FIZZBUZZ LOOP
2010 FOR X = MIN% TO MAX%
2025 IF FN FBMOD(X)=0 THEN RESULT$=FIZZ$+BUZZ$ : GOTO 2050
2035 IF FN FIZZMOD(X)=0 THEN RESULT$=FIZZ$ : GOTO 2050
2045 IF FN BUZZMOD(X)=0 THEN RESULT$=BUZZ$ : GOTO 2050
2049 RESULT$ = STR$(X)
2050 PRINT RESULT$
2090 NEXT X
2099 RETURNthe code lines which aren't used anymore or have been moved
2020 FB% = FIZZ%*BUZZ%
2021 LET V% = X
2024 GOSUB 200
2030 REM LET FB% = FIZZ%
2031 REM GOSUB 200
2040 REM LET FB% = BUZZ%
2041 REM GOSUB 200
2015 RESULT$ = STR$(X)btw, I didn't test the resulting program because the emulator won't let me load a file. Pasting code isn't working either. I tested the MOD stuff and it worked.
Code Snippets
2010 FOR X = MIN% TO MAX%
2015 LET RESULT% = STR$(X)
2020 LET FB% = FIZZ%*BUZZ%5 DEF FN FIZZMOD(V) = V-INT(V/FIZZ%)*FIZZ%
6 DEF FN BUZZMOD(V) = V-INT(V/BUZZ%)*BUZZ%
7 DEF FN FBMOD(V) = V-INT(V/FB%)*FB%200 REM
201 REM MODULO
202 REM
210 LET MOD% = V%-INT(V%/FB%)*FB%
220 RETURN1 REM GOSUB 100 > CLEAR SCREEN
2 REM GOSUB 1000 > INIT VARIABLES
3 REM GOSUB 1100 > FIZZ BUZZ
4 REM
5 DEF FN FIZZMOD(V) = V-INT(V/FIZZ%)*FIZZ%
6 DEF FN BUZZMOD(V) = V-INT(V/BUZZ%)*BUZZ%
7 DEF FN FBMOD(V) = V-INT(V/FB%)*FB%
9 REM
10 GOSUB 100
20 GOSUB 1000
30 GOSUB 1100
99 END
100 REM
101 REM CLEAR SCREEN
102 REM
110 PRINT CHR$(147)
120 RETURN
200 REM
1000 REM
1001 REM INIT VARIABLES
1002 REM
1010 FIZZ$ = "FIZZ"
1011 BUZZ$ = "BUZZ"
1020 FIZZ% = 3
1021 BUZZ% = 5
1022 FB% = FIZZ% * BUZZ%
1030 MIN% = 1
1031 MAX% = 15
1032 RETURN
1090 REM
1091 REM FIZZ BUZZ
1092 REM
1100 PRINT FIZZ$ + ":" + STR$(FIZZ%)
1101 PRINT BUZZ$ + ":" + STR(BUZZ%)
1102 PRINT FIZZ$ + BUZZ$ + ":" + STR$(FB%)
1105 PRINT
2000 REM ACTUAL FIZZBUZZ LOOP
2010 FOR X = MIN% TO MAX%
2025 IF FN FBMOD(X)=0 THEN RESULT$=FIZZ$+BUZZ$ : GOTO 2050
2035 IF FN FIZZMOD(X)=0 THEN RESULT$=FIZZ$ : GOTO 2050
2045 IF FN BUZZMOD(X)=0 THEN RESULT$=BUZZ$ : GOTO 2050
2049 RESULT$ = STR$(X)
2050 PRINT RESULT$
2090 NEXT X
2099 RETURN2020 FB% = FIZZ%*BUZZ%
2021 LET V% = X
2024 GOSUB 200
2030 REM LET FB% = FIZZ%
2031 REM GOSUB 200
2040 REM LET FB% = BUZZ%
2041 REM GOSUB 200
2015 RESULT$ = STR$(X)Context
StackExchange Code Review Q#102640, answer score: 14
Revisions (0)
No revisions yet.