Skip to content

Commit 61caecc

Browse files
authored
Add Zeckendorf in Commodore Basic (#5331)
1 parent f2f4bee commit 61caecc

1 file changed

Lines changed: 112 additions & 0 deletions

File tree

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
5 REM Input N
2+
10 GOSUB 1000
3+
20 IF V = 0 OR C >=0 OR NR < 0 THEN GOTO 110: REM invalid or not end character
4+
30 N = NR
5+
35 REM Max Fibonacci numbers than can be displayed as integers
6+
40 MF = 43
7+
50 DIM F(MF - 1)
8+
55 REM Max Zeckendorf values
9+
60 MZ = INT((MF + 1) / 2)
10+
70 DIM A(MZ - 1)
11+
75 REM Get Zeckendorf values
12+
80 GOSUB 2000
13+
85 REM Display results
14+
90 GOSUB 3500
15+
100 END
16+
110 PRINT "Usage: please input a non-negative integer"
17+
120 END
18+
1000 REM Read input value one character at a time since Commodore BASIC
19+
1001 REM has trouble reading line from stdin properly
20+
1002 REM NR = number
21+
1003 REM V = 1 if valid number, 0 otherwise
22+
1004 REM C = -2 if end of input, -1 if end of value,
23+
1005 REM 32 if whitespace, ASCII code of last character otherwise
24+
1006 REM Initialize
25+
1010 NR = 0
26+
1020 V = 0
27+
1030 S = 1
28+
1035 REM Loop while leading spaces
29+
1040 GOSUB 1500
30+
1050 IF C = 43 OR C = 45 THEN GOTO 1100: REM + or -
31+
1060 IF C >= 48 AND C <= 57 THEN GOTO 1150: REM 0 to 9
32+
1070 IF C = 32 THEN GOTO 1040: REM whitespace
33+
1080 RETURN: REM other character
34+
1085 REM Loop while sign
35+
1090 GOSUB 1500
36+
1100 IF C = 43 THEN GOTO 1090: REM +
37+
1110 IF C >= 48 AND C <= 57 THEN GOTO 1150: REM 0 to 9
38+
1120 IF C <> 45 THEN RETURN: REM not -
39+
1130 S = -S
40+
1140 GOTO 1090
41+
1145 REM Set valid flag
42+
1150 V = 1
43+
1155 REM Loop while digits
44+
1160 NR = (ABS(NR) * 10 + C - 48) * S
45+
1170 GOSUB 1500
46+
1180 IF C >= 48 AND C <= 57 THEN GOTO 1160: REM 0 to 9
47+
1185 REM Loop while trailing spaces
48+
1190 IF C < 0 OR C <> 32 THEN RETURN: REM end character or not whitespace
49+
1200 GOSUB 1500
50+
1210 GOTO 1180
51+
1500 REM Get input character
52+
1501 REM A$ = input character
53+
1502 REM C = One of the following:
54+
1502 REM - -1 if end of value
55+
1503 REM - -2 if end of input
56+
1504 REM - 32 if whitespace
57+
1505 REM - ASCII code otherwise
58+
1510 GET A$
59+
1520 C = ASC(A$)
60+
1530 IF C = 13 THEN C = -1
61+
1540 IF C = 255 THEN C = -2
62+
1550 IF C = 9 OR C = 10 THEN C = 32
63+
1560 RETURN
64+
2000 REM Get Zeckendorf values
65+
2001 REM N = input number
66+
2002 REM A = array containing Fibonacci numbers that add up to N
67+
2003 REM NA = size of array
68+
2005 REM Get Fibonacci numbers up to an including N
69+
2010 GOSUB 3000
70+
2015 REM Get Fibonacci numbers that add up to N
71+
2020 K = NF - 1
72+
2030 NA = 0
73+
2040 IF K < 0 OR N < 1 THEN GOTO 2130
74+
2045 REM Get Fibonacci value
75+
2050 FV = F(K)
76+
2060 K = K - 1
77+
2065 REM If Too large, get previous Fibonacci value
78+
2070 IF FV > N THEN GOTO 2040
79+
2075 REM Store Fibonacci value and skip previous one
80+
2080 A(NA) = FV
81+
2090 NA = NA + 1
82+
2100 K = K - 1
83+
2110 N = N - FV
84+
2120 GOTO 2040
85+
2130 RETURN
86+
3000 REM Fibonacci numbers up to an including N
87+
3001 REM N = input number
88+
3002 REM F = array of Fibonacci
89+
3003 REM NF = number of Fibonacci numbers
90+
3010 FA = 1
91+
3020 FB = 2
92+
3030 NF = 0
93+
3040 IF FA > N OR NF >= MF THEN GOTO 3110
94+
3050 F(NF) = FA
95+
3060 NF = NF + 1
96+
3070 FC = FA + FB
97+
3080 FA = FB
98+
3090 FB = FC
99+
3100 GOTO 3040
100+
3110 RETURN
101+
3500 REM Display array
102+
3501 REM A contains array
103+
3502 REM NA contains size of array
104+
3510 IF NA < 1 THEN GOTO 3590
105+
3520 FOR I = 0 TO NA - 1
106+
3530 S$ = STR$(A(I))
107+
3540 IF A(I) >= 0 THEN S$ = MID$(S$, 2): REM strip leading space
108+
3550 PRINT S$;
109+
3560 IF I < (NA - 1) THEN PRINT ", ";
110+
3570 NEXT I
111+
3580 PRINT
112+
3590 RETURN

0 commit comments

Comments
 (0)