Swift setting a struct value within another struct init - swift

I have Cell struct values (position:, state:) which need to be set within the init of my Grid struct, but I can't seem to set these values of Cell.
struct Cell {
var position: (Int,Int)
var state: CellState
init(_ position: (Int,Int), _ state: CellState) {
self.position = (0,0)
self.state = .empty
}
}
func positions(rows: Int, cols: Int) -> [Position] {
return (0 ..< rows)
.map { zip( [Int](repeating: $0, count: cols) , 0 ..< cols ) }
.flatMap { $0 }
.map { Position(row: $0.0,col: $0.1) }
}
I've commented all of the ways that I've tried to set the position to (row, col)
struct Grid {
static let offsets: [Position] = [
(row: -1, col: 1), (row: 0, col: 1), (row: 1, col: 1),
(row: -1, col: 0), (row: 1, col: 0),
(row: -1, col: -1), (row: 0, col: -1), (row: 1, col: -1)
]
var rows: Int = 10
var cols: Int = 10
var cells: [[Cell]] = [[Cell]]()
init(_ rows: Int,
_ cols: Int,
cellInitializer: (Int, Int) -> CellState = { _,_ in .empty } ) {
self.rows
self.cols
self.cells = [[Cell]](repeatElement([Cell](repeatElement(Cell((0,0), .empty), count: cols)),count: rows))
positions(rows: rows, cols: cols).forEach { row, col in
// var position = cells(position: (row, col)) => cannot call value of non-function type '[[Cell]]'
// cells.position = (row, col) => value type of '[[Cell]] has no member position'
// cells.position(row, col) => value type of '[[Cell]] has no member position'
// position *= cells.position(row, col) => closure cannot implicitly capture a mutating self parameter
}
}
}
Clearly the Cell struct has a property of position, so why can't I access it?

The problem is that none of your lines are actually accessing instances of your Cell struct.
Here's a functioning adaptation of your code. I allowed myself to remove extra stuff that seem to have been left out from your codebase:
struct Cell {
var position: (Int,Int)
init(_ position: (Int,Int)) {
self.position = (0,0)
}
}
func positions(rows: Int, cols: Int) -> [(Int, Int)] {
return (0 ..< rows)
.map { zip( [Int](repeating: $0, count: cols) , 0 ..< cols ) }
.flatMap { $0 }
.map { ($0.0, $0.1) }
}
struct Grid {
var rows: Int = 10
var cols: Int = 10
var cells: [[Cell]] = [[Cell]]()
init(_ rows: Int, _ cols: Int) {
self.rows = rows
self.cols = cols
self.cells = Array.init(repeating: Array.init(repeating: Cell((0,0)), count: cols), count: cols)
positions(rows: rows, cols: cols).forEach { row, col in
cells[row][col].position = (row, col)
}
}
}
let g = Grid(1, 2)
print(g.cells[0][1].position)
Now, for a more detailed explanation of the errors you encountered:
var position = cells(position: (row, col))
Here you're not setting anything on any cell. Instead, you're trying to call your grid as if it was a function, with a parameter position: (Int, Int).
cells.position = (row, col)
Here you're trying to set a property position on your matrix ([[Cell]]). And obviously, Swift complains that such property does not exists in its builtin type Array.
cells.position(row, col)
Here you're trying to set a property position on your matrix ([[Cell]]) and call it as a function with two parameters Int. The problem is similar as above.
position *= cells.position(row, col)
Here I'm can't tell what's going on, since position does not seems to have been declared in your code. I guess it comes from elsewhere in your codebase, or maybe it's merely a typo.

The issue here is that you are trying to access cells.position but cells is a two-dimensional array.
cells.position = (row, col) => value type of '[[Cell]] has no member position'
You could loop through the cells and set the position of each one.
So in your forEach loop you could write instead
cells[row][column].position = (row, col)
and that should do it.

Related

Swift subscript with generic data type

I am trying to program a two-dimensional data storage struct for various data types. However, I am struggling with the subscript for setting the data due 'Cannot assign value of type 'T' to subscript of type 'T' errors. Any help is much appreciated!
struct dataMatrix<T> : Sequence, IteratorProtocol {
var rows: Int, columns: Int
var data: [T]
var position = 0
init(rows: Int, columns: Int) {
self.rows = rows
self.columns = columns
data = Array<T>()
}
func valueAt(column: Int, row: Int) -> T? {
guard column >= 0 && row >= 0 && column < columns else {
return nil
}
let indexcolumn = column + row * columns
guard indexcolumn < data.count else {
return nil
}
return data[indexcolumn]
}
}
subscript<T>(column: Int, row:Int) -> T?{
get{
return valueAt(column: column, row: row) as? T
}
set{
data[(column * row) + column] = (newValue as! T) // does not compile
}
}
// sequence iterator protorocl methods
mutating func next() -> String? {
if position <= data.count{
print(position)
defer { position += 1 }
return "\(position)"
}else{
defer {position = 0}
return nil
}
}
}
subscript<T>(column: Int, row:Int) -> T?{
defines a generic method with a type placeholder T which is unrelated to the generic type T of struct dataMatrix<T>. The solution is simple: Remove the type placeholder:
subscript(column: Int, row: Int) -> T? {
// ...
}
That makes also the type casts inside the getter and setter unnecessary. You only have to decide what to do if the setter is called with a nil argument (e.g.: nothing):
subscript(column: Int, row: Int) -> T? {
get {
return valueAt(column: column, row: row)
}
set {
if let value = newValue {
data[(column * row) + column] = value
}
}
}
Another option is to make the return type of the subscript method non-optional, and treat invalid indices as a fatal error (which is how the Swift Array handles it):
subscript(column: Int, row: Int) -> T {
get {
guard let value = valueAt(column: column, row: row) else {
fatalError("index out of bounds")
}
return value
}
set {
data[(column * row) + column] = newValue
}
}

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

Swift: Access tuple elements using variables/arguments? [duplicate]

This question already has answers here:
Swift Tuple index using a variable as the index?
(5 answers)
Closed 6 years ago.
Here's the [generic version of the] situation:
let tuple: (first: Int, second: Int, third: Int) // tuple.0 is equivalent to tuple.first
enum TupleIndex: Int {
case first = 0, second, third
}
func selectTupleElement (index: TupleIndex) {
let indexNum = index.rawValue
let tupleElement = tuple.indexNum // Oh noooooo!!!
}
The compiler reads the problem spot, indicated in the last line above, as "the indexNum property or element of tuple" (which of course doesn't exist) rather than "the element of tuple at the index equal to the value of indexNum"
Is there a way to do what I'm trying to do, using tuples?
You could make use of runtime introspection to conditionally extract the n:th member of a tuple of fixed size and same-type members (e.g. below: implemented for tuple of arity 3 with uniform typed members) and (conditionally) convert it to the member's type. E.g.:
func selectTupleElementFor<T>(memberNumber: Int, inTuple tuple: (T, T, T)) -> T? {
return Mirror(reflecting: tuple).children.enumerated()
.first(where: { $0.0 == memberNumber - 1 }).flatMap { $1.1 as? T }
}
// example usage
let tuple: (first: Int, second: Int, third: Int) = (10, 20, 30)
if let tupleMember = selectTupleElementFor(memberNumber: 2, inTuple: tuple) {
print(tupleMember) // 20
}
Or, using your TupleIndex enum:
enum TupleIndex: Int {
case first = 0, second, third
}
func selectTupleElementFor<T>(tupleIndex: TupleIndex, inTuple tuple: (T, T, T)) -> T? {
return Mirror(reflecting: tuple).children.enumerated()
.first(where: { $0.0 == tupleIndex.rawValue }).flatMap { $1.1 as? T }
}
// example usage
let tuple: (first: Int, second: Int, third: Int) = (10, 20, 30)
if let tupleMember = selectTupleElementFor(tupleIndex: .second, inTuple: tuple) {
print(tupleMember) // 20
}

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!

Swift 2D Array optional Type and subscripting (Beta 3)

I have a 2D array that worked in Beta 2. However, in Beta 3 I'm getting '#lvalue $T15 is not identical to T?' when setting via subscript.
class Array2D<T> {
let columns: Int
let rows: Int
let array: [T?]
init(columns: Int, rows: Int) {
self.columns = columns
self.rows = rows
array = [T?](count: rows*columns, repeatedValue: nil)
}
subscript(column: Int, row: Int) -> T? {
get {
return array[row*columns + column]
}
set {
array[row*columns + column] = newValue // Error here
}
}}
Any thoughts on how to resolve this?
In Beta3 constant arrays are completely immutable while variable arrays are entirely mutable. Change let array: [T?] to var array: [T?] and your code should work.