Swift - Create variables with different names in a for loop - ios

I am learning Apple Swift with the hope of releasing apps for the iPhone.
There are three different 'modes' to my game: 5 swipes, 10 swipes, or 25 swipes. Let's use 5 swipes as an example. I want a variable to be assigned to each swipe, which will be a random integer within the range 1...100 (inclusive). Obviously it doesn't seem neat when I am creating variables in a long list like this:
var s1 = arc4random_uniform...
var s2 = arc4random_uniform...
Also that could just be a pain when I get to 25 swipes.
So I thought, maybe I could use a 'for' loop. So:
for index(in 1...5) {
//create variable with different name with a random integer
}
So here's where my problem lies... I am unsure how I would create variables with different names. So: s1, s2, s3, s4, and s5.
It would probably be in the form of an algorithm like:
var s(prevnumber+1) = arc4random_uniform....

I will do it this way:
var numElement = 5 // change to 10 or 25 depends on what you need
var array = Array<UInt32>(count: numElement, repeatedValue: 0)
for i in 0 ..< numElement {
array[i] = arc4random_uniform(100)
}
Then to access the first variable, you can do
array[0]
And it will give you the random number

Related

Adding Bool values to every element of matrix array (two dimensional array) in Swift

I have a 2D array that represents every coordinate of a maze:
var maze:[[Int]]
let column = [Int](repeating: 0, count: y)
self.maze = ([[Int]](repeating: column, count: x))
I need to assign 4 Bool values to every single coordinate:
canMoveUp = false
canMoveDown = false
canMoveLeft = false
canMoveRight = false
The problem is I already have a lot of code written using maze:[[Int]]. Is there a way of creating an extra object reaching maze[[Int]] and adding bool values to its every element not affecting the original maze var? If not: just an example of declaring 2D array with Bool values for every element would be really helpful.
I am at the very beginning of my developer career, please be indulgent. Any help is much appreciated!
Is there a way of creating an extra object reaching maze[[Int]] and adding bool values to its every element not affecting the original maze var?
No. Int is a fundamental type, not something you can extend.
You could create a second maze array with the new data in the corresponding locations, but that's a terrible idea; trying to keep two data structures in sync at all times is always an exercise in pain.
What you should do is to refactor your code so that you're using an appropriate type for your maze data instead of the single Int that you're using now. If you do it right, you'll only need to do it once, and from then on you can add new data to each cell in the maze with much less effort. Create a data structure that contains everything that you currently need, like:
struct MazeElement {
var up = false
var down = false
var left = false
var right = false
var count = 0
}
let columns = 4
let rows = 3
var maze = [[MazeElement]](repeating: [MazeElement](repeating:MazeElement(), count: rows), count: columns)
Next you'll have find all the places in your code where you expect maze to be a 2D array of Int, and change each one so that it expects a MazeElement instead. In practice, that mostly means that lines like:
let foo = maze[i][j]
need to be changed to:
let foo = maze[i][j].count
But the benefit is that now it's easy to also get the directional information for each cell:
let canMoveUp = maze[i][j].up
let canMoveLeft = maze[i][j].left
Better yet, when you decide to add some new data to each element, you won't have to do all that work all over again... just change the definition of MazeElement to include the new data:
struct MazeElement {
var up = false
var down = false
var left = false
var right = false
var count = 0
var color = UIColor.white
}

16 bit logic/computer simulation in Swift

I’m trying to make a basic simulation of a 16 bit computer with Swift. The computer will feature
An ALU
2 registers
That’s all. I have enough knowledge to create these parts visually and understand how they work, but it has become increasingly difficult to make larger components with more inputs while using my current approach.
My current approach has been to wrap each component in a struct. This worked early on, but is becoming increasingly difficult to manage multiple inputs while staying true to the principles of computer science.
The primary issue is that the components aren’t updating with the clock signal. I have the output of the component updating when get is called on the output variable, c. This, however, neglects the idea of a clock signal and will likely cause further problems later on.
It’s also difficult to make getters and setters for each variable without getting errors about mutability. Although I have worked through these errors, they are annoying and slow down the development process.
The last big issue is updating the output. The output doesn’t update when the inputs change; it updates when told to do so. This isn’t accurate to the qualities of real computers and is a fundamental error.
This is an example. It is the ALU I mentioned earlier. It takes two 16 bit inputs and outputs 16 bits. It has two unary ALUs, which can make a 16 bit number zero, negate it, or both. Lastly, it either adds or does a bit wise and comparison based on the f flag and inverts the output if the no flag is selected.
struct ALU {
//Operations are done in the order listed. For example, if zx and nx are 1, it first makes input 1 zero and then inverts it.
var x : [Int] //Input 1
var y : [Int] //Input 2
var zx : Int //Make input 1 zero
var zy : Int //Make input 2 zero
var nx : Int //Invert input 1
var ny : Int //Invert input 2
var f : Int //If 0, do a bitwise AND operation. If 1, add the inputs
var no : Int //Invert the output
public var c : [Int] { //Output
get {
//Numbers first go through unary ALUs. These can negate the input (and output the value), return 0, or return the inverse of 0. They then undergo the operation specified by f, either addition or a bitwise and operation, and are negated if n is 1.
var ux = UnaryALU(z: zx, n: nx, x: x).c //Unary ALU. See comments for more
var uy = UnaryALU(z: zy, n: ny, x: y).c
var fd = select16(s: f, d1: Add16(a: ux, b: uy).c, d0: and16(a: ux, b: uy).c).c //Adds a 16 bit number or does a bitwise and operation. For more on select16, see the line below.
var out = select16(s: no, d1: not16(a: fd).c, d0: fd).c //Selects a number. If s is 1, it returns d1. If s is 0, it returns d0. d0 is the value returned by fd, while d1 is the inverse.
return out
}
}
public init(x:[Int],y:[Int],zx:Int,zy:Int,nx:Int,ny:Int,f:Int,no:Int) {
self.x = x
self.y = y
self.zx = zx
self.zy = zy
self.nx = nx
self.ny = ny
self.f = f
self.no = no
}
}
I use c for the output variable, store values with multiple bits in Int arrays, and store single bits in Int values.
I’m doing this on Swift Playgrounds 3.0 with Swift 5.0 on a 6th generation iPad. I’m storing each component or set of components in a separate file in a module, which is why some variables and all structs are marked public. I would greatly appreciate any help. Thanks in advance.
So, I’ve completely redone my approach and have found a way to bypass the issues I was facing. What I’ve done is make what I call “tracker variables” for each input. When get is called for each variable, it returns that value of the tracker assigned to it. When set is called it calls an update() function that updates the output of the circuit. It also updates the value of the tracker. This essentially creates a ‘copy’ of each variable. I did this to prevent any infinite loops.
Trackers are unfortunately necessary here. I’ll demonstrate why
var variable : Type {
get {
return variable //Calls the getter again, resulting in an infinite loop
}
set {
//Do something
}
}
In order to make a setter, Swift requires a getter to be made as well. In this example, calling variable simply calls get again, resulting in a never-ending cascade of calls to get. Tracker variables are a workaround that use minimal extra code.
Using an update method makes sure the output responds to a change in any input. This also works with a clock signal, due to the architecture of the components themselves. Although it appears to act as the clock, it does not.
For example, in data flip-flops, the clock signal is passed into gates. All a clock signal does is deactivate a component when the signal is off. So, I can implement that within update() while remaining faithful to reality.
Here’s an example of a half adder. Note that the tracker variables I mentioned are marked by an underscore in front of their name. It has two inputs, x and y, which are 1 bit each. It also has two outputs, high and low, also known as carry and sum. The outputs are also one bit.
struct halfAdder {
private var _x : Bool //Tracker for x
public var x: Bool { //Input 1
get {
return _x //Return the tracker’s value
}
set {
_x = x //Set the tracker to x
update() //Update the output
}
}
private var _y : Bool //Tracker for y
public var y: Bool { //Input 2
get {
return _y
}
set {
_y = y
update()
}
}
public var high : Bool //High output, or ‘carry’
public var low : Bool //Low output, or ‘sum’
internal mutating func update(){ //Updates the output
high = x && y //AND gate, sets the high output
low = (x || y) && !(x && y) //XOR gate, sets the low output
}
public init(x:Bool, y:Bool){ //Initializer
self.high = false //This will change when the variables are set, ensuring a correct output.
self.low = false //See above
self._x = x //Setting trackers and variables
self._y = y
self.x = x
self.y = y
}
}
This is a very clean way, save for the trackers, do accomplish this task. It can trivially be expanded to fit any number of bits by using arrays of Bool instead of a single value. It respects the clock signal, updates the output when the inputs change, and is very similar to real computers.

Understanding random numbers in iOS Swift 2

How do I make a random number continue to change over time in the program (I.E. become a new one within the range everytime I want to use it)?
I'm stumped. I've read more than 20 different posts and articles on how to generate random numbers in this language (which I'm pretty new to) and I just can't seem to get it to work.
I'm basically trying to get a random double from 1.0-3.0. I can do this pretty easily, but once it has selected that number it doesn't change. This is my code that I use:
var randomNumber:Double = (Double(arc4random() % 3) + 1);
Then I use this as a value for the line:
SKAction.waitForDuration(randomNumber)
Every time I run this I want to change the number again, but once the program starts it continues that same number (It's different every time i reset the program)
I understand how to generate the number, but I can't seem to find anything on updating it!
I've tried adding
randomNumber = (Double(arc4random() % 3) + 1);
into the code in a spot where it will be ran many times, but it still gives me the same thing.
I'm very familiar with c++ so if you're trying to explain something you can reference its style and I will most likely understand.
What you need it is a read only computed property that will return a new random every time you try to access it:
var randomNumber: Double {
return Double(arc4random_uniform(3).successor())
}
print(randomNumber) // 2.0
print(randomNumber) // 2.0
print(randomNumber) // 1.0
print(randomNumber) // 3.0
print(randomNumber) // 3.0
Use:
SKAction.waitForDuration(sec: NSTimeInterval, withRange: NSTimeInterval)
where sec is the middle of the range in time you want to use, since range goes in a +- direction.
So in your case you want:
SKAction.waitForDuration(2, withRange: 2), this will get you a range of 1 to 3 (-1 to 1 range)
If for some reason you need a method that will constantly create a new random wait, you can always do:
extension SKAction
{
func waitForRandomDuration() -> SKAction
{
var randomNumber:Double = (Double(arc4random() % 3) + 1);
return SKAction.waitForDuration(randomNumber);
}
}
And then make sure that you add this as a new action onto your sprite every time you need to get it done, if you store it into a variable, your randomness won't change.
Try this code:
func randomNumberBetween1_0And3_0() -> Double {
return 1 + Double(arc4random_uniform(2000)) / 1000.0
}
for index in 1...10 {
print(randomNumberBetween1_0And3_0())
}
Sample output is:
2.087
1.367
1.867
1.32
2.402
1.803
1.325
1.703
2.069
2.335

Percent Similarity of an Array Swift

Say I have two arrays:
var arrayOne = ["Hi", "Hello", "Hey", "Howdy"]
var arrayOne = ["Hi", "Hello", "Hey", "Not Howdy"]
What could I do to compare how similar the array elements are? As in a function that would return 75% Because the first three elements are the same but the last element are not. The arrays I'm using in my project are strings but they will almost entirely match except for a few elements. I need to see What percent the differences are. Any ideas?
let arrayOne = ["Hi", "Hello", "Hey", "Howdy"]
let arrayTwo = ["Hi", "Hello", "Hey", "Not Howdy"]
var matches = 0
for (index, item) in enumerate(arrayOne) {
if item == arrayTwo[index] {
matches++
}
}
Double(matches) / Double(arrayOne.count) // 0.75
Both of these algorithms use the idea that if you have two different length arrays, the highest similarity you can have is short length / long length, meaning that the difference in the array lengths are counted as not matching.
You could add all of the terms to a set and then make your percentage the size of the set / length of longest array.
You could sort both arrays and then do a loop with an index variable for each array and compare the values at the two indices, advancing the index for the array that has the "lower" value in the comparison, or increment a counter if they are equivalent. Your percentage would be the counter / length of longest array.
One thing to think about though is how you want to measure similarity in weird cases. Suppose you have two arrays: [1, 2, 3, 4, 5] and [1, 1, 1, 1, 1]. I don't know whether you would want to say they are completely similar, since all of the elements in the second array are in the first array, or if they only have a similarity of 20% because once the 1 in the first array is "used", it can't be used again.
Just some thoughts.
maybe something like this? (written off top of my head so havent checked if it actually compiles)
var arrayOne = ["Hi", "Hello", "Hey", "Howdy"]
var arrayTwo = ["Hi", "Hello", "Hey", "Not Howdy"]
var matches = 0
for i in 0...arrayOne.count { //assuming the arrays are always the same length
if arrayOne[i] == arrayTwo[i]{
matches++
}
}
var percent = matches / arrayOne.count
A good way to measure the similarity of 2 arrays is to iterate all elements of an array, and keep a cursor on the 2nd array, such that at any time the current element of the iterated array is not greater than the element at the cursor position.
As you may argue, this algorithm require elements to be comparable, and as such it works if the arrays type implements the Comparable interface.
I've worked on a generic function that perform that calculation, here it is:
func compare<T: Comparable>(var lhs: [T], var rhs: [T]) -> (matches: Int, total: Int) {
lhs.sort { $0 < $1 } // Inline sort
rhs.sort { $0 < $1 } // Inline sort
var matches = 0
var rightSequence = SequenceOf(rhs).generate()
var right = rightSequence.next()
for left in lhs {
while right != nil && left > right {
right = rightSequence.next()
}
if left == right {
++matches
right = rightSequence.next()
}
}
return (matches: matches, total: max(lhs.count, rhs.count))
}
Let me say that the implementation can probably be optimized, but my goal here is to show the algorithm, not to provide its best implementation.
The first thing to do is to obtain a sorted version of each of the 2 arrays - for simplicity, I have declared both parameters as var, which allows me to edit them, leaving all changes in the local scope. That's way I am using in-place sort.
A sequence on the 2nd array is created, called rightSequence, and the first element is extracted, copied into the right variable.
Then the first array is iterated over - for each element, the sequence is advanced to the next element until the left element is not greater than the right one.
Once this is done, left and right are compared for equality, in which case the counter of matches is incremented.
The algorithm works for arrays having repetitions, different sizes, etc.

iOS slow image pixel iterating

I am trying to implement RGB histogram computation for images in Swift (I am new to iOS).
However the computation time for 1500x1000 image is about 66 sec, which I consider to be too slow.
Are there any ways to speed up image traversal?
P.S. current code is the following:
func calcHistogram(image: UIImage) {
let bins: Int = 20;
let width = Int(image.size.width);
let height = Int(image.size.height);
let binStep: Double = Double(bins-1)/255.0
var hist = Array(count:bins, repeatedValue:Array(count:bins, repeatedValue:Array(count:bins, repeatedValue:Int())))
for i in 0..<bins {
for j in 0..<bins {
for k in 0..<bins {
hist[i][j][k] = 0;
}
}
}
var pixelData = CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage))
var data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)
for x in 0..<width {
for y in 0..<height {
var pixelInfo: Int = ((width * y) + x) * 4
var r = Double(data[pixelInfo])
var g = Double(data[pixelInfo+1])
var b = Double(data[pixelInfo+2])
let r_bin: Int = Int(floor(r*binStep));
let g_bin: Int = Int(floor(g*binStep));
let b_bin: Int = Int(floor(b*binStep));
hist[r_bin][g_bin][b_bin] += 1;
}
}
}
As noted in my comment on the question, there are some things you might rethink before you even try to optimize this code.
But even if you do move to a better overall solution like GPU-based histogramming, a library, or both... There are some Swift pitfalls you're falling into here that are good to talk about so you don't run into them elsewhere.
First, this code:
var hist = Array(count:bins, repeatedValue:Array(count:bins, repeatedValue:Array(count:bins, repeatedValue:Int())))
for i in 0..<bins {
for j in 0..<bins {
for k in 0..<bins {
hist[i][j][k] = 0;
}
}
}
... is initializing every member of your 3D array twice, with the same result. Int() produces a value of zero, so you could leave out the triple for loop. (And possibly change Int() to 0 in your innermost repeatedValue: parameter to make it more readable.)
Second, arrays in Swift are copy-on-write, but this optimization can break down in multidimensional arrays: changing an element of a nested array can cause the entire nested array to be rewritten instead of just the one element. Multiply that by the depth of nested arrays and number of element writes you have going on in a double for loop and... it's not pretty.
Unless there's a reason your bins need to be organized this way, I'd recommend finding a different data structure for them. Three separate arrays? One Int array where index i is red, i + 1 is green, and i + 2 is blue? One array of a custom struct you define that has separate r, g, and b members? See what conceptually fits with your tastes or the rest of your app, and profile to make sure it works well.
Finally, some Swift style points:
pixelInfo, r, g, and b in your second loop don't change. Use let, not var, and the optimizer will thank you.
Declaring and initializing something like let foo: Int = Int(whatever) is redundant. Some people like having all their variables/constants explicitly typed, but it does make your code a tad less readable and harder to refactor.
Int(floor(x)) is redundant — conversion to integer always takes the floor.
If you have some issues about performance in your code, first of all, use Time Profiler from Instruments. You can start it via Xcode menu Build->Profile, then, Instruments app opened, where you can choose Time Profiler.
Start recording and do all interactions in the your app.
Stop recording and analyse where is the "tightest" place of your code.
Also check options "Invert call tree", "Hide missing symbols" and "Hide system libraries" for better viewing profile results.
You can also double click at any listed function to view it in code and seeing percents of usage

Resources