Mercurial > repos > other > SevenLanguagesInSevenWeeks
view 2-Io/day2-self-study.io @ 47:409249712590
Add final experimentation and note about DSL
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Fri, 22 Sep 2017 19:48:13 +0100 |
parents | f4ea1f637f22 |
children |
line wrap: on
line source
# 1) Fibanacci by recursion (fibr) and loop (fibl) fibr := method(num, if (num < 1, return 0, if (num == 1, return 1, prev := fibr(num - 1) ; prev_prev := fibr(num - 2) ; return prev + prev_prev ) ) ) "fibr(9) = " print fibr(9) println "fibr(4) = " print fibr(4) println "fibr(1) = " print fibr(1) println fibl := method(num, if (num < 1, return 0) if (num == 1, return 1) prev := 1 prev_prev := 0 val := 0 for(i, 2, num, val = prev + prev_prev prev_prev = prev prev = val ) return val ) "fibl(9) = " print fibl(9) println "fibl(4) = " print fibl(4) println "fibl(1) = " print fibl(1) println # 2) Changing "/" operator to return 0 for a zero denominator # Operators are just messages on objects, so "/" is the message to override # and it must be on the object type Number Number defaultDivide := Number getSlot("/") Number / := method(denom, if (denom == 0, return 0, return self defaultDivide(denom)) ) (4 / 2) println (4 / 0) println # 3) Add up numbers in a 2D array arr := list( list(1, 2, 3), list(4, 5, 6), list(7, 8, 9) ) add2D := method(arr, sum := 0 # A "reduce()" method would be nice, but KISS for now and foreach all the things arr foreach(dimension, dimension foreach(val, sum = sum + val)) return sum ) add2D(arr) println # 4) Add myAverage to average numbers in a list List myAverage := method( sum := 0 self foreach(val, if (val proto == Number, sum = sum + val, Exception raise("Non-object found in list")) ) return sum / self size ) list(1, 2, 3) myAverage println # This will exception - run at the end! # list(1, 2, 3, "foo") myAverage # With default behaviour then this could divide by zero (unless we'd been defensive coding) # But we're in the same file as our custom "/", so we should get zero list() myAverage println #5) 2D list TwoDList := Object clone # It'd be nice to do something to set defaults when first cloning # but I can't find how to do that, so force the developer to # always dim() after clone TwoDList dim := method(x, y, self arr := list() for (i, 1, x, sub_list := list() for (j, 1, y, sub_list append(nil) ) arr append(sub_list) ) ) TwoDList set := method(x, y, value, self arr at(x) atPut(y, value) ) TwoDList get := method(x, y, outer := self arr at(x) if (outer != nil, return outer at(y), return nil ) ) my_arr := TwoDList clone my_arr dim(2, 3) my_arr println my_arr set(0, 1, "0,1") my_arr set(1, 2, "Bottom-right") my_arr get(1, 2) println my_arr get(0, 1) println my_arr get(0, 0) println my_arr get(5, 5) println #6) Bonus "transpose" method (ugly and inefficient method) TwoDList transpose := method( new_list := TwoDList clone x := self arr size y := self arr at(0) size new_list dim(y, x) for (i, 0, x - 1, for (j, 0, y - 1, new_list set(j, i, self get(i, j)) ) ) return new_list ) transposed := my_arr transpose transposed get(1, 2) println transposed get(0, 1) println transposed get(2, 1) println transposed get(1, 0) println #7) Write a matrix to a file and read it back # Might as well use the TwoDList as a matrix # Note: This isn't white-space safe, but nvm TwoDList as_string := method( x := self arr size y := self arr at(0) size #str := "#{self arr size}×#{self arr at(0) size}\n" interpolate str := "" for (i, 0, x - 1, for (j, 0, y - 1, str = "#{str}#{self get(i, j)} " interpolate ) str = "#{str asMutable strip}\n" interpolate ) ) TwoDList load := method(matrix_string, # strip to make sure that we don't get trailing new lines rows := matrix_string strip split("\n") row_count := rows size # Ugly way to get column count col_count := rows at(0) split(" ") size self dim(row_count, col_count) for (i, 0, row_count - 1, row := rows at(i) split(" ") for (j, 0, col_count - 1, self set(i, j, row at(j)) ) ) ) matrix_file := "matrix.txt" f := File with(matrix_file) f remove f openForUpdating f write(my_arr as_string) f flush f close f2 := File with(matrix_file) f2 openForReading new_list := TwoDList clone new_list load(f2 contents) f2 close new_list get(1, 2) println new_list get(0, 1) println # 4) final piece list(1, 2, 3, "foo") myAverage