Skip to content

Commit 8277e5f

Browse files
committed
Initial commit
0 parents  commit 8277e5f

File tree

4 files changed

+222
-0
lines changed

4 files changed

+222
-0
lines changed

.gitignore

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Xcode
2+
#
3+
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4+
5+
## Build generated
6+
build/
7+
DerivedData/
8+
9+
## Various settings
10+
*.pbxuser
11+
!default.pbxuser
12+
*.mode1v3
13+
!default.mode1v3
14+
*.mode2v3
15+
!default.mode2v3
16+
*.perspectivev3
17+
!default.perspectivev3
18+
xcuserdata/
19+
20+
## Other
21+
*.moved-aside
22+
*.xccheckout
23+
*.xcscmblueprint
24+
25+
## Obj-C/Swift specific
26+
*.hmap
27+
*.ipa
28+
*.dSYM.zip
29+
*.dSYM
30+
31+
## Playgrounds
32+
timeline.xctimeline
33+
playground.xcworkspace
34+
35+
# Swift Package Manager
36+
#
37+
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
38+
# Packages/
39+
# Package.pins
40+
.build/
41+
42+
# CocoaPods
43+
#
44+
# We recommend against adding the Pods directory to your .gitignore. However
45+
# you should judge for yourself, the pros and cons are mentioned at:
46+
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
47+
#
48+
# Pods/
49+
50+
# Carthage
51+
#
52+
# Add this line if you want to avoid checking in source code from Carthage dependencies.
53+
Carthage/Checkouts
54+
Carthage/Build
55+
56+
# fastlane
57+
#
58+
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
59+
# screenshots whenever they are needed.
60+
# For more information about the recommended setup visit:
61+
# https://docs.fastlane.tools/best-practices/source-control/#source-control
62+
63+
fastlane/report.xml
64+
fastlane/Preview.html
65+
fastlane/screenshots
66+
fastlane/test_output
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
//
2+
// ChessKnightShortestPath.playground
3+
//
4+
// Created by Ivan Kalaica on 20/10/2017.
5+
// Copyright © 2017 Kalaica. All rights reserved.
6+
//
7+
8+
// all 8 possible movements for a knight
9+
fileprivate let knightMoves = [
10+
[ 2, -1],
11+
[ 2, 1],
12+
[-2, 1],
13+
[-2, -1],
14+
[ 1, 2],
15+
[ 1, -2],
16+
[-1, 2],
17+
[-1, -2]
18+
]
19+
20+
struct Node {
21+
let y: Int, x: Int // (x, y) represents chessboard coordinates
22+
let dist: Int // dist represent its minimum distance from the source
23+
24+
init(x: Int, y: Int, dist: Int = 0) {
25+
self.x = x
26+
self.y = y
27+
self.dist = dist
28+
}
29+
}
30+
31+
extension Node: Hashable {
32+
// Using Node struct as a key we need conform to Hashable
33+
var hashValue: Int {
34+
return "\(self.x)\(self.y)".hashValue
35+
}
36+
37+
static func ==(lhs: Node, rhs: Node) -> Bool {
38+
return lhs.x == rhs.x && lhs.y == rhs.y
39+
}
40+
}
41+
42+
enum BfsError: Error {
43+
case shortestPathNotFound
44+
}
45+
46+
// Find minimum number of steps taken by the knight
47+
// from source to destination using BFS
48+
func bfs(src: Node, dest: Node) throws -> Int {
49+
// map to check if matrix cell is visited before or not
50+
var visited = [Node: Bool]()
51+
52+
// Create a queue and enqueue first node
53+
// Queue node used in BFS
54+
var q = Queue(array: [Node]())
55+
q.enqueue(src)
56+
57+
// Run until queue is empty
58+
while (!q.isEmpty) {
59+
60+
// Pop front node and process it
61+
guard let node = q.dequeue() else { break }
62+
63+
let x = node.x
64+
let y = node.y
65+
let dist = node.dist
66+
67+
// If destination is reached, return distance
68+
if (x == dest.x && y == dest.y) { return dist }
69+
70+
// Skip if location is visited
71+
if visited[node] == nil {
72+
visited[node] = true
73+
74+
// Check for all 8 possible movements for a knight
75+
// and enqueue each valid movement
76+
for i in 0..<knightMoves.count {
77+
78+
// Get the new valid position of Knight from current
79+
// position on chessboard and enqueue it in the
80+
// queue with +1 distance
81+
let position = knightMoves[i]
82+
let x1 = x + position[0]
83+
let y1 = y + position[1]
84+
85+
if (isValid(x: x1, y: y1)) {
86+
q.enqueue(Node(x: x1, y: y1, dist: dist + 1))
87+
}
88+
}
89+
}
90+
}
91+
throw BfsError.shortestPathNotFound
92+
}
93+
94+
// Check if (x, y) is valid chessboard cordinate
95+
// Note that a knight cannot go out of the chessboard
96+
fileprivate func isValid(x: Int, y: Int) -> Bool {
97+
guard (x >= 0 && y >= 0 && x < knightMoves.count && y < knightMoves.count) else { return false }
98+
return true
99+
}
100+
101+
fileprivate struct Queue<T> {
102+
fileprivate var array = [T]()
103+
104+
public var isEmpty: Bool {
105+
return self.array.isEmpty
106+
}
107+
108+
public var count: Int {
109+
return self.array.count
110+
}
111+
112+
public mutating func enqueue(_ element: T) {
113+
self.array.append(element)
114+
}
115+
116+
public mutating func dequeue() -> T? {
117+
if self.isEmpty {
118+
return nil
119+
} else {
120+
return self.array.removeFirst()
121+
}
122+
}
123+
124+
public var front: T? {
125+
return self.array.first
126+
}
127+
}
128+
129+
if let a = try? bfs(src: Node(x: 0, y: 0), dest: Node(x: 7, y: 0)) {
130+
print("Minimum number of steps required is \(a).")
131+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<playground version='5.0' target-platform='ios'>
3+
<timeline fileName='timeline.xctimeline'/>
4+
</playground>

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2017 Ivan
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

0 commit comments

Comments
 (0)