## Monday, March 12, 2012

### Seven Languages in Seven Weeks - Io Day 2 Self-Study

Here's the next self-study section about the Io programming language. These are several exercises to get some practice.

A Fibonacci sequence starts with two 1s. Each subsequent number is the sum of the two numbers that came before; 1, 1, 2, 3, 5, 8, 13, 21, and so on. Write a program to get the nth Fibonacci number. fib(1) is 1, and fib(4) is 3. As a bonus, solve the problem with recursion and with loops

The recursive approach (very concise):
```fib := method(n,  if (n <= 2, 1, fib(n-1) + fib(n-2)))
```
And with a loop:
```fib := method(n,
p := 1;
q := 1;
sum := 1;
for (i, 3, n,
sum := p + q;
p := q;
q := sum
);
sum
)
```
How would you change / to return 0 if the denominator is zero?
```Number div := Number getSlot("/")
Number / := method(n, if (n == 0, 0, self div(n))
```
Write a program to add up all of the numbers in a two-dimensional array.
```a := list(list(1, 2, 3, 4), list(5, 6, 7, 8))
s := 0
a foreach(sublist, s := s + sublist sum)
```
Or more concise:
```a flatten sum
```
Add a slot called myAverage to a list that computes the average of all the numbers in a list. What happens if there are no numbers in a list? (Bonus: Raise an Io exception if any item in the list is not a number.)
```List myAverage := method(self sum / self size)
```
And with exception handling:
```List myAverage := method(
sum := 0;
self foreach(e,
(e isKindOf(Number)) ifFalse(Exception raise("not a number"));
sum := sum + e
);
sum / self size
)
```
Write a prototype for a two-dimensional list. The dim(x, y) method should allocate a list of y lists that are x elements long. set(x, y, value) should set the value, and get(x, y) should return that value
```List2d := Object clone

List2d dim := method(x, y,
self rows := List clone;
for (i, 1, x,
cols := List clone;
for (j, 1, y,
cols append(nil)
);
self rows append(cols)
);
self
)

List2d set := method(x, y, value,
self rows at(x) atPut(y, value);
self
)

List2d get := method(x, y,
self rows at(x) at(y)
)
```
Bonus: write a transpose method so that (new_matrix get(y, x)) == matrix get(x, y) on the original list.
```List2d transpose := method(
transposed := List2d clone;
transposed dim(self rows at(0) size, self rows size);
self rows foreach(i, row,
row foreach(j, elem,
transposed set(j, i, elem)
);
);
transposed;
)
```
Write the matrix to a file, and read a matrix from a file
```List2d toFile := method(filename,
file := File clone open(filename);
self rows foreach(col,
col foreach (elem,
file write(elem asString, " ")
);
file write("\n")
);
file flush close;
file
)

List2d fromFile := method(filename,
self rows := List clone;
file := File clone open(filename);
cols := line split;
self rows append(cols)
);
self
)
```
Write a program that gives you ten tries to guess a random number from 1--100. If you would like, give a hint of "hotter" or "colder" after the first guess.
```secretNum := Random value(100) floor() + 1
in := File standardInput
for (i, 1, 10,
write("Guess number (try #", i, "): ");
if (guess == secretNum, write("Win!"); break);
if (i > 1,
if ((secretNum - guess) abs < (secretNum - previousGuess) abs,
write("hotter\n"),
write("cooler\n")
)
);
previousGuess := guess;
)
```