Swift Programming from Scratch
The Swift Sandbox is integrated, making the exercises interactive. Read more about the book here.
Chapter 4: Loops
Introduction
Let’s make make some pancakes!
So far we only looked at programs that have a fixed number of steps. For example look the algorithm to make a pancake:
- put 1/4 cup of batter in the frying pan
- cook for about 2 minutes
- flip and cook for another 2 minutes
- remove the pancake
How would the algorithm to make 10 pancakes would look? Would it be much different?
10 times do:
- put 1/4 cup of batter in the frying pan
- cook for about 2 minutes
- flip and cook for another 2 minutes
- remove the pancake
Loops let you describe repetitive processes. They could have a fixed amount of steps like the example above. Or they could have an unknow number of steps, for example a more realistic algorithm for making pancakes:
while you have pancake batter do:
- put 1/4 cup of batter in the frying pan
- cook for about 2 minutes
- flip and cook for another 2 minutes
- remove the pancake
while
A while
loop performs a set of statements until a condition becomes false
.
while condition
{
statements
}
For example in order to print
all the numbers from 1 to 10. We need to create a variable with the initial value of 1. Print the value and increase it by one and until it becomes bigger than 10.
var i = 1
while i <= 10 {
print(i)
i = i + 1
}
repeat
repeat
loops while a condition is met. The difference between a while
and a repeat
loop is that the repeat loop evaluates the condition after executing the statements from the loop.
repeat {
statements
} while condition
var i = 1
repeat {
print(i)
i = i + 1
} while i < 10
Both while
and repeat
are best used in loops where the numbers of stepts is unkown. Take for example the algorithm of converting a number to binary: divide the number by two until it becomes 0. Write the reminders from right to left to get the binary form of the number.
var number = 123
var binary = 0
var digit = 1
while number > 0 {
let reminder = number % 2
// add the new digit to the number
binary = digit * reminder + binary
// move the digit to the left
digit *= 10
// remove the last binary digit
number /= 2
}
binary // 1111011
for
loops
Swift provides two kinds of loops that perform a set of statements a certain number of times:
The for-in loop performs a set of statements for each item in a range or collection.
Swift also provides two range operators lowerBound...upperBound
and lowerBound..<upperBound
, as a shortcut for expressing a range of values.
1...3 // 1, 2, 3
1..<3 // 1, 2
for value
in range
{
statements
}
// prints 1-10
for i in 1...10 {
print(i)
}
// prints 0-9
for i in 0..<10 {
print(i)
}
If lowerBound
is greater than upperBound
you code will crash:
// this will crash - don't do it! :)
for i in 10...1 {
print(i)
}
If you want to loop on a range in reverse order you can use the reversed
range method:
// this will print the numbers from 10 to 1
for i in (1...10).reversed() {
print(i)
}
stride
stride
is a function from the swift standard library that returns the sequence of values start
, start + stride
,start + 2 * stride
, … end
) where last is the last value in the progression that is less than end.
The stride
function works with any kind of number:
stride(from: 1, to: 10, by: 2) // 1, 3, 5, 7, 9
stride(from: 1, to: 2, by: 0.1) // 1.0, 1.1 ... 1.9
Let’s take for example a program that counts from 1 to 10 by 3:
for i in stride(from: 1, to: 10, by: 3) {
print(i)
}
You can use stride
to create decreasing sequences if the stride
parameter is negative:
for i in stride(from: 3, to: 1, by: -1) {
print(i)
}
// prints: 3 2 1
print
and terminators
For the drawing exercises below you will need use the terminator
parameter for the print
function. Theterminator
refers to the thing that is printed at the end. The default terminator is the new line character "\n"
.
print(value)
will print the value and a new lineprint(value, terminator: "")
will print the value
print("BAT", terminator: "") // prints BAT
print("MAN", terminator: "") // prints MAN
print("") // prints a newline character
// BATMAN
print("BAT")
// BAT
print("MAN")
// MAN
Executing a statement multiple times
Sometimes you just want to execute some statements multiple times but don’t care about having an index. A swift convention in for
loops is to use _
as the loop variable name when you don’t intend to use the variable in the loop.
For examplet to to print “Hello World” 5 times you can use:
for _ in 1...5 {
print("Hello World")
}
Naming your loop variable _
is useful because you immediately tell that the variable is not used in the loop.
4.1 Chalkboard
Write a program that writes “I will not skip the fundamentals!” N
times.
Input:
var N = 3
Output:
I will not skip the fundamentals!
I will not skip the fundamentals!
I will not skip the fundamentals!
Input:
var N = 5
Output:
I will not skip the fundamentals!
I will not skip the fundamentals!
I will not skip the fundamentals!
I will not skip the fundamentals!
I will not skip the fundamentals!
The solution to a similar problem was shown in the theory, you can use either for
or while
to solve this problem.
var N = 10
// with a while loop
var times = 0
while times < N {
print("I will not skip the fundamentals!")
times = times + 1
}
var N = 10
// with a for loop
for _ in 1...N {
print("I will not skip the fundamentals!")
}
4.2 Squares
Print the first N
square numbers. A square number, also called perfect square, is an integer that is obtained by squaring some other integer; in other words, it is the product of some integer with itself (ex. 1
, 4
= 2
* 2
, 9
= 3
* 3
…).
Input:
var N = 2
Output:
1
4
Input:
var N = 5
Output:
1
4
9
16
25
var N = 10
var cnt = 1
while cnt <= N {
print(cnt * cnt)
cnt = cnt + 1
}
4.3 Powers of 2
Print the powers of 2
that are less than or equal to N
.
Input:
var N = 5
Output:
2
4
Input:
var N = 100
Output:
2
4
8
16
32
64
The first power of 2
is 2
. Given a power of 2
, power
, the next power of 2
is power * 2
.
var N = 10
var power = 2
while power <= N {
print(power)
power = power * 2
}
4.4 Alternative Counting
Write all the numbers from 1 to N
in alternative order, one number from the left side (starting with one) and one number from the right side (starting from N
down to 1
).
Input:
var N = 4
Output:
1
4
2
3
Input:
var N = 9
Output:
1
9
2
8
3
7
4
6
5
Use two variables to remember the left
and right
index that you need to print next.
There’s a special case you’ll have to handle when N
is odd.
var N = 5
var left = 1
var right = N
while left < right {
print(left)
print(right)
left += 1
right -= 1
}
if left == right {
print(left)
}
4.5 Square
Given an integer N
draw a square of N x N
asterisks. Look at the examples.
Input:
var N = 1
Output:
*
Input:
var N = 2
Output:
**
**
Input:
var N = 3
Output:
***
***
***
Try printing a single line of *
first.
You can use print("")
to print an empty line.
var N = 4
for i in 1...N {
for j in 1...N {
print("*", terminator: "")
}
print("")
}
4.6 Rectangle
Given two integers N
and M
draw a rectangle of N x M
asterisks. Look at the examples.
Input:
var N = 1
var M = 3
Output:
***
Input:
var N = 2
var M = 2
Output:
**
**
Input:
var N = 3
var M = 7
Output:
*******
*******
*******
You’ll need to change the bounds of one of the loops.
var N = 3
var M = 7
for i in 1...N {
for j in 1...M {
print("*", terminator: "")
}
print("")
}
4.7 Triangle
Given an integer N
draw a triangle of asterisks. The triangle should have N
lines, the i
-th line should have i
asterisks on it.
Input:
var N = 1
Output:
*
Input:
var N = 3
Output:
*
**
***
Input:
var N = 4
Output:
*
**
***
****
First you’ll want to print a single *
. Then you’ll want to print 2 *
, then 3 *
. How many stars will you print at the i-th
iteration?
var N = 3
for i in 1...N {
for j in 1...i {
print("*", terminator: "")
}
print("")
}
4.8 Pyramid
Given an integer N
draw a pyramid of asterisks. The pyramid should have N
lines. On the i-th line there should beN-i
spaces followed by i*2-1
asterisks.
Input:
var N = 1
Output:
*
Input:
var N = 2
Output:
*
***
Input:
var N = 3
Output:
*
***
*****
Input:
var N = 4
Output:
*
***
*****
*******
How many stars do you have to print at each iteration?
How many spaces do you have to print at each iteration?
What’s a general formula for the sequence: 1
, 3
, 5
,7
?
var N = 3
for i in 1...N {
for j in 0..<(N-i) {
print(" ", terminator: "")
}
for j in 1...2*i-1 {
print("*", terminator: "")
}
print("")
}
4.9 Rhombus
Given an integer N
draw a rhombus of asterisks, like the ones in the examples.
Input:
var N = 1
Output:
*
Input:
var N = 2
Output:
*
***
*
Input:
var N = 3
Output:
*
***
*****
***
*
Input:
var N = 4
Output:
*
***
*****
*******
*****
***
*
Notice that the upper half of the rhombus is the pyramid from the previous exercise.
The second half is the pyramid only inverted and with the last line removed.
let N = 4
for i in 1...N {
for j in 0..<(N-i) {
print(" ", terminator: "")
}
for j in 1...2*i-1 {
print("*", terminator: "")
}
print("")
}
if (N > 1) {
for j in 2...N {
var i = N - j + 1
for k in 0..<(N-i) {
print(" ", terminator: "")
}
for k in 1...2*i-1 {
print("*", terminator: "")
}
print("")
}
}
4.10 Aztec Pyramid
Given an integer N
draw a Aztec pyramid of asterisks, like the ones in the examples.
Input:
var N = 1
Output:
**
**
Input:
var N = 2
Output:
**
**
******
******
Input:
var N = 3
Output:
**
**
******
******
**********
**********
You’ll have to draw each line twice.
How many stars are on each line?
What’s the general term for the sequence 2
, 6
, 10
, 14
, … ?
let N = 3
for i in 1...N {
for _ in 1...2 {
for _ in 0..<(N-i) {
print(" ", terminator: "")
}
for _ in 1...2*i-1 {
print("**", terminator: "")
}
print("")
}
}
4.11 Chess Board
Given an integer N
draw a chess board of size N x N
. Each line of the chess board should have spaces and number signs(#
) alternating. A space represents a white cell and the number sign a black one. The chess board should be bordered using +
, -
and |
like in the examples below.
Input:
var N = 1
Output:
+-+
|#|
+-+
Input:
var N = 3
Output:
+---+
|# #|
| # |
|# #|
+---+
Input:
var N = 5
Output:
+-----+
|# # #|
| # # |
|# # #|
| # # |
|# # #|
+-----+
Input:
var N = 8
Output:
+--------+
|# # # # |
| # # # #|
|# # # # |
| # # # #|
|# # # # |
| # # # #|
|# # # # |
| # # # #|
+--------+
First consider how to draw the top and bottom border.
How can you alternate between ” ” and “#” ? Consider the remainder(%
) when dividing the indices of the loops by 2
.
let N = 8
// prints the top border
print("+", terminator: "")
for _ in 1...N {
print("-", terminator: "")
}
print("+")
for i in 1...N {
// prints the left border
print("|", terminator: "")
for j in 1...N {
if i % 2 == j % 2 {
print("#", terminator: "")
} else {
print(" ", terminator: "")
}
}
// prints the right border a a new line
print("|")
}
// prints the bottom border
print("+", terminator: "")
for _ in 1...N {
print("-", terminator: "")
}
print("+")
4.12 Fibonacci
Write a program that prints the first N
Fibonacci numbers. The first two Fibonacci numbers are 1
, the rest of the elements are the sum of the previous two. The first seven numbers are 1
, 1
, 2
, 3
, 5
, 8
and 13
.
Input:
var N = 3
Output:
1
1
2
Input:
var N = 6
Output:
1
1
2
3
5
8
Use two variables a = 1
and b = 0
. At each step a
should be the i-th Fibonacci number, and b
the i-1-th.
var N = 10
var a = 1
var b = 0
for _ in 1...N {
print(a)
var tmp = a + b
b = a
a = tmp
}
4.13 Leap Years
Write a program that prints the next N
leap years
starting with leapYear
. A leap year
is a year containing an extra day. It has 366 days
instead of the normal 365 days
. The extra day is added in February, which has 29 days
instead of the normal 28 days
. Leap years
occur every 4
years, 2012
was a leap year and 2016 will be a leap year
.
Except that every 100
years special rules apply. Years that are divisible by 100
are not leap years
if they are not divisible by 400
. For example 1900
was not a leap year
, but 2000
was.
Input:
var N = 6
// the current leap year
var leapYear = 2016
Output:
2016
2020
2024
2028
2032
2036
Input:
var N = 3
// the current leap year
var leapYear = 1996
Output:
1996
2000
2004
Keep in mind that the variable leapYear
is a leap year to begin with. Given a leap year how can you generate the next leap year ?
var N = 5
// the current leap year
var leapYear = 2016
// the number of leap years that were printed so far
var cnt = 0
// until we print N years
while cnt < N {
// print the next leap year
print(leapYear)
// increase the counter
cnt += 1
// go to the next leap year
leapYear += 4
if leapYear % 100 == 0 && leapYear % 400 != 0 {
leapYear += 4
}
}
4.14 Reverse
You are given a number
. Print the number with the digits in reversed order.
Input:
var number = 12345
Output:
54321
Input:
var number = 23432
Output:
23432
Input:
var number = 1000
Output:
0001
To get the last digit use the %
operator (the reminder to 10
is the last digit). To get the number without the last digit divide by 10
.
var number = 1234
while number > 0 {
print(number % 10, terminator: "")
number /= 10
}
4.15 GCD
You are given two numbers a
and b
. Find and print the greatest common divisor of a
and b
.
The greatest common divisor of a
and b
is the largest number that divides both a
and b
.
Input:
var a = 24
var b = 18
Output:
6
Input:
var a = 21
var b = 13
Output:
1
Input:
var a = 12
var b = 36
Output:
12
The smallest divisor of a
and b
is 1
. And the greatest value can be at most min(a, b)
.
Find the minimum of a
and b
and store it in maxDiv
.
Write a for loop that goes from 1
to maxDiv
and check each number.
var a = 24
var b = 18
var maxDiv = a
if b < maxDiv {
maxDiv = b
}
var gcd = 1
for i in 1...maxDiv {
if (a % i == 0) && (b % i == 0){
gcd = i
}
}
print(gcd) // 6
4.16 Prime numbers
You are given a number
. Print "prime"
if the number is a prime and "not prime"
otherwise.
A number is a prime if it has exactly 2 distinct divisors (1 and itself).
Input:
var number = 2
Output:
prime //2 is only divisible by 1 and 2
Input:
var number = 3
Output:
prime //3 is only divisible by 1 and 3
Input:
var number = 15
Output:
not prime //15 is divisible by 1,3,5 and 15
Input:
var number = 17
Output:
prime //17 is only divisible by 1 and 17
Input:
var number = 1
Output:
not prime //1 is only divisible by 1 (needs exactly 2 divisors to be a prime, only has 1)
Count the number of divisors of the input number.
var number = 17
var numberOfDivisors = 0
for i in 1...number {
if number % i == 0 {
numberOfDivisors += 1
}
}
if numberOfDivisors == 2 {
print("prime")
} else {
print("not prime")
}
4.17 Factoring numbers
You are given a number
. Decompose number
into prime factor and write it as an expression(see examples).
Input:
var number = 24
Output:
24 = 2 * 2 * 2 * 3
Input:
var number = 12
Output:
12 = 2 * 2 * 3
Input:
var number = 15
Output:
15 = 3 * 5
Input:
var number = 7
Output:
7 = 7
Input:
var number = 4
Output:
4 = 2 * 2
Dividing a number by one of it’s factors will result in a smaller number. A number can have a prime factor divisor multiple times, ex: 8 = 2 * 2 * 2
var number = 10
print("\(number) = ", terminator: "")
var isFirst = true
for i in 2...number {
if number % i == 0 {
while (number % i == 0) {
number /= i
if isFirst {
isFirst = false
} else {
print(" * ", terminator: "")
}
print(i, terminator: "")
}
}
}
4.18 Free of squares
Find all numbers free of squares less than or equal to N
. A number is free of square if it cannot be divided by any square number except 1
.
Input:
var N = 10
Output:
1
2
3
5
6
7
10
Input:
var N = 30
Output:
1
2
3
5
6
7
10
11
13
14
15
17
19
21
22
23
26
29
30
var N = 10
print(1)
for i in 2...N {
var isFree = true
var a = i
for j in 2...a {
if a % j == 0 {
var put = 0
while (a % j == 0) {
a /= j
put += 1
}
if put > 1 {
isFree = false
}
}
}
if isFree {
print(i)
}
}
Swift Programming from Scratch
Read more about the book here.
Feel free to ask any questions in the comments bellow.
Are while loops used that often? I’m only familiar with javascript, I seem to see for loops almost always used. I’ve never seen a do…while loop in scripts.
It’s not like there’s a correct or better way to loop
Each one has it’s purpose, know them and use them when you need
thks dude, nice job, it help me a lot and other newbie like me ( oops, i just assume:) )
but can you post solution for all twist above pls ? cos i think a newbie like me also want to improve the logic thinking further more the excercise :). i will delight
It’s a challenge
– I don’t want to ruin the fun
Could you please just give us a hint?
on what problem?
lol, my brain was going get heat up as thinking about twist challenge :).
btw
why dont you create a function for seeing twist solution for people can not work it out like me :).
ex: if “click ” = 1000 times then print the line ( twist solution ) or “page view” = 100 time then u can see the twist solution.
just in case some brain get pop out
Newbie over here.
I’m trying to understand what the difference is when writing,
–n
n–
I think your question is “what is the difference between ++n/–n and n++/n–“.
n++ means take the value of n and then inclement it by one.
var n = 1
var a = n++
// n = 2
// a = 1
++n means inclement the value of n by one then take that value.
var n = 1
var a = ++n
// n = 2
// a = 2
In exercise 4.5 could you explain what i and j represent, and also how you determine vertical from horizontal rows when drawing such pictures? By the way this website has been extremely helpful!
in exercise 4.5 we don’t need i and j – they are the vertical and horizontal index respectively. you draw this kind of shapes one row at a time – each time we call println we add a new line character.
hello, answer to 4.16,
if number % i == 0 {
numberOfDivisors += 1
}
}
if numberOfDivisors == 2
are you able to elaborate? I’m not understanding why we check if number divided by i has zero remainders to then add 1, if I’m not mistaken numberofdivisors += 1 means 0 + 1, how is it 2 afterwards ?
thanks
Hi Andre!! Thank you so much for your supremely helpful exercises and explanations :).
I was performing exercise 4.3, “Powers of 2”, and I noticed that your solution is a little bit off. Your solution only prints “2”, “4”, and “8”, when it should print the numbers 2, 4, 8, 16, 32, 64, 128, 256, 512, and 1024 (if you are printing all of the powers of two, 2^1 ~ 2^10). If you are to use a “while” statement, a solution that prints all of the appropriate values would look something like this:
var powerOfTwo = 10
var ctr = 1
var twoMulti = 1
while ctr <= powerOfTwo {
println(2 * twoMulti)
++ctr
twoMulti *= 2
}
However I've found that using a "for-in" loop can make the code more elegant (read "short"):
var powersOfTwo = 10
var twoMulti = 2
for _ in 1…powersOfTwo {
println(twoMulti)
twoMulti *= 2
}
I'm not an expert so there might be an even better way to do it :-/. Anyway, thank you again for your super helpful guide!!
The exercise asks to print the powers of two less than or equal to N. Not the first N powers of two. For N = 10. 2, 4 and 8 are less than 10. 16, 32, 64, 128, 256, 512 and 1024 are greater than 10.
Hope this helps!
If that’s the case, then aren’t your example outputs incorrect?
In example 1, For N=2 you have the output as “2, 4”. However 4 is not less than or equal to 2, so the only output that should appear is 2.
Similarly, in example 2, for N=6 you have the output of “2, 4, 8, 16, 32, 64”, when the only outputs less than 6 (thus the only outputs that should appear) are “2” and “4”.
(btw I don’t mean any disrespect, I’m just trying to understand the exercise. :)!)
You are right, the examples are wrong! We updated the exercise. Thank you!
For exercise 4.7, perhaps you could note that attempting to print the string “\” (backslash) will not work normally, and that the programmer needs to type print(“\\”) in order to print the special character \.
… Unless your goal is to have your visitors Google-search the answer for themselves :-p.
Good point
!! Will definitely do that!
Hey again, I have another question.
For 4.15, why is it necessary to compare a and b and find the one with the lower value?
Below is the code I used, and it seems to me that it’s the same as yours, functionally, but shorter. Are you comparing a and b to make sure that the computer is not spending extra cycles on looking for a gcd that it won’t find (because it will eventually surpass the lower of the two values if you pick the higher value for the for loop)? Is there any other reason to compare the values before putting it through the for loop?
var one = 24
var two = 18
var final = 1
for var divisor = 1; divisor <= one; ++divisor {
if one % divisor == 0 && two % divisor == 0 {
final = divisor
}
}
print(final)
Thank you in advance for the clarification :)!
it does the same thing. yours can make “extra” steps if
one
is greater thantwo
For 4.17 Twist, because you don’t have an if statement for the exponents/powers, your solution prints i^1 instead of just i when the value of “put” is 1!
If that is intended, then please ignore my comment! :-p
it was intended – sorry for the late reply!
Hi, first off great work on the exercise platform. Paired with Treehouse it’s really helped me hammer in the basic concepts.
Secondly, I was able to solve 4.5, albeit with a different solution from yours. Would just like to know if there are any downsides to this solution vs yours. For example, not having arrived at the same solution as yours may indicate that I haven’t fully grasped the concepts yet? Thanks in advance. Here is my solution:
var N = 4
// your code here
var area = N * N
var counter: Int = 1
for var numOfasterisk = 1; numOfasterisk <= area; ++numOfasterisk {
print("*")
if counter % N == 0 {
print("\n")
}
counter = counter + 1
}
Cool solution!
the point of these exercises was to practice nested loops in a visual way – if you understand nested loops you can move on
Hi Andrei,
Many thanks to your effort in helping us learn swift! I have come up another solution to Alternative Counting problem below. Hope it is helpful to other learners as well.
var N = 5
var leftOdd = 1
var rightEven = N
for i in 1…N {
if i % 2 != 0 {
println(leftOdd)
++leftOdd
} else {
println(rightEven)
–rightEven
}
}
Cool solution!
Hi Andrei,
As for problem 4.5 Square, the solution can be even more simpler by omitting i and j:
var N = 4
var asterisk = “*”
// using for in loop
for _ in 1…N { // print each line of * four times
for _ in 1…N { // print * 3 times on one line
print(asterisk)
}
println() // print * with a line break
}
ps. an suggestion: if you can add students’ less simpler solutions to compare with the simpler solutions, it may also show the comparison and enhance comprehension of the concepts.
Where would we be able to find the solutions to the TWIST problems?
In your imagination!
Try to solve them – they are pretty similar to the original problems.
Good luck!
haha…ok… working on them.. also 4.17 uses an isFirst variable as a boolean. It later gets used in the loop to write the (“*”) after each number. Is there anything on the lessons that addresses or explains this? I see what it’s doing but I’m having a hard time grasping how it does it and so I’m not really sure how to use it.
Thanks
Hey Andrei,
I started with the book and exercise platform a few weeks ago. I have to say I have been enjoying it. I’m about half way through the exercises in chapter 4 and I’m getting stuck on these exercises. Do you have any recommendations for thinking about these problems? Also, do you recommend any additional resources for learning loops? Thanks!
A lot of people seem to need more practice at this point in the book. I’ll add more exercises to the platform soon.
I learned to code a loooong time ago – the only thing I can do is google “practice loops in swift” and give you the links.
One thing I would recommend is that you take the solution to the problem you are stuck and copy paste it. Then change the code a bit – see how the result changes. I’ve learned a lot by just playing around.
Hey Alex:
I too am getting stuck in the exercises from around halfway through Ch. 4, and came back to the comments to see if anyone else was in a similar situation.
Were you able to find any additional resources (tutorials, etc.) that helped you work through these exercises and learn loops?
Thanks!
I’ve learned programming a long time ago and unfortunately I can’t recommend any swift content for that.
In case you have an iPad I suggest you play this game – its the first game programmed completely on an iPad. Or this game on your PC.