Tracks
/
Swift
Swift
/
Exercises
/
Magician-in-Training
Magician-in-Training

Magician-in-Training

Learning Exercise

Introduction

Arrays are one of Swift's three primary collection types. An array is an ordered list of elements. Arrays can store elements of any type, but all elements in a given array must share the same type. Arrays are mutable when assigned to a variable, meaning you can add, remove, or modify elements after creating the array. When assigned to a constant, an array is immutable, meaning its contents cannot be changed.

Array literals are written as a comma-separated list of elements enclosed in square brackets ([...]). Swift can infer the array's type from the elements inside the literal.

let evenInts = [2, 4, 6, 8, 10, 12]
var oddInts = [1, 3, 5, 7, 9, 11, 13]
let greetings = ["Hello!", "Hi!", "¡Hola!"]

You can also specify the type explicitly. Array types can be written in two ways: Array<T> or the shorthand syntax [T], where T is the type of values the array contains.

let evenInts: Array<Int> = [2, 4, 6, 8, 10, 12]
var oddInts: [Int] = [1, 3, 5, 7, 9, 11, 13]
let greetings: [String] = ["Hello!", "Hi!", "¡Hola!"]

Size of an Array

You can find the number of elements in an array using its count property:

evenInts.count
// returns 6

Empty Arrays

To create an empty array, you must specify its type. You can do this using array initializer syntax or an explicit type annotation:

let emptyArray = [Int]()
let emptyArray2 = Array<Int>()
let emptyArray3: [Int] = []

Multi-dimensional Arrays

Arrays can be nested to create multi-dimensional arrays. When specifying the type of a nested array explicitly, wrap the element type in nested brackets, such as [[Int]] or Array<Array<Int>>:

let multiDimArray = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let multiDimArray2: [[Int]] = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

Appending to an Array

You can add an element to the end of a mutable array using the append(_:) method:

var oddInts = [1, 3, 5, 7, 9, 11, 13]
oddInts.append(15)
// oddInts is now [1, 3, 5, 7, 9, 11, 13, 15]

Inserting into an Array

You can insert an element at a specific index using the insert(_:at:) method. This method takes two arguments: the element to insert and the index at which to insert it.

var oddInts = [1, 3, 5, 7, 9, 11, 13]
oddInts.insert(0, at: 0)
// oddInts is now [0, 1, 3, 5, 7, 9, 11, 13]

Adding Arrays Together

You can combine two arrays into a single array using the + operator. The + operator creates and returns a new array; it does not modify the original arrays.

var oddInts = [1, 3, 5, 7, 9, 11, 13]
let combined = oddInts + [15, 17, 19]
// combined is [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

print(oddInts)
// prints [1, 3, 5, 7, 9, 11, 13]

Accessing Elements of an Array

You can access an individual element of an array by placing its index inside square brackets ([]) following the array name. Array indices are zero-based Int values, starting at 0 for the first element. Accessing an index outside the valid range causes a runtime error and crashes the program.

let evenInts = [2, 4, 6, 8, 10, 12]
let oddInts = [1, 3, 5, 7, 9, 11, 13]

evenInts[2]
// returns 6

oddInts[7]
// Fatal error: Index out of range

Modifying Elements of an Array

You can change an element in a mutable array by assigning a new value to a specific index. As with reading elements, using an index outside the valid range causes a runtime error.

var evenInts = [2, 4, 6, 8, 10, 12]

evenInts[2] = 0
// evenInts is now [2, 4, 0, 8, 10, 12]

Converting an Array to a String and Back

You can join an array of strings into a single string using the joined(separator:) method, which takes a separator string:

let evenInts = ["2", "4", "6", "8", "10", "12"]
let evenIntsString = evenInts.joined(separator: ", ")
// returns "2, 4, 6, 8, 10, 12"

You can split a string into an array of substrings using the split(separator:) method, passing the delimiter character:

let evenIntsString = "2, 4, 6, 8, 10, 12"
let evenInts = evenIntsString.split(separator: ",")
// returns ["2", " 4", " 6", " 8", " 10", " 12"]

Removing Elements from an Array

You can remove an element at a given index using the remove(at:) method. The index must be within the array's valid bounds; otherwise, a runtime error occurs.

var oddInts = [1, 3, 5, 7, 9, 11, 13]
oddInts.remove(at: 3)
// oddInts is now [1, 3, 5, 9, 11, 13]

To remove the final element of an array, use the removeLast() method. Calling removeLast() on an empty array causes a runtime error.

var oddInts = [1, 3, 5, 7, 9, 11, 13]
oddInts.removeLast()
// oddInts is now [1, 3, 5, 7, 9, 11]

Instructions

As a magician-to-be, Elyse needs to practice some basics. She has a stack of cards that she wants to manipulate.

To make things a bit easier she only uses the cards 1 to 10 so her stack of cards can be represented by an array of numbers. The position of a certain card corresponds to the index in the array. That means position 0 refers to the first card, position 1 to the second card etc.

Note

All functions should update the array of cards and then return the modified array - a common way of working known as the Builder pattern, which allows you to nicely daisy-chain functions together.

1. Retrieve a card from a stack

To pick a card, return the card at index position from the given stack.

Implement the function getCard(at:from:) that takes two arguments: at which is the position of the card in the stack, and from which is the stack of cards. The function should return the card at position index from the given stack.

let index = 2
getCard(at: index, from: [1, 2, 4, 1])
// returns 4

2. Change a card in the stack

Perform some sleight of hand and exchange the card at index position with the replacement card provided.

Implement the function setCard(at:in:to) that takes three arguments: at which is the position of the card in the stack, in which is the stack of cards, and to which is the new card to replace the card at position index. The function should return a copy of the stack with the card at position index replaced with the new card. If the given index is not a valid index in the stack, the original stack should be returned, unchanged.

let index = 2
let newCard = 6
setCard(at: index, in: [1, 2, 4, 1], to: newCard)
// returns [1, 2, 6, 1]

3. Insert a card at the of top the stack

Make a card appear by inserting a new card at the top of the stack.

Implement the function insert(_:atTopOf:) that takes two arguments: the new card to be inserted, and the stack of cards. The function should returns a copy of the stack with the new card provided added to the top of the stack.

let newCard = 8
insert(newCard, atTopOf: [5, 9, 7, 1])
// returns [5, 9, 7, 1, 8]

4. Remove a card from the stack

Make a card disappear by removing the card at the given position from the stack.

Implement the function removeCard(at:from:) that takes two arguments: at which is the position of the card in the stack, and from which is the stack of cards. The function should return a copy of the stack with the card at position index removed. If the given index is not a valid index in the stack, the original stack should be returned, unchanged.

let index = 2
removeCard(at: index, from: [3, 2, 6, 4, 8])
// returns [3, 2, 4, 8]

5. Insert a card in the stack

Make a card appear by inserting a new card at the given position in the stack.

Implement the function insert(_:at:from:) that takes three arguments: the new card to be inserted, the position at which the new card should be inserted, and the stack of cards. The function should return a copy of the stack with the new card provided added at the given position. If the given index is not a valid index in the stack, the original stack should be returned, unchanged.

let newCard = 8
insert(newCard, at: 2, from: [5, 9, 7, 1])
// returns [5, 9, 8, 7, 1]

6. Check size of the stack

Check whether the size of the stack is equal to stackSize or not.

Implement the function checkSizeOfStack(_:_:) that takes two arguments: stack which is the stack of cards, and stackSize which is the size of the stack. The function should return true if the size of the stack is equal to stackSize and false otherwise.

let stackSize = 4
checkSizeOfStack([3, 2, 6, 4, 8], stackSize)
// returns false
Edit via GitHub The link opens in a new window or tab
Swift Exercism

Ready to start Magician-in-Training?

Sign up to Exercism to learn and master Swift with 35 concepts116 exercises, and real human mentoring, all for free.