39
|
1 # 1) Fibanacci by recursion (fibr) and loop (fibl)
|
|
2 fibr := method(num,
|
|
3 if (num < 1,
|
|
4 return 0,
|
|
5 if (num == 1,
|
|
6 return 1,
|
|
7 prev := fibr(num - 1) ;
|
|
8 prev_prev := fibr(num - 2) ;
|
|
9 return prev + prev_prev
|
|
10 )
|
|
11 )
|
|
12 )
|
|
13
|
|
14 "fibr(9) = " print
|
|
15 fibr(9) println
|
|
16 "fibr(4) = " print
|
|
17 fibr(4) println
|
|
18 "fibr(1) = " print
|
|
19 fibr(1) println
|
|
20
|
|
21
|
|
22 fibl := method(num,
|
|
23 if (num < 1, return 0)
|
|
24 if (num == 1, return 1)
|
|
25 prev := 1
|
|
26 prev_prev := 0
|
|
27 val := 0
|
|
28 for(i, 2, num,
|
|
29 val = prev + prev_prev
|
|
30 prev_prev = prev
|
|
31 prev = val
|
|
32 )
|
|
33 return val
|
|
34 )
|
|
35
|
|
36 "fibl(9) = " print
|
|
37 fibl(9) println
|
|
38 "fibl(4) = " print
|
|
39 fibl(4) println
|
|
40 "fibl(1) = " print
|
|
41 fibl(1) println
|
|
42
|
|
43
|
|
44 # 2) Changing "/" operator to return 0 for a zero denominator
|
|
45 # Operators are just messages on objects, so "/" is the message to override
|
|
46 # and it must be on the object type Number
|
|
47 Number defaultDivide := Number getSlot("/")
|
|
48 Number / := method(denom,
|
|
49 if (denom == 0,
|
|
50 return 0,
|
|
51 return self defaultDivide(denom))
|
|
52 )
|
|
53 (4 / 2) println
|
|
54 (4 / 0) println
|
|
55
|
|
56
|
|
57 # 3) Add up numbers in a 2D array
|
|
58 arr := list(
|
|
59 list(1, 2, 3),
|
|
60 list(4, 5, 6),
|
|
61 list(7, 8, 9)
|
|
62 )
|
|
63
|
|
64 add2D := method(arr,
|
|
65 sum := 0
|
|
66 # A "reduce()" method would be nice, but KISS for now and foreach all the things
|
|
67 arr foreach(dimension, dimension foreach(val, sum = sum + val))
|
|
68 return sum
|
|
69 )
|
|
70
|
|
71 add2D(arr) println
|
|
72
|
|
73
|
|
74 # 4) Add myAverage to average numbers in a list
|
|
75 List myAverage := method(
|
|
76 sum := 0
|
|
77 self foreach(val, if (val proto == Number,
|
|
78 sum = sum + val,
|
|
79 Exception raise("Non-object found in list"))
|
|
80 )
|
|
81 return sum / self size
|
|
82 )
|
|
83
|
|
84 list(1, 2, 3) myAverage println
|
|
85 # This will exception - run at the end!
|
|
86 # list(1, 2, 3, "foo") myAverage
|
|
87 # With default behaviour then this could divide by zero (unless we'd been defensive coding)
|
|
88 # But we're in the same file as our custom "/", so we should get zero
|
|
89 list() myAverage println
|
|
90
|
|
91
|
40
|
92 #5) 2D list
|
|
93 TwoDList := Object clone
|
|
94 # It'd be nice to do something to set defaults when first cloning
|
|
95 # but I can't find how to do that, so force the developer to
|
|
96 # always dim() after clone
|
|
97 TwoDList dim := method(x, y,
|
|
98 self arr := list()
|
|
99 for (i, 1, x,
|
|
100 sub_list := list()
|
|
101 for (j, 1, y,
|
|
102 sub_list append(nil)
|
|
103 )
|
|
104 arr append(sub_list)
|
|
105 )
|
|
106 )
|
|
107 TwoDList set := method(x, y, value,
|
|
108 self arr at(x) atPut(y, value)
|
|
109 )
|
|
110
|
|
111 TwoDList get := method(x, y,
|
|
112 outer := self arr at(x)
|
|
113 if (outer != nil,
|
|
114 return outer at(y),
|
|
115 return nil
|
|
116 )
|
|
117 )
|
|
118
|
|
119 my_arr := TwoDList clone
|
|
120 my_arr dim(2, 3)
|
|
121 my_arr println
|
|
122 my_arr set(0, 1, "0,1")
|
|
123 my_arr set(1, 2, "Bottom-right")
|
|
124 my_arr get(1, 2) println
|
|
125 my_arr get(0, 1) println
|
|
126 my_arr get(0, 0) println
|
|
127 my_arr get(5, 5) println
|
|
128
|
|
129
|
|
130
|
|
131 # 4) final piece
|
39
|
132 list(1, 2, 3, "foo") myAverage |