Skip to content

Latest commit

 

History

History
241 lines (179 loc) · 6.26 KB

05-loops.adoc

File metadata and controls

241 lines (179 loc) · 6.26 KB

Loops

Loops are another control flow construct which allow us to run some parts of code multiple times. This can either be a known number of times (for-loops) or for as long as some condition is satisfied (while-loops).

 

For loop

Syntax of a for-loop is:

for <loopVariable> in <iterable>:
  <loop body>

Traditionally, i is often used as a loopVariable name, but any other name can be used. That variable will be available only inside the loop. Once the loop has finished, the value of the variable is discarded.

The iterable is any object we can iterate through. Of the types already mentioned, strings are iterable objects. (More iterable types will be introduced in the next section.)

All lines in the loop body are executed at every loop, which allows us to efficiently write repeating parts of code.

 

If we want to iterate through a range of (integer) numbers in Nim, the syntax for the iterable is start .. finish where start and finish are numbers. This will iterate through all the numbers between start and finish, including both start and finish. For the default range iterable, start needs to be smaller than finish.

If we want to iterate until a number (not including it), we can use ..<:

for1.nim
link:{source-dir}/for1.nim[role=include]
  1. Iterating through a range of numbers using .. — both ends are included in the range.

  2. Iterating through the same range using ..< — it iterates until the higher end, not including it.

5
6
7
8
9

5
6
7
8

If we want to iterate through a range of numbers with a step size different than one, countup is used. With countup we define the starting value, the stopping value (included in the range), and the step size.

for2.nim
link:{source-dir}/for2.nim[role=include]
  1. Counting up from zero to 16, with a step size of 4. The end (16) is included in the range.

0
4
8
12
16

To iterate through a range of numbers where the start is larger than finish, a similar function called countdown is used. Even if we’re counting down, the step size must be positive.

for2.nim
link:{source-dir}/for2.nim[role=include]
  1. To iterate from a higher to a lower number, we must use countdown (The .. operator can only be used when the starting value is smaller than the end value).

  2. Even when counting down, the step size must be a positive number.

4
3
2
1
0

-3
-5
-7
-9

Since string is an iterable, we can use a for-loop to iterate through each character of the string (this kind of iteration is sometimes called a for-each loop).

for3.nim
link:{source-dir}/for3.nim[role=include]
a
l
p
h
a
b
e
t

If we also need to have an iteration counter (starting from zero), we can achieve that by using for <counterVariable>, <loopVariable> in <iterator>: syntax. This is very practical if you want to iterate through one iterable, and simultaneously access another iterable at the same offset.

for3.nim
link:{source-dir}/for3.nim[role=include]
letter 0 is: a
letter 1 is: l
letter 2 is: p
letter 3 is: h
letter 4 is: a
letter 5 is: b
letter 6 is: e
letter 7 is: t

While loop

While loops are similar to if statements, but they keep executing their block of code as long as the condition remains true. They are used when we don’t know in advance how many times the loop will run.

We must make sure the loop will terminate at some point and not become an infinite loop.

while.nim
link:{source-dir}/while.nim[role=include]
  1. This condition will be checked every time before entering the new loop and executing the code inside of it.

  2. inc is used to increment a by one. It is the same as writing a = a + 1 or a += 1.

a is: 1
a is: 2
a is: 3
final value of a: 4

Break and continue

The break statement is used to prematurely exit from a loop, usually if some condition is met.

In the next example, if there were no if statement with break in it, the loop would continue to run and print until i becomes 1000. With the break statement, when i becomes 3, we immediately exit the loop (before printing the value of i).

break.nim
link:{source-dir}/break.nim[role=include]
1
2

 

The continue statement starts the next iteration of a loop immediately, without executing the remaining lines of the current iteration. Notice how 3 and 6 are missing from the output of the following code:

continue.nim
link:{source-dir}/continue.nim[role=include]
1
2
4
5
7
8

Exercises

  1. Collatz conjecture is a popular mathematical problem with simple rules. First pick a number. If it is odd, multiply it by three and add one; if it is even, divide it by two. Repeat this procedure until you arrive at one. E.g. 5 → odd → 3*5 + 1 = 16 → even → 16 / 2 = 8 → even → 4 → 2 → 1 → end!
    Pick an integer (as a mutable variable) and create a loop which will print every step of the Collatz conjecture. (Hint: use div for division)

  2. Create an immutable variable containing your full name. Write a for-loop which will iterate through that string and print only the vowels (a, e, i, o, u). (Hint: use case statement with multiple values per branch)

  3. Fizz buzz is a kids game sometimes used to test basic programming knowledge. We count numbers from one upwards. If a number is divisible by 3 replace it with fizz, if it is divisible by 5 replace it with buzz, and if a number is divisible by 15 (both 3 and 5) replace it with fizzbuzz. First few rounds would look like this: 1, 2, fizz, 4, buzz, fizz, 7, …​
    Create a program which will print first 30 rounds of Fizz buzz. (Hint: beware of the order of divisibility tests)

  4. In the previous exercises you have converted inches to centimeters, and vice versa. Create a conversion table with multiple values. For example, the table might look like this:

in	| cm
----------------
1	| 2.54
4	| 10.16
7	| 17.78
10	| 25.4
13	| 33.02
16	| 40.64
19	| 48.26