The answer section is a work in progress. I am working on providing answers to every exercise but this takes time. Thank you for your patience.
Note that many exercises may have multiple possible answers. If your code looks a bit differnt from mine, but produces valid results, then your answer is fine. If you are uncertain, you can always contact me.
3. First programs
Exercise 1
You will of course have to replace my name with your own. (The exercise specification is vague enough that you could print your first name, your last name or both.)
|
|
Exercise 2
|
|
If you quoted the numbers (fmt.println("1")
), that is perfectly fine as well. The println
procedure works with both numbers and strings.
Using what we have learned so far, a program to print the numbers 1-10,000 would be slightly more than 10,000 lines long. It goes without saying that such a program would be highly inefficient.
Exercise 3
All the output will be on a single line:
$ odin run .
Hi there!I am learning OdinIt's a lot of fun so far.$
Depending on the system you use and how it has been configured, you may or may not see the prompt at the end of the output as well.
So println
means “print and jump to the next line in the terminal”, wheras print
stays on the same line after printing.
Exercise 4
|
|
However, if you are not English-speaking, or you are learning some language apart from English, why not print in that other language. Text enclosed in quotes (called string literals) is Unicode in Odin, which means you can use characters that are not part of the Latin alphabet.
Here, for instance, is the same program but with the month names in Ga instead. If you were learning Ga, you could run this program to remind yourself of the names of the months.
|
|
Right now, you really just want to practice writing code as much as possible, so if you speak 5 languages, take the opportunity to write the program 5 times.
Exercise 5
There are two errors you need to fix:
- In Odin, the declaration of the main procedure is
main :: proc
not justmain
(line 5) - In Odin, string literals are enclosed in a pair of double quotes, not single ones (line 7)
I can’t stress this enough: get familiar with the error messages that the Odin compiler gives and use them as a guide to finding and fixing the problem.
Exercise 6
The output of the program is:
$ odin run .
I am currently learning Odin
The new concept here is a variable, something you will learn in the next lesson. Try changing lang := "Odin"
to lang := "Go"
or something like that and see how the output changes.
Exercise 7
Try taking a very basic program like hellope and capitalizing proc
and see the result. Here is the modified program:
|
|
This is what happens, when I compile:
lorenzo@orthanc:~/Temporary/odin$ odin run .
/home/lorenzo/Temporary/odin/main.odin(5:1) Error: 'main' is reserved as the entry point procedure in the initial scope
main :: PROC() {
In this case, the error message might not be the most explanatory, but we can safely conclude that Odin is case sensitive. Note however, that this will work fine:
|
|
That is because Odin doens’t really care about what you put between the double quotes (there are a few exceptions that we will look at later, such as putting a double qoute between an pair of double quotes).
If you think about it, it’s just like in English. “I ain’t got no book” is unfortunately not considered proper English. If you were studying English and wrote this in an exam, you’d lose points.
However, if you were writing a book and wrote something like
“I ain’t got no book”, he said.
That would be perfectly fine, since you are quoting exactly what somebody said. So Odin follows similar rules to English.
Exercise 8
The hellope program is perfect for these types of small experiments. Simply change main
to start
and try to run.
lorenzo@orthanc:~/Temporary/odin$ odin run .
/home/lorenzo/src/hellope/main.odin(1:2) Error: Undefined entry point procedure 'main'
package main
^
That doesn’t work. Conclusion: every Odin executable program must have a special procedure called main
, which acts as the starting point of the program.
It is possible to write things that are not executable programs, like libraries in Odin as well. As you will see later, they are not required to have a main
procedure.
Exercise 9
There was only one bug in the program, println
should be all lowercase. Fix that and the program runs well. Do pay attention to the error message before you fix it.
Exercise 10
Here are the errors:
package
should not be capitalized (line 1)- The import should be “core:fmt”, not just “core” (line 3)
- The procedure signature for main is
main :: proc()
notproc :: main()
(line 5). println
is misspelled. (line 6)
I usually fix one error at a time and rerun the program to see if it is working and take note of how the error output has changed if it doesn’t work.
It can feel a bit overwhelming at first when you get a long list of error messages. You need to learn to filter it out and only focus on one thing at a time. For example, look at the very first error message and try to figure out what caused that.
Exercise 11
Hopefully you looked at the program first and guessed what it would do before running it in order to confirm.
Here is the output:
a + b = 8
a - b = 2
a * b = 15
a / b = 1
This program uses two variables: a
and b
. It also uses four different arithmetic operators: plus, minus, multiply and divide.
Exercise 12
The original program prints:
$ odin run .
I'll take it.
If we increase the rice to 200, get:
$ odin run .
It's too expensive!
At exactly 150, the program again prints “I’ll take it.”, since the if statement spefically checks if price is greater than 150.
Exercise 13
The program produces the following output:
1
2
3
4
5
6
7
8
9
10
We can get it to print from 5 to 20 by changing line 6 to:
for i in 5..=20
If we change 1..=10
to 1..<10
we get:
$ odin run .
1
2
3
4
5
6
7
8
9
If the first number is greater than the first we get an error:
$ odin run .
/home/lorenzo/Temporary/odin/main.odin(6:16) Error: Invalid interval range
for i in 10..=1 {
^
/home/lorenzo/Temporary/odin/main.odin(7:21) Error: Undeclared name: i
fmt.println(i)
^
Exercise 14
The default order of execution is to execute each line of code from top to bottom. Here is an example of a program that consists of more than one line of code
package main
import "core:fmt"
main :: proc() {
fmt.println("one")
fmt.println("two")
fmt.println("three")
}
This program will always produce the output:
one
two
three
This is because of the order of the statements.
Exercise 15
|
|
Exercise 16
|
|
Exercise 17
The output of the program is:
$ odin run .
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
This is exactly the same as the output of exercise 16 (before you added the comments).
The program uses a for
loop to iterate throught the capital letters, from ‘A’ to ‘Z’, printing each one on a line of its own. As you can see, this program is significantly shorter than the one in exercise 16, demonstrating the benefit of a loop.
4. Variables and Conditionals
Exercises 1
Since you haven’t learned how to use fmt.printfln
at this stage, getting the output gets a bit finicky.
|
|
Note the last print statement is println
to ensure that we get a newline at the end of the output. You could also do the following, if you are okay with space in between each part.
|
|
Notice however, that this solution isn’t exactly according to the specification. This could be a problem, if our program was a part of a larger system where some other part of the system is going to read the time from our program. Those extra spaces could be a problem, if that’s not what the other side expects. That is why it is important in software development, where different teams work on different parts of a larger system, that everybody follows the same spec and does so exactly.
The proper solution to this exercise would have been to use the printfln
function that I mentioned above. This version also prepends a zero before any part that is less than 10. We will learn about formatting text with printf
and printfln
in future lessons.
|
|
Exercise 2
|
|
I expect that you will test the program with both the possible values is_hungry
.
Exercise 3
The !
(exclamation mark) means not, so !is_tired
should be read as “is not tired”.
Exercise 4
|
|
Make sure you change the value of num
to see all the different messages.
Exercise 5
I decided to use the “good day” greeting between the hours 11 and 13 (3pm). You may have chosen different hours and that is fine, as long as the program behaves the way you intended it to.
|
|
Exercise 6
|
|
For the list of test values, the program will print “out of range” when num
is 17 or 78. For all the other values the program will not print anything.
Exercise 7
Before, you got the hour with h, _, _ := time.clock_from_time(n)
, discarding the minutes and seconds. Now we want the minutes instead, meaning you can discard the hour and seconds.
|
|
Exercise 8
|
|
Exercise 9
First we fix the errors that prevent the program from compiling:
- on line 3, change
"core:for"
to"core:fmt"
- on line 5, change
proc :: main()
tomain :: proc()
- on line 8, change the name of the variable from
num
toage
(twice) - on line 8, change the operand from
=>
to>=
- on line 8, change
or
to||
However, that is not enough, as you will see if you test the program with different ages. There are logic errors that cause the program to print the wrong output under some circumstances:
- on line 8, change
<=
to<
- on line 8, change
>=
to>
- on line 8, change 45 to 65
There are a lot of changes to be made to line 8. The final version should look as follows:
if age < 18 || age > 65 {
Exercise 10
|
|
Obvsiouly, the output of the program will vary based on the exact time of the day. We can figure out the range of possible numbers you can see. If you happened to manage to run the program exactly at midnight, you would get 0. If you run exactly one second earlier, the time would be 23:59:59, resulting in the ouput 141.
Exercise 11
We can use the following program to check if we are allowed to add two booleans.
|
|
Trying to compile, we get:
$ odin build .
/home/lorenzo/Temporary/odin/main.odin(7:16) Error: Operator '+' is only allowed with numeric expressions
bsum := b1 + b2
^
That error message should be enough for us to conclude that Odin does not allow this. (Some other languages may consider false
to be 0 and true
to be 1 or some other non-zero value, Odin does not do this.)
We modify the program slightly to see if we can use the +
operator with strings:
|
|
Again, we see that Odin does not allow this.
$ odin build .
/home/lorenzo/Temporary/odin/main.odin(7:16) Error: String concatenation is only allowed with constant strings
ssum := s1 + s2
^
Some languages, like Python, overload the +
operator to “concatenate” two strings. Since we are learning Odin, we should only be concerned with what Odin allows and doesn’t.
Exercise 12
We need to do three things:
- decide on whether we should print “am” or “pm”
- subtract 12 from the hour if it is > 12
- for the special hour 0, add 12
I’m going to create a variable called suffix
and set it to “am” by default. Only if the hour is greater than 12 should suffix
be “pm”.
Once that is done, we can deal with the other 2 cases. The code, without using fmt.printfln
is below:
|
|
We improve the output (and shorten the program) using printfln
instead:
|
|
5. Command Line Args
Exercise 1
The first element has the index number 0 and the last one has the index number 9.
Exercise 2
You can use the following program to test the slices:
|
|
Uncomment the fmt.println
lines one at a time and run. Below is the output.
values[2:4]
gives[30, 40]
values[5:10]
gives[60, 70, 80, 90, 100]
values[5:11]
fails to compile due toError: Index '11' is out of bounds range 0..<10, got 11
values[6:2]
fails to compile due toError: Invalid slice indices: [6 > 2]