Swift - declare 2d array contains - swift

I want to say that if some 2d array contains the "point" format [Int,Int], then regenerate the random numbers, not counting the iteration.
for _ in 0..<33{
let j = Int(arc4random_uniform(10))
let k = Int(arc4random_uniform(10))
while live.contains(//The point j,k){
live.append(Array(arrayLiteral: j,k))
cells[j][k] = true
}
}

From what I understood your question, you want to generate an array of 2D points excluding repetition, you can use CGPoint or define your own Point
struct Point: Equatable {
let x: Int
let y: Int
}
func == (lhs: Point, rhs: Point) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y
}
var live: [Point] = []
for _ in 0..<10{
var candidate = Point(x: Int(arc4random_uniform(10)), y: Int(arc4random_uniform(10)))
while live.contains(candidate) {
candidate = Point(x: Int(arc4random_uniform(10)), y: Int(arc4random_uniform(10)))
}
live.append(candidate)
}
or you can use tuple like so
var live: [(Int, Int)] = []
for _ in 0..<10{
var j = Int(arc4random_uniform(10))
var k = Int(arc4random_uniform(10))
while live.contains({$0 == (j, k)}) {
j = Int(arc4random_uniform(10))
k = Int(arc4random_uniform(10))
}
live.append((j,k))
}
Depending on your problem size, it might be more optimal to build an array of all possible values, and then shuffle and take first X elements every time you need new set of random points. You can optimize it further, but the code'd look similar to:
var possibleValues: [Point] = []
for x in 0..<5 {
for y in 0..<5 {
possibleValues.append(Point(x: x, y: y))
}
}
func randomPoints(numberOfPoints: Int) -> [Point] {
// shuffle original array without changing it
let shuffled = possibleValues.sorted { _ in arc4random_uniform(10) > 5 }
// take first X elements
return Array(shuffled[0..<numberOfPoints])
}
randomPoints(numberOfPoints: 10)
You can optimize this solution even further but that'd require to know more about your data set. Hope this helps

Related

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

where do i go from here? swift

func step(_ g: Int, _ m: Int, _ n: Int) -> (Int, Int)? {
var z = [m]
var x = m
var y = n
while x < y {
x += 1
z += [x]
}
for i in z {
var k = 2
while k < n {
if i % k != 0 && i != k {
}
k += 1
}
}
print(z)
return (0, 0)
}
print (step(2, 100, 130))
so it currently returns the set of numbers 100-130 in the form of an array. the overall function will do more than what i am asking about but for now i just want to create an array that takes the numbers 100-130, or more specifically the numbers x- y and returns an array of prime. the if i%k part need the help. yes i know it is redundant and elongated but im new at this. that being said try to only use the simple shortcuts.
that being said i would also be ok with examples of ways to make it more efficient but im going to need explanations on some of it because.. well im new. for context assume if only been doing this for 20-30 days (coding in general)
you can do this:
let a = 102
let b = 576 // two numbers you want to check within
/**** This function returns your array of primes ****/
func someFunc(x: Int, y: Int) -> [Int] {
var array = Array(x...y) // This is a quick way to map and create array from a range . /// Array(1...5) . ---> [1,2,3,4,5]
for element in array {
if !isPrime(n: element) { // check if numberis prime in a for loop
array.remove(at: array.index(of: element)!) // remove if it isnt
}
}
return array
}
someFunc(x: a, y: b) //this is how you call this func. someFunc(x: 4, y: 8) ---> [5, 7]
// THis is a supporting function to find a prime number .. pretty straight forward, explanation in source link below.
func isPrime(n: Int) -> Bool {
if n <= 1 {
return false
}
if n <= 3 {
return true
}
var i = 2
while i*i <= n {
if n % i == 0 {
return false
}
i = i + 1
}
return true
}
Source: Check if a number is prime?
Firstly, it's a good idea to separate out logic into functions where possible. E.g. Here's a generic function for calculating if a number is prime (adapted from this answer):
func isPrime<T>(_ n: T) -> Bool where T: BinaryInteger {
guard n > 1 else {
return false
}
guard n > 3 else {
return true
}
var i = T(2)
while (i * i) <= n {
if n % i == 0 {
return false
}
i += 1
}
return true
}
To get the numbers by step, Swift provides the stride function. So your function can simplify to:
func step(_ g: Int, _ m: Int, _ n: Int) -> (Int, Int)? {
let z = stride(from: m, to: n, by: g).filter { isPrime($0) }
print(z)
return (0, 0)
}
To explain, stride will return a Sequence of the numbers that you want to step through, which you can then filter to get only those that return true when passed to the function isPrime.
By the way, your example of print(step(2, 100, 130)) should print nothing, because you'll be checking all the even numbers from 100 to 130, which will obviously be non-prime.
I'd also recommend that you don't use single-letter variable names. g, m, n and z aren't descriptive. You want clarity over brevity so that others can understand your code.
This returns an array of primes between 2 numbers:
extension Int {
func isPrime() -> Bool {
if self <= 3 { return self == 2 || self == 3 }
for i in 2...self/2 {
if self % i == 0 {
return false
}
}
return true
}
}
func getPrimes(from start: Int, to end: Int) -> [Int] {
var primes = [Int]()
let range = start > end ? end...start : start...end
for number in range {
if number.isPrime() { primes.append(number) }
}
return primes
}
In the extension you basically loop through every number in between 2 and selected number/2 to check if its divisible or not and return false if it is, else it will return true.
The getPrimes() basically takes in 2 numbers, if the start number is higher than the end number they switch places (a failsafe). Then you just check if the number is prime or not with help of the extension and append the value to the array if it is prime.
func step(_ steps: Int, _ start: Int, _ end: Int) {
var primes = [Int]()
var number = start
repeat {
if number.isPrime() { primes.append(number) }
number+=steps
} while number <= end
}
Here is another function if you want to take steps in the difference higher than 1

Sum of Fibonacci term using Functional Swift

I'm trying to learn functional Swift and started doing some exercises from Project Euler.
Even Fibonacci numbers
Problem 2
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
Implemented a memoized Fibonacci function, as per WWDC advanced Swift videos:
func memoize<T:Hashable, U>( body: ((T)->U,T) -> U) -> (T)->U {
var memo = [T:U]()
var result: ((T)->U)!
result = { x in
if let q = memo[x] { return q }
let r = body(result,x)
memo[x] = r
return r
}
return result
}
let fibonacci = memoize { (fibonacci:Int->Double,n:Int) in n < 2 ? Double(n) : fibonacci(n-1) + fibonacci(n-2) }
and implemented a class that conforms to the Sequence protocol
class FibonacciSequence: SequenceType {
func generate() -> GeneratorOf<Double> {
var n = 0
return GeneratorOf<Double> { fibonacci(n++) }
}
subscript(n: Int) -> Double {
return fibonacci(n)
}
}
The first (non-functional) solution of the problem:
var fib = FibonacciSequence().generate()
var n:Double = 0
var sum:Double = 0
while n < Double(4_000_000) {
if n % 2 == 0 {
sum += n
}
n = fib.next()!
}
println(sum)
The second, more functional solution, using ExSwift for it's takeWhile function
let f = FibonacciSequence()
println((1...40).map { f[$0] }
.filter { $0 % 2 == 0 }
.takeWhile { $0 < 4_000_000 }
.reduce(0, combine: +))
I'd like to improve on this solution, because of the 1...40 range at the begging that's calculating too many terms for no reason. Ideally I'd like to be able to have some sort of infinite range, but at the same time only calculate the required terms that satisfy the condition in the takeWhile
Any suggestions ?
Here I generate the sequence that already stops once max value is reached.
Then you just need to reduce without filtering, just sum 0 when n is odd.
func fibonacciTo(max: Int) -> SequenceOf<Int> {
return SequenceOf { _ -> GeneratorOf<Int> in
var (a, b) = (1, 0)
return GeneratorOf {
(b, a) = (a, b + a)
if b > max { return nil }
return b
}
}
}
let sum = reduce(fibonacciTo(4_000_000), 0) {a, n in (n % 2 == 0) ? a + n : a }
As an alternative, if you wish to keep fibonacci a more general function you could extend SequenceOf with takeWhile and reduce1 obtaining something that resembles function composition:
extension SequenceOf {
func takeWhile(p: (T) -> Bool) -> SequenceOf<T> {
return SequenceOf { _ -> GeneratorOf<T> in
var generator = self.generate()
return GeneratorOf {
if let next = generator.next() {
return p(next) ? next : nil
}
return nil
}
}
}
// Reduce1 since name collision is not resolved
func reduce1<U>(initial: U, combine: (U, T) -> U) -> U {
return reduce(self, initial, combine)
}
}
func fibonacci() -> SequenceOf<Int> {
return SequenceOf { _ -> GeneratorOf<Int> in
var (a, b) = (1, 0)
return GeneratorOf {
(b, a) = (a, b + a)
return b
}
}
}
let sum2 = fibonacci()
.takeWhile({ $0 < 4_000_000 })
.reduce1(0) { a, n in (n % 2 == 0) ? a + n : a}
Hope this helps
There is a filter() function which takes a sequence as an argument:
func filter<S : SequenceType>(source: S, includeElement: (S.Generator.Element) -> Bool) -> [S.Generator.Element]
but since the return value is an array, this is not suited if you want
to work with an "infinite" sequence. But with
lazy(FibonacciSequence()).filter ( { $0 % 2 == 0 })
you get an "infinite" sequence of the even Fibonacci numbers. You cannot
call the .takeWhile() method of ExSwift on that sequence because
.takeWhile() is only defined for struct SequenceOf and not for
general sequences. But
TakeWhileSequence(
lazy(FibonacciSequence()).filter ( { $0 % 2 == 0 }),
{ $0 < 4_000_000 }
)
works and gives the sequence of all even Fibonacci numbers less than
4,000,000. Then
let sum = reduce(TakeWhileSequence(
lazy(FibonacciSequence()).filter ( { $0 % 2 == 0 }),
{ $0 < 4_000_000 }), 0, +)
gives the intended result and computes only the "necessary"
Fibonacci numbers.
Note that there is no actual need to memoize the Fibonacci numbers
here because they are accessed sequentially. Also (as #Matteo
already noticed), all Fibonacci numbers are integers. So you could
define the sequence more simply as
struct FibonacciSequence : SequenceType {
func generate() -> GeneratorOf<Int> {
var current = 1
var next = 1
return GeneratorOf<Int>() {
let result = current
current = next
next += result
return result
};
}
}
and the above computation does still work.
You can get quite close to what you want by using Swift's lazy sequences. If you take your generator of fibonacci numbers (here's the one I'm using:)
var (a, b) = (1, 0)
var fibs = GeneratorOf<Int> {
(b, a) = (a, b + a)
return b
}
You can wrap it in lazy():
var (a, b) = (1, 0)
var fibs = lazy(
GeneratorOf<Int> {
(b, a) = (a, b + a)
return b
}
)
Which exposes it to filter() as a lazy function. This filter() returns:
LazySequence<FilterSequenceView<GeneratorOf<Int>>>
Now, to get your takeWhile() function, you'd need to extend LazySequence:
extension LazySequence {
func takeWhile(condition: S.Generator.Element -> Bool)
-> LazySequence<GeneratorOf<S.Generator.Element>> {
var gen = self.generate()
return lazy( GeneratorOf{ gen.next().flatMap{ condition($0) ? $0 : nil }})
}
}
So that it returns nil (stops the generator) if either the underlying sequence ends, or the condition isn't satisfied.
With all of that, your fibonacci sequence under a given number looks a lot like what you wanted:
fibs
.filter {$0 % 2 == 0}
.takeWhile {$0 < 100}
//2, 8, 34
But, because reduce isn't a method on LazySequence, you have to convert to an array:
fibs
.filter {$0 % 2 == 0}
.takeWhile {$0 < 100}.array
.reduce(0, combine: +)
//44
You could do a quick and dirty extension to LazySequence to get reduce():
extension LazySequence {
func reduce<U>(initial: U, combine: (U, S.Generator.Element) -> U) -> U {
var accu = initial
for element in self { accu = combine(accu, element) }
return accu
}
}
And you can write the final thing like this:
fibs
.filter {$0 % 2 == 0}
.takeWhile {$0 < 100}
.reduce(0, combine: +)
//44
All of those sequences get to persist in their laziness - fibs is infinite, so they wouldn't really work otherwise. In fact, nothing is calculated until reduce: it's all thunks until then.
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()}
You can get the sum of the even-numbered terms under four million like this:
fibs.prefix{$0 < 4000000}.filter{$0 % 2 == 0}.reduce(0){$0 + $1}
Be warned that filter and map are strict by default, and will run forever on an infinite Sequence. In the example above, this doesn't matter since prefix returns only a finite number of values. You can call .lazy to get a lazy Sequence where filter and map will behave non-strictly. For example, here are the first 5 even Fibonacci numbers:
> print( Array(fibs.lazy.filter{$0 % 2 == 0}.prefix(5)) )
[2, 8, 34, 144, 610]

Correct way to find leftmost position in an Array of CGPoints in Swift

Drawing from Correct way to find max in an Array in Swift, I am attempting to find the leftmost position in Swift array using reduce. I would have thought that this would work:
var a = [CGPoint(x:1,y:1),CGPoint(x:2,y:2),CGPoint(x:0,y:0)]
var leftMost = a.reduce(CGPoint(x:CGFloat.max,y:CGFloat.max)) {min($0.x,$1.x)}
However, I get this error:
`Type 'CGPoint' does not conform to protocol 'Comparable'
Of course, I'm not comparing a CGPoint, I'm comparing the point .x, whic should be a CGFloat.
Ideas?
The array holds CGPoint, whereas in the reduce closure you're trying to return a CGFloat - you have to convert it to a CGPoint instead:
var leftMost = a.reduce(CGPoint(x:CGFloat.greatestFiniteMagnitude,y:CGFloat.greatestFiniteMagnitude)) {
CGPoint(x: min($0.x,$1.x), y: $0.y)
}.x
I know, the error message doesn't help much :)
Another way to achieve the same result is by transforming the points into x coordinates first, and then reduce:
var leftMost = a.map { $0.x }.reduce(CGFloat.greatestFiniteMagnitude) { min($0,$1) }
maybe easier to read, although probably more expensive in terms of performance. But as #MartinR suggests, it can also be simplified as:
var leftMost = a.reduce(CGFloat.greatestFiniteMagnitude) { min($0, $1.x) }
Swift 5 implementation:
Usage:
let leftMost = self.findPoint(points: points, position: .leftMost)
Function and enum:
enum Position {
case topMost
case bottomMost
case leftMost
case rightMost
}
func findPoint(points: [CGPoint], position: Position) -> CGPoint? {
var result: CGPoint?
switch (position) {
case .bottomMost:
result = points.max { a, b in a.y < b.y }
case .topMost:
result = points.max { a, b in a.y > b.y }
case .leftMost:
result = points.max { a, b in a.x > b.x }
case .rightMost:
result = points.max { a, b in a.x < b.x }
}
return result
}

Swift: adding optionals Ints

I declare the following:
var x:Int?
var y:Int?
and I'd like a third variable z that contains the sum of x and y. Presumably, as x & y are optionals, z must also be an optional:
var z:Int? = x + y
but this gives a complier error "value of optional type 'Int?' not unwrapped; did you mean to use '!' or '?'"
If I unwrap x & y:
var z:Int? = x! + y!
I get a run-time error as x & y are nil, so can't be unwrapped.
I can achieve the desired result as follows:
var z:Int?
if let x1 = x {
if let y1 = y {
z = x1+y1
}
}
but this seems a bit verbose for adding together 2 integers! Is there a better way of achieving this?
Here is my take, I think it's cleaner:
let none:Int? = nil
let some:Int? = 2
func + (left: Int?, right:Int?) -> Int? {
return left != nil ? right != nil ? left! + right! : left : right
}
println(none + none)
println(none + some)
println(some + none)
println(some + some)
println(2 + 2)
With results of:
nil
Optional(2)
Optional(2)
Optional(4)
4
The best I can think of is:
if x && y {
z = x! + y!;
}
Since they are all Optionals... there's really no way to avoid:
checking that they aren't nil
Unwrapping them before you add them.
Best solution IMO:
z = x.map { x in y.map { $0 + x } }
Did you know the map operator on Optional<T>? It is very nice.
Documentation says:
If self == nil, returns nil. Otherwise, returns f(self!).
It depends exactly what you're trying to achieve, but you could do it with an optional tuple:
var xy: (Int, Int)?
var z: Int
if let (x1, y1) = xy {
z = x1 + y1 // Not executed
}
xy = (3, 4)
if let (x1, y1) = xy {
z = x1 + y1 // 7
}
Update
As #Jack Wu points out, this changes the semantics. If you were willing to be a bit more verbose, you could however do it as follows:
func optIntAdd(x: Int?, y: Int?) -> Int? {
if let x1 = x {
if let y1 = y {
return x1 + y1
}
}
return nil
}
operator infix +! { }
#infix func +! (x: Int?, y: Int?) -> Int?{
return optIntAdd(x, y)
}
var x: Int?
var y: Int?
var z: Int?
z = x +! y // nil
x = 1
z = x +! y // nil
y = 2
z = x +! y // 3
Not sure "+!" is a useful choice of name for the operator, but it would't let me choose "+?".
Someday, we'll have variadic generics. Until then, you need a pair of overloads for all arities.
var z = Optional(x, y).map(+)
public extension Optional {
/// Exchange two optionals for a single optional tuple.
/// - Returns: `nil` if either tuple element is `nil`.
init<Wrapped0, Wrapped1>(_ optional0: Wrapped0?, _ optional1: Wrapped1?)
where Wrapped == (Wrapped0, Wrapped1) {
self = .init((optional0, optional1))
}
/// Exchange two optionals for a single optional tuple.
/// - Returns: `nil` if either tuple element is `nil`.
init<Wrapped0, Wrapped1>(_ optionals: (Wrapped0?, Wrapped1?))
where Wrapped == (Wrapped0, Wrapped1) {
switch optionals {
case let (wrapped0?, wrapped1?):
self = (wrapped0, wrapped1)
default:
self = nil
}
}
}
z = (x ?? 0) + (y ?? 0)
* Worked on Xcode 9 *
Swift 5.5 Sum any optional values
infix operator +?: AdditionPrecedence
public func +? <T: AdditiveArithmetic>(lhs: T?, rhs: T?) -> T {
if let lhs = lhs, let rhs = rhs {
return lhs + rhs
} else if let lhs = lhs {
return lhs
} else if let rhs = rhs {
return rhs
} else {
return .zero
}
}