# Io — Day Two

Wow. Day two messed with my head. I woke up a bit tired this morning to have a crack at it and got really baffled by how to make a fibonacci sequence. Just drew a total blank. So, I dug out some old c code I had and copied that into io. Which is sort of cheating, but got me going and also helped me feel a bit more comfortable with the language. Like Tate says, feeling comfortable with a new language is often about typing some code. Well, my homework excercises with some commentary looked like this.

### 1. fib.io

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 find the nth Fibonacci number. fib(1) is 1, and fib(4) is 3. As a bonus, solve the problem with recursion and with loops.

Like I said, my brain was totally blank at first, so I’ve pretty much rewritten C code. By the end of this I was starting to get the hang of how Io approaches stuff. ``` #!/usr/local/bin/io # Iterative version. Probably faster. fib := method( last_index, # save a tiny bit of work # we already know that fib(1) and fib(2) return 1 if (last_index < 3, return 1 ) first := second := 1 for( unused, 1, last_index-1, running_total := first + second first := second; second = running_total; ) return first ) call_count := 0 # A naive and often seen recursive implementation rfib := method ( n, if(n<2, return n ) return rfib(n-1) + rfib(n-2) ) # this and the next method iwork together and are a bit more efficient new_rfib := method (n, if ( n<1, return 0 ) return new_rfib2(n, 0, 1) ) new_rfib2 := method(n,first,second, if( n<2, return second ) return new_rfib2(n-1, second, first+second) ) "\nIterative version\n------------------" println for(i,1,10, writeln( "Iteration ", i, ": ", fib(i) ) ) "\nRecursive version 1\n------------------" println for(i,1,10, writeln( "Iteration ", i, ": ", rfib(i) ) ) "\nRecursive version 2\n------------------" println for(i,1,10, writeln( "Iteration ", i, ": ", new_rfib(i) ) ) ```

### 2. override_divide.io

How would you change / to return 0 if the denominator is zero?

This mostly took looking at the docs. I tooke the approach of making a copy of the default / operator and passing the figures on to it unless the denomonator was zero. Other people seem to have taken a similar approach. ``` #!/usr/local/bin/io # store the 'core', original divide operator Number div_method := Number getSlot("/") # Now extend the Number class Number / := method(denom, if (denom == 0, return 0, return self div_method(denom)) ) # tests "expect 2" println (14/7) println "expect 0" println (14/0) println ```

### 3. list_sum.io

Write a program to add up all of the numbers in a two-dimensional array.

Fortunately the docs for List are very well written, and I chanced across the sum and flatten methods. So it was pretty trivial to implement something that matched the spec. I note that Ben Nadel took a much more "from scratch approach". I’m lazy though. ``` #!/usr/local/bin/io # you can flatten a list, then sum list_sum := method ( list, list flatten sum ) "Expect 10" println list_sum( list( list(1,2), list(3,4))) println ```

### 4. my_average.io

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.)

Well, the last problem had already introduced the sum method. And reading the docs, sum throws an exception on NaN. So, being lazy, I reused that. ``` #!/usr/local/bin/io List my_average := method ( return sum / size ) x := list (1,2,3) "Expect 2" println x my_average println x := list ("NaN",1,2,3) "Expect Exception" println x my_average println ```

### 5..7

All these questions were related so I was able to tackle them all in one lump of code

5. 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 a value, and get(x, y) should return that value. 6. Bonus: Write a transpose method so that (new_matrix get(y, x)) == matrix get(x, y) on the original list. 7. Write the matrix to a file, and read a matrix from a file.

This was stretching for me, especially the transpose method. Not that the code is super difficult, its just expressing oneself in an unfamiliar language that feels like swimming in treacle. ``` #!/usr/local/bin/io matrix := List clone; matrix dim := method(x,y, self setSize(x); // make first dimension this big for (i, 0, (x - 1), 1, self atPut(i, (list setSize(y)) ) ) ) matrix get := method (x,y, return self at(x) at(y) ) matrix set := method (x,y,value, self at(x) atPut(y,value) return self ) matrix transpose := method ( my_x := self size my_y := self first size my_matrix := matrix clone dim ( my_y, my_x ) // note x and y swapped for (i, 0, (my_x-1), for(j, 0, (my_y-1), my_matrix set(j,i,self get(i,j)) ) ) # Ooh! you can not nother with 'return', just like perl my_matrix ) matrix save := method ( # Borrowed this cute syntax from http://stackoverflow.com/questions/4533478/how-do-i-deserialize-objects-in-io File with("matrix.dat") open write(self serialized) close ) matrix show := method ( for(i, 0, self size-1, for(j, 0, self first size-1, self get(i,j) print if(j<self first size-1, ", " print ) ) "" println ) ) // Tests m:=matrix clone dim(3,3) "\nExpect 3x3 Matrix of nils" println m println m set(0,0,"O") m set(0,1,"O") m set(0,2,"X") m set(2,2,"X") "Expect X" println m get(2,2) println "Expect formatted-ish matrix" println m show m2 := m transpose "Expect formatted transposed matrix" println m2 show m2 save m := doFile("matrix.dat"); "Expect 3x3 matrix" println m println ```

### 8. guesser.io

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.

I felt like I was on the home strait with this question, and started to appreciate Tate's characterization of Io as being kinda like Ferris Bueller. The one place where I got stuck was having an "and" in my conditional. Parantheses to the rescue! ``` #!/usr/local/bin/io to_guess := Random value(1,100) round i := 0 prev_diff := nil in := File standardInput; "\n\nGuess my number (1-100, Q to quit)!" println while(i<10, guess := in readLine("Your guess: ") if(guess=="Q", break) // Quit guess := guess asNumber if(guess isNan, continue) // Try again, not a number difference := (to_guess - guess) abs if( difference == 0, "Congratulations, you win!" println break ) if((prev_diff and prev_diff != difference), if(prev_diff > difference, "Warmer" println, "Colder" println ) ) prev_diff := difference ) ```

• Be respectful. You may want to read the comment guidelines before posting.
• You can use Markdown syntax to format your comments. You can only use level 5 and 6 headings.
• You can add class="your language" to code blocks to help highlight.js highlight them correctly.

Privacy note: This form will forward your IP address, user agent and referrer to the Akismet, StopForumSpam and Botscout spam filtering services. I don’t log these details. Those services will. I do log everything you type into the form. Full privacy statement.

• #163

just like you, i got no trouble about ruby, then start learn Io, day one is fresh but still ok, day two is hard, i have no idea how to finish the excercises, maybe i should read offical Io programming guide first, did you do the same thing or just suddenly got idea then done. and do you have any suggestions how to learn these 6 languages besides ruby?

• #196

#### Learning

Hey @mega. Well I took a bit of a mixed approach. I spent a lot of time on duckduckgo and other search engines, and picking the brains of some very awesome communities on forums and IRC as well as skimming the manuals. My best advice would be don't rush through it, take the time to understand everything you're being shown. And don't worry if it takes more than 7 weeks. It took me about a year!!