How do I transform/operate on a set/sequence? - vdm++

I have a set S = { 1, 2, 3, 4, 5 }.
What is the syntax for changing the contents of the set (or rather, creating a new set) by applying a mathematical operation to it e.g. multiplication, power?

This sounds like a case for a set comprehension. So you generate f(e) for those elements of s which match a predicate p(e). The general syntax is:
{ f(s) | e in set S & p(e) }
So for example:
{ e*e | e in set {1,2,3,4,5,6} & e mod 2 = 0 } = {4, 16, 36}
There are more complex cases where you bind more than one element from the set, but this is enough to meet your example :)

Related

Array Performing XOR On Itself With Offset

Trying to implement an autocorrelation algorithm, meaning, for example:
let exampleData: [Float] = [1, 2, 3, 4, 5]
Trying to find the fastest way to evaluate 1 ^ 2 + 2 ^ 3 + 3 ^ 4 + 4 ^ 5.
Essentially, iterate through the array, and for every element, calculate the result of XOR between it and another element a set distance away.
Trouble is, this also has to be done for many different values of the offset.
Right now I just have a nested for loop, and I don't know how to make it faster...
var data: [Bool]
var result: [Int]
...
for offset in start..<end {
for index in 0..<(end - offset) {
if (data[index] ^ data[index + frequency]) {
result[offset] += 1
}
}
}
Sounds like you might want windows(ofCount:) from swift-algorithms:
https://github.com/apple/swift-algorithms/blob/main/Guides/Windows.md
That will give you a sliding window through any collection, and if your offset is relatively small (or you actually want the whole window, e.g. to do a moving average), that will be great.
The swift-algorithms stuff is nice since it's more optimized than whatever you'll do ad hoc, plus offers lazy eval.
You might also consider aligning and zipping up your sequence and then mapping over that, e.g.:
zip(data, data.dropFirst(offset))
.map { $0 ^ $1 }
...and so on

Logic behind Two Number Sum Algorithm

Could someone explain to me the logic behind this hashMap algorithm? I'm getting confused about how the algorithm receives the total sum. I'm starting to learn about algorithms, so it's a little confusing for me. I made comments in my code to pinpoint each line code, but I'm not sure I'm grasping logic correctly. I'm just looking for an easier way to understand how the algorithm works to avoid confusing myself.
//**calculate Two Number Sum
func twoNumberSum(_ array: [Int], _ targetSum: Int) -> [Int] {
//1) initilize our Array to hold Integer Value: Boolean value to store value into hashTable
var numbersHashMap = [Int:Bool]()
//2) create placeHolder called number that iterates through our Array.
for number in array {
//3) variable = y - x
let match = targetSum - number
//4) ??
if let exists = numbersHashMap[match], exists {
//5) match = y / number = x
return [match, number] //
} else {
//6) Store number in HashTable and repeats
numbersHashMap[number] = true
}
}
return []
}
twoNumberSum([3,5,-4, 8, 11, 1, -1, -6], 10)
// x = Number
// y = Unknown *Solve for Y*
Sure, I can walk you through it. So we have a list of numbers, are we are trying to find two numbers that add together to make the specified target. To do this, for each number x, we check if (target - x) is in the list. If it is not, then we add x to the list. If it is, then we return x and (target - x).
Step 4 in your code is the part where we check if (target - x) is in the list. To see why this makes sense, let's walk through an example.
Say we have [2, 3, -1] and our target is 1. In this case, we first consider x = 2 and check our hashmap for (target - x) = (1 - 2) = -1. Since -1 is not in the hashmap, we add 2 to the hashmap. We then consider x = 3 and check for (1 - 3) = -2. Again, -2 is not in the hashmap, so we add it. Now we check x - -1. In this case, when we check (target - x) = (1 - (-1)) = 2, 2 is in the hashmap. Intuitively, we have already "seen" 2, and know that 2 and -1 can be added to get our value.
This is what provides the speed optimization over checking every two numbers in the list.

Set/sequence summation operator?

I have a set, S = { 1, 2, 3, 4, 5 }.
If I wanted to sum this in standard logic it's just ∑S (no MathJax on SO so I can't format this nicely).
What's the VDM equivalent? I don't see anything in the numerics/sets section of the language reference.
There isn't a standard library function to do this (though perhaps there should be). You would sum a set with a simple recursive function:
sum: set of nat +> nat
sum(s) ==
if s = {}
then 0
else let e in set s in
e + sum(s \ {e})
measure card s;
The "let" selects an arbitrary element from the set, and then add that to the sum of the remainder. The measure says that the recursion always deals with smaller sets.
This should work:
sum(S)
But you could find this very easily.

Shortening If/Else from if(x == y || x == z) to if(x == y || z) in swift

I'm making an app where I have to put a lot of if/else statements. I know you can do as in the title in some other coding language, but I'm not sure if you can do it in Swift.
How do you shorten this:
if x == y || x == z {
//do something
}
To something like this:
if x == y || z {
//do something
}
Perhaps you could consider using an array and checking to see if x is in the array, like in the following example:
let (x, y, z) = (3, 8, 3)
if [y, z].contains(x) {
//True
}
If you're comparing objects (like UIImage), use containsObject instead of contains:
if [x, y, z].containsObject(y) {
//True
}
I conject that there is no sensible language (swift included), that distributes comparison == across logical or ||.
The way you've written it - x == y || x == z - is the most compact form.
Jack Greenhill's answer does indeed go into the right direction. However with more and more values, his method will get very inefficient, since it has to check every element of the array against equality, therefore complexity O(n).
A very underrated data structure, which can do this kind of operation in O(1) should be used instead: The Set. It uses hash values to check quickly whether a value is present or not. You can use it like this:
let x = 3
let values : Set = [1, 3, 6, 1, 7] // {6, 7, 3, 1}
if values.contains(x) {
// ...
}
This takes the same amount of time, whether values contains just one or 1000 elements. An array would be 1000 times slower.
Oftentimes the decision to use an array is made before even considering a set. If your elements don't have any order and can only occur once (which is actually more often the case than you'd think), you probably want a set. A set gives you useful methods, such as union, isSubset, interception and more, for free by just putting your elements in it. The only additional requirement for the element type is to conform to Hashable.
Perhaps this:
switch x {
case y, z : // do then
default : // do else
}

Why does passing an unnamed function as transform to array add one to iteration count in playground in furthest abstractions

I'm in the process of getting comfortable passing unnamed functions as arguments and I am using this to practice with, based off of the examples in the Swift Programming Guide.
So we have an array of Ints:
var numbers: Int[] = [1, 2, 3, 4, 5, 6, 7]
And I apply a transform like so: (7)
func transformNumber(number: Int) -> Int {
let result = number * 3
return result
}
numbers = numbers.map(transformNumber)
Which is equal to: (7)
numbers = numbers.map({(number: Int) -> Int in
let result = number * 3
return result;
})
Which is equal to: (8)
numbers = numbers.map({number in number * 3})
Which is equal to: (8)
numbers = numbers.map({$0 * 3})
Which is equal to: (8)
numbers = numbers.map() {$0 * 3}
As you can see in the following graphic, the iteration count in the playground sidebar shows that in the furthest abstraction of a function declaration, it has an 8 count.
Question
Why is it showing as 8 iterations for the last two examples?
It's not showing 8 iterations, really. It's showing that 8 things executed on that line. There were 7 executions as part of the map function, and an 8th to do the assignment back into the numbers variable.
It looks like this could probably provide more helpful diagnostics. I would highly encourage you to provide feedback via https://bugreport.apple.com.
Slightly rewriting your experiment to use only closures, the call counts still differ by one:
Case 1: Explicitly specifying argument types (visit count is 7)
var f1 = {(number: Int) -> Int in
let result = number * 3
return result
}
numbers.map(f1)
Case 2: Implicit argument types (visit count is 8)
var f2 = {$0 * 3}
numbers.map(f2)
If the (x times) count reported by the REPL does indeed represent a count of visits to that code location, and noting that the count is greater by one in cases where the closure type arguments are not explicitly specified (e.g. f2), my guess is that at least in the playground REPL, the extra visit is to establish actual parameter types and fill that gap in the underlying AST.