Searching a Set in Swift - swift

I have something like the following
struct ht : Hashable {
var x : Int
var y : Int
var z : Int
//Edit added following func following Ahmad's comment
var hashValue: Int { return (x+y+z) }
static func == (lhs: ht, rhs: ht) -> Bool
{
return lhs.x == rhs.x
&& lhs.y == rhs.y
&& lhs.z == rhs.z
}
}
let defaultX = 4
let searchForX = 7
//let searchForX = 1000000
var ss : Set<ht> = [ ht(x:1,y:2,z:3), ht(x:4,y:5,z:6), ht(x:7, y:8, z:100), ht(x:9, y:19, z:12)]
Does Swift have LINQ like functionality where I can search the set ss to retrieve the struct that matches searchForX = 7 as shown above to return (7, 8, 100)? If searchForX = 1000000 I want it to return (4, 5, 6), so failing over to returning the value where defaultX = 4
My current code uses loops. In C# you can use LINQ and specify .FirstOrDefault(...).
Is this possible in Swift?
Thank you

Swift isn't really my thing but a ternary operator similar to the code below may move you along.
var answer = ss.first(where: { $0.x == searchForX }) ?? ss.first(where: { $0.x == defaultX })
Regards
Mike

So the quick answer to your question is
let element = ss.first { $0.x == searchForX } ?? ss.first { $0.x == defaultX }
This can be turned a simple extension
extension Sequence {
func first(_ criteria: (Element) -> Bool, orDefault: (Element) -> Bool) -> Element? {
return first(where: criteria) ?? first(where: orDefault)
}
}
let element = ss.first({ $0.x == searchForX }, orDefault: { $0.x == searchForX })
By making this an extension on Sequence, it will work for Arrays and anything that implements Sequence.
If you are concerned about performance you can roll your own.
extension Sequence {
func first(_ criteria: (Element) -> Bool, orDefault: (Element) -> Bool) -> Element? {
var defaultElement: Element?
for element in self {
if criteria(element) { return element }
if criteria(element) { defaultElement = element }
}
return defaultElement
}
}

You could implement your own custom method to do the desired functionality.
First of all, if you would declare a set of custom structs, note that your struct must be Hashable protocol -which means that it implicitly must be Equatable -, thus it would be implemented as follows:
struct MyStruct: Hashable, Equatable {
var x : Int
var y : Int
var z : Int
// Hashable
var hashValue: Int
// Equatable
static func ==(lhs: MyStruct, rhs: MyStruct) -> Bool {
return lhs.x == rhs.x
}
}
So, you could declare a set of MyStruct.
Probably this is not the right way to assign a value to the hashValue, but for the purpose of answering the question I will assign dummy values to them.
For implementing the method for achieving the desired output, I would recommend to declare it in a set extension (if you would let it also functional for arrays, you could declare it as a Collection extension instead), constrained by the set element type:
extension Set where Element == MyStruct {
func firstOrDefault(for expectedXValue: Int, defaultXValue: Int) -> MyStruct? {
// expeccted
if let expected = first(where: { $0.x == expectedXValue }) {
return expected
}
// default
if let defaultValue = first(where: { $0.x == defaultXValue }) {
return defaultValue
}
// neither
return nil
}
}
Note that if there are more than one expected or default x value in the set, it would returns the first matched one.
You would notice that the main functionality of implementing firstOrDefault method is to use first(where:) method (which is similar to what are you looking for), with a little bit of logic to get a -first- default value instead.
Output:
In case of there is an expected object with x = 7:
let mySet: Set<MyStruct> = [MyStruct(x: 1, y: 2, z: 3, hashValue: 101),
MyStruct(x: 4, y: 5, z: 6, hashValue: 102),
MyStruct(x: 7, y: 8, z: 100, hashValue: 103),
MyStruct(x: 9, y: 19, z: 12, hashValue: 104)]
let myObject = mySet.firstOrDefault(for: 7, defaultXValue: 4)
dump(myObject)
/*
▿ Optional(__lldb_expr_187.MyStruct(x: 7, y: 8, z: 9, hashValue: 102))
▿ some: __lldb_expr_187.MyStruct
- x: 7
- y: 8
- z: 9
- hashValue: 102
*/
In case of there is no expected value and the default x = 4:
let mySet2: Set<MyStruct> = [MyStruct(x: 1, y: 2, z: 3, hashValue: 101),
MyStruct(x: 4, y: 5, z: 6, hashValue: 102),
MyStruct(x: 1000, y: 8, z: 100, hashValue: 103),
MyStruct(x: 9, y: 19, z: 12, hashValue: 104)]
let myObject2 = mySet2.firstOrDefault(for: 7, defaultXValue: 4)
dump(myObject2)
/*
▿ Optional(__lldb_expr_249.MyStruct(x: 4, y: 5, z: 6, hashValue: 102))
▿ some: __lldb_expr_249.MyStruct
- x: 4
- y: 5
- z: 6
- hashValue: 102
*/
In case of there is no expected and no default value:
let mySet3: Set<MyStruct> = [MyStruct(x: 1, y: 2, z: 3, hashValue: 101),
MyStruct(x: 1000, y: 5, z: 6, hashValue: 102),
MyStruct(x: 1000, y: 8, z: 100, hashValue: 103),
MyStruct(x: 9, y: 19, z: 12, hashValue: 104)]
let myObject3 = mySet3.firstOrDefault(for: 7, defaultXValue: 4)
dump(myObject3) // - nil

Related

ambiguous use of init with default values

I have class that have two similar looking initializers:
public init(
contentInsets: MyInsets = .init(vertical: .level0, horizontal: .level6),
midToLeftSpacing: CGFloat = 0,
rightToMidSpacing: CGFloat = 0
)
public init(
contentInsets: MyInsets = .init(vertical: .level0, horizontal: .level6),
midToLeftSpacing: MyInsetLevel = .level0,
rightToMidSpacing: MyInsetLevel = .level0
)
Now i run into problem, looks like when i trying to call initializer compiler can't figure out which one to chose:
init(
vertical: .level0,
left: .level22,
right: .level0
)
Gives error - Ambiguous use of 'init'
It could be easily fixed with modifying initializer or adding next argument with default value, but it doesn't look right, is there any other way to specify init method called?
Your example doesn't match your code (there is no init(vertical:left:right) defined), so I'm going to try to generalize this problem a bit with a full example that avoids the extra types. I'll just use Double and Int here.
Imagine a struct X that internally stores three Doubles:
struct X {
var x: Double
var y: Double
var z: Double
init(x: Double = 0, y: Double = 0, z: Double = 0) {
self.x = x
self.y = y
self.z = z
}
}
You also want to be able to pass three Ints instead, but all three must either be Doubles or Ints, and you want default values. Every use of default values is just a shorthand for an extra method with fewer parameters. To avoid conflicts, you need to include at least one of the parameters as non-default:
extension X {
init(x: Int, y: Int = 0, z: Int = 0) {
self.init(x: Double(x), y: Double(y), z: Double(z))
}
init(y: Int, z: Int = 0) { self.init(x: 0, y: y, z: z) }
init(z: Int) { self.init(x: 0, y: 0, z: z) }
}
Now, every combination is legal, but there are no ambiguities.
This is nice when there's just one extra way to call the init. But maybe you want there to be many. Then a protocol is useful. For example, this approach allows either Int or Double for every parameter:
protocol XParameter {
var xParameterValue: Double { get }
}
extension Double: XParameter {
var xParameterValue: Double { self }
}
extension Int: XParameter {
var xParameterValue: Double { Double(self) }
}
struct X {
var x: Double
var y: Double
var z: Double
init(x: some XParameter = 0, y: some XParameter = 0, z: some XParameter = 0) {
self.x = x.xParameterValue
self.y = y.xParameterValue
self.z = z.xParameterValue
}
}

loading series of struct from data in Swift [duplicate]

This question already has answers here:
round trip Swift number types to/from Data
(3 answers)
Swift 5.0: 'withUnsafeBytes' is deprecated: use `withUnsafeBytes<R>(...)
(4 answers)
Closed 1 year ago.
I am not sure where I got this piece of code. But here I have some code to get series of Vertex(or whatever) out of Data in swift.
struct Vertex {
var x, y, z, w: Float16
var r, g, b, a: Float16
}
extension Data {
func elements<T>() -> [T] {
return withUnsafeBytes {
Array(UnsafeBufferPointer<T>(start: $0, count: count/MemoryLayout<T>.stride))
}
}
}
It works fine to me, but I have this warning. I spent some time, but I cannot figure this out. So could someone please help me out?
'withUnsafeBytes' is deprecated: use `withUnsafeBytes<R>(_: (UnsafeRawBufferPointer) throws -> R) rethrows -> R` instead
By the way, I am trying to save and load large number of data with this way with pairing of following piece of code.
extension Array {
var data: Data {
var value = self
return NSData(bytes: &value, length: MemoryLayout<Element>.stride * self.count) as Data
}
}
Thank you,
EDIT
Here is the code what I like to do, it works fine, but I like to get rid of warning...
struct Vertex: Equatable {
var x, y, z, w: Float16
var r, g, b, a: Float16
// assumption: no precision error
static func == (lhs: Self, rhs: Self) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z && lhs.w == rhs.w &&
lhs.r == rhs.r && lhs.g == rhs.g && lhs.b == rhs.b && lhs.a == rhs.a
}
}
let v0 = Vertex(x: 1, y: 2, z: 3, w: 4, r: 0, g: 0.25, b: 0.5, a: 0.75)
let v1 = Vertex(x: 5, y: 6, z: 7, w: 8, r: 0.2, g: 0.4, b: 0.6, a: 0.8)
let v2 = Vertex(x: 9, y: 0, z: 1, w: 2, r: 0.5, g: 0.75, b: 0.0, a: 1.0)
let original: [Vertex] = [v0, v1, v2]
let data = original.data
print(data as NSData)
let restored: [Vertex] = data.elements()
let w0 = restored[0]
let w1 = restored[1]
let w2 = restored[2]
print(v0 == w0)
print(v1 == w1)
print(v2 == w2)
First make your struct conform to ContiguousBytes:
extension Vertex: ContiguousBytes {
func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
try Swift.withUnsafeBytes(of: self) { try body($0) }
}
}
Then create a custom initializer on ContiguousBytes to allow initializing any type that conforms to it with contiguous bytes:
extension ContiguousBytes {
init<T: ContiguousBytes>(_ bytes: T) {
self = bytes.withUnsafeBytes { $0.load(as: Self.self) }
}
}
To extract the bytes/data from the types that conform to it:
extension ContiguousBytes {
var bytes: [UInt8] { withUnsafeBytes { .init($0) } }
var data: Data { withUnsafeBytes { .init($0) } }
}
Now you can simply make the magic happen.
Playground testing:
struct Vertex {
var x, y, z, w: Float16
var r, g, b, a: Float16
}
let vertex = Vertex(x: 1.2, y: 2.3, z: 3.4, w: 4.5, r: 0.5, g: 0.6, b: 0.7, a: 1)
let bytes = vertex.bytes // [205, 60, 154, 64, 205, 66, 128, 68, 0, 56, 205, 56, 154, 57, 0, 60]
let loadedVertex = Vertex(bytes)
print(loadedVertex) // Vertex(x: 1.2, y: 2.3, z: 3.4, w: 4.5, r: 0.5, g: 0.6, b: 0.7, a: 1.0)
edit/update:
to convert your bytes to a collection of vertices:
extension Array {
var data: Data {
var value = self
return .init(bytes: &value, count: MemoryLayout<Element>.stride * count)
}
}
extension ContiguousBytes {
func objects<T>() -> [T] { withUnsafeBytes { .init($0.bindMemory(to: T.self)) } }
var vertices: [Vertex] { objects() }
}
let vertex1 = Vertex(x: 1.2, y: 2.3, z: 3.4, w: 4.5, r: 0.5, g: 0.6, b: 0.7, a: 1)
let vertex2 = Vertex(x: 2.3, y: 3.4, z: 4.5, w: 5.6, r: 1, g: 0.8, b: 1, a: 1)
let data = [vertex1, vertex2].data
let loadedVertices = data.vertices
print(loadedVertices) // [__lldb_expr_8.Vertex(x: 1.2, y: 2.3, z: 3.4, w: 4.5, r: 0.5, g: 0.6, b: 0.7, a: 1.0), __lldb_expr_8.Vertex(x: 2.3, y: 3.4, z: 4.5, w: 5.6, r: 1.0, g: 0.8, b: 1.0, a: 1.0)]
To mirror what is being done in .data I believe you just want to copy the bytes directly into the Array. This is all pretty dangerous, because it's making some pretty strong assumptions around memory management (if T, or any property of T were a class or included hidden classes internally, the reference counts could be wrong). So I'd be really uncomfortable making this a generic extension like this. But for Float16 it's probably fine, assuming that you never encounter an endian issue (or an architecture that pads differently).
But to just do what you're doing, I'd recommend:
extension Data {
func elements<T>() -> [T] {
Array(unsafeUninitializedCapacity: count/MemoryLayout<T>.stride) { buffer, initializedCount in
copyBytes(to: buffer)
initializedCount = buffer.count
}
}
}

Distinct Pair sum swift

Hi am trying to get the number of distinct pair that add up to a particular value. currently I am able to get equal pairs but I am unable to get a work around for distinct pairs.
func checkPairs(in numbers: [Int], forSum target: Int) -> Int {
for (i, x) in numbers.enumerated() {
for y in numbers[i+1 ..< numbers.count] {
if x + y == target {
return x
}
if x + y > target {
break
}
}
}
return 0
}
print(checkPairs(in: [5,7,9,13,11,6,6,3,3], forSum: 12))
Sets are great for keeping track of unique things. Since you want (5, 7) and (7, 5) to be counted as the same pair, you can always store them in the same order (lowest value first, for instance). Use a struct to store the pair and make it Hashable so that it can be used with a Set. Then add your pairs to the Set as you find them and get the .count at the end.
struct Pair: Hashable, CustomStringConvertible {
let x: Int
let y: Int
var description: String { "(\(x), \(y))" }
init(_ x: Int, _ y: Int) {
self.x = min(x, y)
self.y = max(x, y)
}
}
func checkPairs(in numbers: [Int], forSum target: Int) -> Int {
var set = Set<Pair>()
for (i, x) in numbers.enumerated() {
for y in numbers[i+1 ..< numbers.count] {
if x + y == target {
set.insert(Pair(x, y))
}
}
}
print(set)
return set.count
}
print(checkPairs(in: [5,7,9,13,11,6,6,3,3], forSum: 12))
[(6, 6), (5, 7), (3, 9)]
3

Fibonacci numbers generator in Swift 3

The following Q&A covers a few methods of generating Fibonacci numbers in Swift, but it's quite outdated (Swift 1.2?):
Sum of Fibonacci term using Functional Swift
Question: How could we generate Fibonacci numbers neatly using modern Swift (Swift >= 3)? Preferably methods avoiding explicit recursion.
An alternative for Swift 3.0 would be to use the helper function
public func sequence<T>(first: T, while condition: #escaping (T)-> Bool, next: #escaping (T) -> T) -> UnfoldSequence<T, T> {
let nextState = { (state: inout T) -> T? in
// Return `nil` if condition is no longer satisfied:
guard condition(state) else { return nil }
// Update current value _after_ returning from this call:
defer { state = next(state) }
// Return current value:
return state
}
return sequence(state: first, next: nextState)
}
from Express for loops in swift with dynamic range:
for f in sequence(first: (0, 1), while: { $1 <= 50 }, next: { ($1, $0 + $1)}) {
print(f.1)
}
// 1 1 2 3 5 8 13 21 34
Note that in order to include zero in the resulting sequence, it
suffices to replace the initial value (0, 1) by (1, 0):
for f in sequence(first: (1, 0), while: { $1 <= 50 }, next: { ($1, $0 + $1)}) {
print(f.1)
}
// 0 1 1 2 3 5 8 13 21 34
That makes the "artificial" check
if pair.1 == 0 { pair.1 = 1; return 0 }
redundant. The underlying reason is that the Fibonacci numbers can
be generalized to negative indices (https://en.wikipedia.org/wiki/Generalizations_of_Fibonacci_numbers):
... -8, 5, -3, 2, -1, 1, 0, 1, 1, 2, 3, 5, 8, ...
Using the global sequence(state:next:) function
Swift 3.0
As one alternative we could make use of one the neat global sequence functions, a pair of functions that were implemented in Swift 3.0 (as described in evolution proposal SE-0094).
sequence(first:next:)
sequence(state:next:)
Using the latter of these, we may keep the previous and current state of the Fibonacci numbers sequence as the mutable state property in the next closure of sequence(state:next:).
func fibs(through: Int, includingZero useZero: Bool = false)
-> UnfoldSequence<Int, (Int, Int)> {
return sequence(state: useZero ? (1, 0) : (0, 1),
next: { (pair: inout (Int, Int)) -> Int? in
guard pair.1 <= through else { return nil }
defer { pair = (pair.1, pair.0 + pair.1) }
return pair.1
})
}
// explicit type annotation of inout parameter closure
// needed due to (current) limitation in Swift's type
// inference
// alternatively, always start from one: drop useZero
// conditional at 'state' initialization
func fibs1(through: Int)
-> UnfoldSequence<Int, (Int, Int)> {
return sequence(state: (0, 1),
next: { (pair: inout (Int, Int)) -> Int? in
guard pair.1 <= through else { return nil }
defer { pair = (pair.1, pair.0 + pair.1) }
return pair.1
})
}
Or, condensing this using tuple hacks (however executing next one extra, unnecessary, time)
func fibs(through: Int, includingZero useZero: Bool = false) -> UnfoldSequence<Int, (Int, Int)> {
return sequence(state: useZero ? (1, 0) : (0, 1), next: {
($0.1 <= through ? $0.1 : Optional<Int>.none, $0 = ($0.1, $0.0 + $0.1)).0 })
}
func fibs1(through: Int) -> UnfoldSequence<Int, (Int, Int)> {
return sequence(state: (0, 1), next: {
($0.1 <= through ? $0.1 : Optional<Int>.none, $0 = ($0.1, $0.0 + $0.1)).0 })
}
Note that we explicitly terminate the sequences with a nil return when the ... <= through condition is no longer met.
Example usage:
// fib numbers up through 50, excluding 0
fibs(through: 50).forEach { print($0) }
// 1 1 2 3 5 8 13 21 34
// ... or
fibs1(through: 50).forEach { print($0) }
// 1 1 2 3 5 8 13 21 34
// ... including 0
fibs(through: 50, includingZero: true).forEach { print($0) }
// 0 1 1 2 3 5 8 13 21 34
// project Euler #2: sum of even fib numbers up to 4000000
print(fibs(through: 4_000_000)
.reduce(0) { $1 % 2 == 0 ? $0 + $1 : $0 }) // 4 613 732
We could also remove the termination criteria from above to construct an infinite sequence of fibonacci numbers, to be used in combination e.g. with prefix:
func infFibs() -> UnfoldSequence<Int, (Int, Int)> {
return sequence(state: (0, 1), next: {
(pair: inout (Int, Int)) -> Int in (pair.1, pair = (pair.1, pair.0 + pair.1)).0 })
}
// prefix the first 6 fib numbers (excluding 0) from
// the infinite sequence of fib numbers
infFibs().prefix(10).forEach { print($0) }
// 1 1 2 3 5 8 13 21 34 55
Swift 3.1
When Swift 3.1 arrives, the prefix(while:) method for sequences, as described in evolution proposal SE-0045, will have been implemented. Using this additional feature, we can modify the fibs methods above to avoid the explicit by-nil conditional sequence termination:
func fibs(through: Int, startingFromZero useZero: Bool = false)
-> AnySequence<Int> {
return sequence(state: useZero ? (1, 0) : (0, 1),
next: { (pair: inout (Int, Int)) -> Int? in
defer { pair = (pair.1, pair.0 + pair.1) }
return pair.1
}).prefix(while: { $0 <= through })
}
// alternatively, always start from one: drop useZero
// conditional at 'state' initialization
func fibs1(through: Int) -> AnySequence<Int> {
return sequence(state: (0, 1),
next: { (pair: inout (Int, Int)) -> Int? in
defer { pair = (pair.1, pair.0 + pair.1) }
return pair.1
}).prefix(while: { $0 <= through })
}
Examples should work the same as for Swift 3.0 above.
In Swift 3.1, here's an iterator that generates Fibonacci numbers forever, and an infinite sequence derived from it:
class FibIterator : IteratorProtocol {
var (a, b) = (0, 1)
func next() -> Int? {
(a, b) = (b, a + b)
return a
}
}
let fibs = AnySequence{FibIterator()}
To print the first 10 Fibonacci numbers:
> print(Array(fibs.prefix(10)))
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
If you want to filter or map this infinite sequence you'll need to call .lazy first, since otherwise filter or map will behave strictly and will not terminate. Here are the first 5 even Fibonacci numbers:
> print( Array(fibs.lazy.filter{$0 % 2 == 0}.prefix(5)) )
[2, 8, 34, 144, 610]
I have just saw Dhaval Gevariya code and just move print fibonacci above instead below and now it will print 0 also
func fibonaci(n: Int)
{
var fiboNumberOne = 1
var fiboNumberTwo = 0
for i in 0..<n
{
print("Fibonaci \(fiboNumberTwo)")
let temp = fiboNumberOne + fiboNumberTwo
fiboNumberOne = fiboNumberTwo
fiboNumberTwo = temp
}
}
fibonaci(n: 5)
From David kopec's book “Classic Computer Science Problems in Swift”:
By recursion
var fibMemo: [UInt: UInt] = [0: 0, 1: 1] // our old base cases
func fib3(n: UInt) ­> UInt
{
if let result = fibMemo[n]
{
// our new base case
return result
}
else
{
fibMemo[n] = fib3(n: n ­ 1) + fib3(n: n ­ 2) // memoization
}
return fibMemo[n]!
}
By iterative approach
func fib4(n: UInt) ­> UInt
{
if (n == 0)
{
// special case
return n
}
var last: UInt = 0, next: UInt = 1 // initially set to fib(0) & fib(1
for _ in 1..<n {
(last, next) = (next, last + next) }
return next
}
func fibonaci(n: Int)
{
var fiboNumberOne = 1
var fiboNumberTwo = 0
for i in 0..<n
{
let temp = fiboNumberOne + fiboNumberTwo
fiboNumberOne = fiboNumberTwo
fiboNumberTwo = temp
print("Fibonaci \(fiboNumberTwo)")
}
}
fibonaci(n: 5)
If you don't need accuracy there is O(1) function for your needs:
func fibonacci(iteration: Int) -> Int {
return Int(round(pow(1.618033988749895, Double(iteration)) / 2.23606797749979))
}
So here how it works:
print((0..<40).map(fibonacci))
// prints [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181]
Works perfectly until 70 iteration.
Warning: On 71 iteration returns 308061521170130 instead of 308061521170129
Details
Xcode 9.3.1, Swift 4.1
Solution
extension Array where Element: BinaryInteger {
private mutating func fibonacci(index: Int) {
if index >= count {
return
}
self[index] = self[index-1] + self[index-2]
return fibonacci(index: index+1)
}
init(fibonacci count: Int) {
self = [Element]()
if count < 0 {
self = [Element]()
}
self = [Element](repeating: 1, count: count)
fibonacci(index: 2)
}
static func calculate(fibonacciAt index: Int) -> Element? {
if index < 0 {
return nil
}
if index < 2 {
return 1
}
func calc(a: Element, b: Element, index: Int) -> Element {
if index == 1 {
return b
}
return calc(a: b, b: a+b, index: index-1)
}
return calc(a: 1, b: 1, index: index)
}
}
Usage
let fibonacciSequence = [Int](fibonacci: 15)
let index = 12
print(fibonacciSequence)
print(fibonacciSequence[index])
let value = [Int].calculate(fibonacciAt: index)
print("\(value!)")
Results
Details
XCode Version 10.0 beta 6, Swift 4.2
The control flow is required to get either the first or the first two iterations of the fibonacci seq starting with 0.
Time Complexity: O(n)
Space Complexity: O(n)
Code
func fib(_ n: Int) -> [Int] {
var fibs: [Int] = [0, 1]
switch n
{
case 1: return [fibs[0]]
case 2: return [fibs[0],fibs[1]]
default:
(2...n-1).forEach
{ i in
fibs.append(fibs[i - 1] + fibs[i - 2])
}
return fibs
}
}
Usage
fib(8)
//print(fib(8))
// MARK: - Function
func fibonacciSeries(_ num1 : Int,_ num2 : Int,_ term : Int,_ termCount : Int) -> Void{
if termCount != term{
print(num1)
fibonacciSeries(num2, num2+num1, term, termCount + 1)
}
}
// MARK: - Calling Of Function
fibonacciSeries(0, 1, 5, 0)
// MARK: - out Put
0 1 1 2 3
Note Need to Change only No Of term for fibonacci Series.
func fibonacci(n: Int) -> Int {
if n <= 1 {
return n
} else {
return fibonacci(n: n - 1) + fibonacci(n: n - 2)
}
}
print(fibonacci(n: 10))
This is bad to use recursion!! recursion is evil!
I would have rather done it this way:
func fibo(_ n:Int) -> Int {
var a = 0
var b = 1
for _ in 0..<n {
a += b
b = a - b
}
return a
}
Which is much faster and cleaner!

Is there a specific way to use tuples as set elements in Swift?

I want to do set operations on co-ordinate pair elements from an x-y grid.
E.g. {(0,0),(1,4),(1,5),(2,3)} union with {(2,3),(1,4),(2,6)} = {(0,0),(1,4),(1,5),(2,3),(2,6)}
Unfortunately I can't work out a way of inserting tuples into Swift's Set commands as it says that they do not conform to the 'hashable' protocol.
Error: type '(Int, Int)' does not conform to protocol 'Hashable'
I believe I've got a work around but it involves a lot of code. Is there a simple way that I'm missing before I hit the grindstone?
Rather than using tuples to represent points, use the built in type CGPoint. You can extend CGPoint to be hashable by extending it:
import UIKit
extension CGPoint: Hashable {
public var hashValue: Int {
return self.x.hashValue << sizeof(CGFloat) ^ self.y.hashValue
}
}
// Hashable requires Equatable, so define the equality function for CGPoints.
public func ==(lhs: CGPoint, rhs: CGPoint) -> Bool {
return CGPointEqualToPoint(lhs, rhs)
}
Now that CGPoint is Hashable, you can use it in sets. For example:
let point1 = CGPoint(x: 0, y: 1)
let point2 = CGPoint(x: 0, y: 2)
let point3 = CGPoint(x: 1, y: 1)
let point4 = CGPoint(x: 3, y: 3)
let point5 = CGPoint(x: 3, y: 3) // Intentionally the same as point4 to see the effect in union and difference.
let set1 = Set([point1, point2 , point5])
let set2 = Set([point4, point3])
let union = set1.union(set2) // -> {{x 0 y 2}, {x 3 y 3}, {x 0 y 1}, {x 1 y 1}}
let difference = set1.intersect(set2) // -> {{x 3 y 3}}
You could make a struct as a Hashable type:
struct Point: Hashable {
let x: Int
let y: Int
}
Now that you have a hashable tuple, normal Set operations can be used:
let set1 = Set([
Point(x:0,y:0),
Point(x:1,y:4),
Point(x:1,y:5),
Point(x:2,y:3)
])
let set2 = Set([
Point(x:2,y:3),
Point(x:1,y:4),
Point(x:2,y:6)
])
let setUnion = set1.union(set2)
/*
setUnion = {
Point(x: 1, y: 5),
Point(x: 0, y: 0),
Point(x: 1, y: 4),
Point(x: 2, y: 3),
Point(x: 2, y: 6)
}
*/
Here you go:
class Pair {
var x: Int
var y: Int
init(x: Int, y:Int){
self.x = x
self.y = y
}
func isExisted(inPairs pairs:[Pair]) -> Bool {
for p in pairs {
if p.y == self.y && p.x == self.x{
return true
}
}
return false
}
static func union (pairs1: [Pair], pairs2: [Pair]) -> [Pair] {
var pairsFinal = [Pair]()
for p in pairs1 {
pairsFinal.append(p)
}
for p in pairs2 {
if !p.isExisted(inPairs: pairsFinal){
pairsFinal.append(p)
}
}
return pairsFinal
}
}
let pari1 = Pair(x: 4, y: 7)
let pair2 = Pair(x: 5, y: 2)
let pair3 = Pair(x: 4, y: 7)
let pair4 = Pair(x: 3, y: 9)
let pairs1 = [pari1, pair2]
let pairs2 = [pair3, pair4]
let f = Pair.union(pairs1, pairs2: pairs2)
And this is the result of the union: