Skip to content

Commit 6908429

Browse files
committed
Add range concept and exercise
1 parent fa878ba commit 6908429

File tree

13 files changed

+468
-0
lines changed

13 files changed

+468
-0
lines changed

concepts/ranges/.meta/config.json

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"blurb": "Optionals can be used to represent the possible absence of a value.",
3+
"authors": [
4+
"meatball133"
5+
],
6+
"contributors": []
7+
}

concepts/ranges/about.md

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Ranges
2+
3+
[Ranges][range] represent an interval between two values.
4+
The most common types that support ranges are `Int`, `String`, and `Date`.
5+
They can be used for many things, such as quickly creating a collection, slicing an array, checking if a value is in a range, and iteration.
6+
They are created using the range operator `...` or `..<` (inclusive and exclusive, respectively).
7+
8+
```swift
9+
1...5 // A range containing 1, 2, 3, 4, 5
10+
1..<5 // A range containing 1, 2, 3, 4
11+
```
12+
13+
The reason for having two range operators is to create ranges that are inclusive or exclusive of the end value, which can be useful when, for example, working with zero-based indexes.
14+
15+
~~~~exercism/note
16+
When creating a range in Swift using the range operators `...` or `..<`, and wanting to call a method on the range, you need to wrap the range in parentheses.
17+
This is because the otherwise will the method be called on the 2nd argument of the range operator.
18+
19+
```swift
20+
(1...5).contains(3) // Returns true
21+
1...5.contains(3) // => Error: value of type 'Int' has no member 'contains'
22+
```
23+
~~~~
24+
25+
## Convert a range to an array
26+
27+
To convert a range to an array, you can use the `Array` initializer.
28+
This can be useful when you want to create a collection of values, without having to write them out.
29+
30+
```swift
31+
let range = 1...5
32+
let array = Array(range) // Returns [1, 2, 3, 4, 5]
33+
```
34+
35+
## Slice an array
36+
37+
Ranges can be used to slice an array.
38+
39+
```swift
40+
let array = [1, 2, 3, 4, 5]
41+
let slice = array[1...3] // Returns [2, 3, 4]
42+
```
43+
44+
## Range methods
45+
46+
Ranges do have a set of methods that can be used to work with them.
47+
For example, these methods can be used to get the sum of all the values in the range or check if the range includes a value.
48+
49+
| Method                  | Description                                                             | Example                         |
50+
| ----------------------- | ----------------------------------------------------------------------- | ------------------------------------- |
51+
| `count`       | Returns the size of the range                                         | `(1...5).count // returns 5` |
52+
| [`contains`][contains] | Returns `true` if the range includes the given value, otherwise `false` | `(1...5).contains(3) // Returns true` |
53+
54+
## Endless & Beginningless ranges
55+
56+
A range can be endless and beginless.
57+
58+
Using beginless and endless ranges is useful when you want to, for example, slice an array from the beginning or to the end.
59+
60+
~~~~exercism/caution
61+
If not used on a collection, the endless range can cause an endless sequence, if not used with caution.
62+
~~~~
63+
64+
## String ranges
65+
66+
String can be used in ranges and allow you to get an interval of Strings between two Strings.
67+
For example, this can be handy when you want to get the alphabet.
68+
69+
```swift
70+
"a"..."z" // A range containing ["a", "b", "c", ..., "z"]
71+
```
72+
73+
[range]: https://developer.apple.com/documentation/swift/range
74+
[contains]: https://developer.apple.com/documentation/swift/range/contains(_:)

concepts/ranges/introduction.md

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Ranges
2+
3+
[Ranges][range] represent an interval between two values.
4+
The most common types that support ranges are `Int`, `String`, and `Date`.
5+
They can be used for many things, such as quickly creating a collection, slicing an array, checking if a value is in a range, and iteration.
6+
They are created using the range operator `...` or `..<` (inclusive and exclusive, respectively).
7+
8+
```swift
9+
1...5 // A range containing 1, 2, 3, 4, 5
10+
1..<5 // A range containing 1, 2, 3, 4
11+
```
12+
13+
The reason for having two range operators is to create ranges that are inclusive or exclusive of the end value, which can be useful when, for example, working with zero-based indexes.
14+
15+
~~~~exercism/note
16+
When creating a range in Swift using the range operators `...` or `..<`, and wanting to call a method on the range, you need to wrap the range in parentheses.
17+
This is because the otherwise will the method be called on the 2nd argument of the range operator.
18+
19+
```swift
20+
(1...5).contains(3) // Returns true
21+
1...5.contains(3) // => Error: value of type 'Int' has no member 'contains'
22+
```
23+
~~~~
24+
25+
## Convert a range to an array
26+
27+
To convert a range to an array, you can use the `Array` initializer.
28+
This can be useful when you want to create a collection of values, without having to write them out.
29+
30+
```swift
31+
let range = 1...5
32+
let array = Array(range) // Returns [1, 2, 3, 4, 5]
33+
```
34+
35+
## Slice an array
36+
37+
Ranges can be used to slice an array.
38+
39+
```swift
40+
let array = [1, 2, 3, 4, 5]
41+
let slice = array[1...3] // Returns [2, 3, 4]
42+
```
43+
44+
## Range methods
45+
46+
Ranges do have a set of methods that can be used to work with them.
47+
For example, these methods can be used to get the sum of all the values in the range or check if the range includes a value.
48+
49+
| Method                  | Description                                                             | Example                         |
50+
| ----------------------- | ----------------------------------------------------------------------- | ------------------------------------- |
51+
| `count`       | Returns the size of the range                                         | `(1...5).count // returns 5` |
52+
| [`contains`][contains] | Returns `true` if the range includes the given value, otherwise `false` | `(1...5).contains(3) // Returns true` |
53+
54+
## Endless & Beginningless ranges
55+
56+
A range can be endless and beginless.
57+
58+
Using beginless and endless ranges is useful when you want to, for example, slice an array from the beginning or to the end.
59+
60+
~~~~exercism/caution
61+
If not used on a collection, the endless range can cause an endless sequence, if not used with caution.
62+
~~~~
63+
64+
## String ranges
65+
66+
String can be used in ranges and allow you to get an interval of Strings between two Strings.
67+
For example, this can be handy when you want to get the alphabet.
68+
69+
```swift
70+
"a"..."z" // A range containing ["a", "b", "c", ..., "z"]
71+
```
72+
73+
[range]: https://developer.apple.com/documentation/swift/range
74+
[contains]: https://developer.apple.com/documentation/swift/range/contains(_:)

concepts/ranges/links.json

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[
2+
{
3+
"url": "https://developer.apple.com/documentation/swift/range",
4+
"description": "Swift docs: Range"
5+
}
6+
]

config.json

+17
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,18 @@
119119
],
120120
"status": "active"
121121
},
122+
{
123+
"slug": "chess-game",
124+
"name": "Chess Game",
125+
"uuid": "162bf709-ed48-438d-9a32-f572099cf42e",
126+
"concepts": [
127+
"ranges"
128+
],
129+
"prerequisites": [
130+
"arrays"
131+
],
132+
"status": "active"
133+
},
122134
{
123135
"slug": "santas-helper",
124136
"name": "Santa's Swifty Helper",
@@ -1503,6 +1515,11 @@
15031515
"slug": "repeat-while",
15041516
"name": "repeat while"
15051517
},
1518+
{
1519+
"uuid": "cb0d8166-672c-4bdf-820b-d60531574d73",
1520+
"slug": "ranges",
1521+
"name": "Ranges"
1522+
},
15061523
{
15071524
"uuid": "a4b7ebd1-28f4-4270-910f-cf511ec4b45a",
15081525
"slug": "self",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Instructions
2+
3+
As a chess enthusiast, you want to write your version of the game.
4+
Yes, there may be plenty of implementations of chess available online already, but yours will be unique!
5+
6+
You start with implementing a chess board.
7+
8+
The chess game will be played on an eight-square wide and eight-square long board.
9+
The squares are identified by a letter and a number.
10+
11+
## 1. Define rank & file range
12+
13+
The game will have to store the ranks of the board.
14+
The ranks are the rows of the board, and are numbered from 1 to 8.
15+
16+
The game will also have to store the files on the board.
17+
The files are the board's columns and are identified by the letters A to H.
18+
19+
Define the `ranks` and `files` constants that store the range of ranks and files respectively.
20+
21+
```swift
22+
ranks
23+
// returns 1..8
24+
25+
files
26+
// returns 'A'..'H'
27+
```
28+
29+
## 2. Check if square is valid
30+
31+
The game will have to check if a square is valid.
32+
A square is valid if the rank and file are within the ranges of the ranks and files.
33+
34+
Define the `isValidSquare(rank:file:)` method that takes the arguments `rank` that holds an int of the rank and `file` that holds a char of the file.
35+
The method should return `true` if the rank and file are within the range of ranks and files, and return `false` otherwise.
36+
37+
```swift
38+
isValidSquare(rank: 1, file: "A")
39+
// returns true
40+
```
41+
42+
## 3. Get row
43+
44+
The game will store all the squares of the board in a single dimensional array.
45+
The squares are formed as a string of the rank and file, e.g. "1A", "8B", "4G", etc.
46+
To get the row of a square, the game will have to calculate the index of the first square of the row.
47+
48+
Define the `getRow(rank:)` method that takes the argument `rank` that holds an int of the rank.
49+
The method should return an array of strings that represent the squares of the row.
50+
51+
```swift
52+
let board = ["1A", "1B", "1C", "1D", "1E", "1F", "1G", "1H", "2A", ..., "8H"]
53+
getRow(board, rank: 1)
54+
// returns ["1A", "1B", "1C", "1D", "1E", "1F", "1G", "1H"]
55+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Ranges
2+
3+
[Ranges][range] represent an interval between two values.
4+
The most common types that support ranges are `Int`, `String`, and `Date`.
5+
They can be used for many things, such as quickly creating a collection, slicing an array, checking if a value is in a range, and iteration.
6+
They are created using the range operator `...` or `..<` (inclusive and exclusive, respectively).
7+
8+
```swift
9+
1...5 // A range containing 1, 2, 3, 4, 5
10+
1..<5 // A range containing 1, 2, 3, 4
11+
```
12+
13+
The reason for having two range operators is to create ranges that are inclusive or exclusive of the end value, which can be useful when, for example, working with zero-based indexes.
14+
15+
~~~~exercism/note
16+
When creating a range in Swift using the range operators `...` or `..<`, and wanting to call a method on the range, you need to wrap the range in parentheses.
17+
This is because the otherwise will the method be called on the 2nd argument of the range operator.
18+
19+
```swift
20+
(1...5).contains(3) // Returns true
21+
1...5.contains(3) // => Error: value of type 'Int' has no member 'contains'
22+
```
23+
~~~~
24+
25+
## Convert a range to an array
26+
27+
To convert a range to an array, you can use the `Array` initializer.
28+
This can be useful when you want to create a collection of values, without having to write them out.
29+
30+
```swift
31+
let range = 1...5
32+
let array = Array(range) // Returns [1, 2, 3, 4, 5]
33+
```
34+
35+
## Slice an array
36+
37+
Ranges can be used to slice an array.
38+
39+
```swift
40+
let array = [1, 2, 3, 4, 5]
41+
let slice = array[1...3] // Returns [2, 3, 4]
42+
```
43+
44+
## Range methods
45+
46+
Ranges do have a set of methods that can be used to work with them.
47+
For example, these methods can be used to get the sum of all the values in the range or check if the range includes a value.
48+
49+
| Method                  | Description                                                             | Example                         |
50+
| ----------------------- | ----------------------------------------------------------------------- | ------------------------------------- |
51+
| `count`       | Returns the size of the range                                         | `(1...5).count // returns 5` |
52+
| [`contains`][contains] | Returns `true` if the range includes the given value, otherwise `false` | `(1...5).contains(3) // Returns true` |
53+
54+
## Endless & Beginningless ranges
55+
56+
A range can be endless and beginless.
57+
58+
Using beginless and endless ranges is useful when you want to, for example, slice an array from the beginning or to the end.
59+
60+
~~~~exercism/caution
61+
If not used on a collection, the endless range can cause an endless sequence, if not used with caution.
62+
~~~~
63+
64+
## String ranges
65+
66+
String can be used in ranges and allow you to get an interval of Strings between two Strings.
67+
For example, this can be handy when you want to get the alphabet.
68+
69+
```swift
70+
"a"..."z" // A range containing ["a", "b", "c", ..., "z"]
71+
```
72+
73+
[range]: https://developer.apple.com/documentation/swift/range
74+
[contains]: https://developer.apple.com/documentation/swift/range/contains(_:)
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.DS_Store
2+
/.build
3+
/Packages
4+
/*.xcodeproj
5+
xcuserdata/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
let ranks = 1...8
2+
let files = "A"..."H"
3+
4+
func isVaildSquare(rank: Int, file: String) -> Bool {
5+
return ranks.contains(rank) && files.contains(file)
6+
}
7+
8+
func getRow(_ board : [String], rank: Int) -> [String] {
9+
let startIndex = (rank - 1) * 8
10+
let endIndex = startIndex + 8
11+
return Array(board[startIndex..<endIndex])
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"authors": [
3+
"meatball133"
4+
],
5+
"files": {
6+
"solution": [
7+
"Sources/ChessBoard/ChessBoard.swift"
8+
],
9+
"test": [
10+
"Tests/ChessBoardTests/ChessBoardTests.swift"
11+
],
12+
"exemplar": [
13+
".meta/Sources/ChessBoard/ChessBoardExemplar.swift"
14+
]
15+
},
16+
"blurb": "Learn about ranges while making a chess board.",
17+
"icon": "chessboard"
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// swift-tools-version:6.0
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
4+
import PackageDescription
5+
6+
let package = Package(
7+
name: "ChessBoard",
8+
products: [
9+
// Products define the executables and libraries a package produces, and make them visible to other packages.
10+
.library(
11+
name: "ChessBoard",
12+
targets: ["ChessBoard"])
13+
],
14+
dependencies: [
15+
// Dependencies declare other packages that this package depends on.
16+
// .package(url: /* package url */, from: "1.0.0"),
17+
],
18+
targets: [
19+
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
20+
// Targets can depend on other targets in this package, and on products in packages this package depends on.
21+
.target(
22+
name: "ChessBoard",
23+
dependencies: []),
24+
.testTarget(
25+
name: "ChessBoardTests",
26+
dependencies: ["ChessBoard"]),
27+
]
28+
)

0 commit comments

Comments
 (0)