Why does Swift playground shows wrong number of executions? - swift

I am using a completion handler to sum up numbers. What I don't understand is if I break my code in 2 lines, the number of executions would change from 6 to 7!! WHY?
func summer (from : Int, to: Int, handler: (Int) -> (Int)) -> Int {
var sum = 0
for i in from...to {
sum += handler(i)
}
return sum
}
summer(1, to:6){ //Shows '21'
return $0} // shows '(6 times)'
// Same code, but in 1 line
summer(1, to:6){return $0} // shows '(7 times)'
IMAGE

It's showing how many times a function / expression is being called on that line:
since the calling expression (summer()) is on the same line, it counts as an extra operation. Hence, 6 prints + 6 returns + 1 summer() = 13 times something happened on that line.
I'm sure I'm not using the correct terminology, but this is what's going on.

It's merely a consequence of the presentation:
21 //the result from the first time
(6 times) //the other 6 times
(7times) //all 7 times, including the 21 one.

Related

Greatest Common Exponent in Swift

I'm new to Swift and I was trying to make something which coverts any base 10 number to a different base. I started by making a function which finds the the greatest exponent value for a base and a number. For example, if the number was 26 and the base was 5, the greatest exponent would be 2. I created the program but it always gives me an error. I feel like it might have something to do with the Double(num/exponentedBase), but I'm not sure. Finally, is there a better way to do this. Please help.
The xor operator in the first line in combination with the division in the second line of your functions is causing the exception.
The xor operator returns a new number whose bits are set to 1 where the input bits are different and are set to 0 where the input bits are the same (see https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AdvancedOperators.html, chapter Bitwise XOR operator).
Therefor your variable "exponentedbase" can be 0 and it is possible that you are trying to divide through 0, which causes the exception.
When you print the values of your greatestCommonExponent function with num 12 and base 2, you get the following result:
first call:
num: 12
base: 2
exponent: 1
exponentedbase: 3
second call:
num: 12
base: 2
exponent: 2
exponentedbase: 0
You should add a guard statement to make your code save. (https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/ControlFlow.html#//apple_ref/doc/uid/TP40014097-CH9-ID120, chapter "early exit")
Edit:
The ^ operator in Swift is the XOR function. The statement 2^2 will compare the numbers bitwise.
10 XOR 10 = 00
For further reference follow https://en.wikipedia.org/wiki/Exclusive_or or https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AdvancedOperators.html
If you want to have a pow function, you should do something like this:
How to get the Power of some Integer in Swift language?
This should work for you:
func greatestCommonExponent(num: Int, base: Int, exponent: Int = 1) -> Int {
let exponentedbase = base^^exponent
let value = Double(num/exponentedbase)
if value > 1 {
return greatestCommonExponent(num: num, base: base, exponent: exponent+1)
}
if value == 1 {
return exponent
} else {
return exponent-1
}
}
precedencegroup PowerPrecedence { higherThan: MultiplicationPrecedence }
infix operator ^^ : PowerPrecedence
func ^^ (radix: Int, power: Int) -> Int {
return Int(pow(Double(radix), Double(power)))
}
greatestCommonExponent(num: 12, base: 2)
The result of 12 base 2 is 3

Struggling to understand the code - which tries to return the decimal digit 'n' places in from the right of the number

I'm new to Swift and is trying to learn the concept of extension. I saw this code in "the swift programming language", which tries to return the decimal digit 'n' places in from the right of the number. The code work fine, but I am struggling to understand how the code actually works.
Could someone explain it to me?
extension Int {
subscript(var digitIndex: Int) -> Int {
var decimalBase = 1
while digitIndex > 0 {
decimalBase *= 10
--digitIndex
}
return (self / decimalBase) % 10
}
}
746381295[0]
// returns 5
746381295[1]
// returns 9
746381295[2]
// returns 2
746381295[8]
// returns 7
746381295[9]
Extensions work by adding capability to existing types, with the caveat that they cannot introduce their own storage. In the case in point:
/*1*/ extension Int {
/*2*/ subscript(var digitIndex: Int) -> Int {
/*3*/ var decimalBase = 1
/*4*/ while digitIndex > 0 {
/*5*/ decimalBase *= 10
/*6*/ --digitIndex
/*7*/ }
/*8*/ return (self / decimalBase) % 10
}
}
Line 1 defines the extension as applying to all Int types.
Line 2 is setting up a new subscript operator for an Int, which will allow you to have 12345[4] and produce 'something'. Lines 3-8 define that something.
The while in lines 4-8 is multiplying decimalBase by 10 for 'digitIndex' times. A bit of a weird way of doing it, but never mind. The upshot is if digitIndex is 1, decimalBase is 10; if it's 2, decimal base is 100; 3 it's 1000; etc.
The guts is in line 8. First it retrieves self. Since the extension applies to an Int, self will be that integer value. It then divides it by decimalBase, and because they're both integers, any fractional part will be lost. Therefore in the case of 746381295[2] decimalBase will be 100 so you get 7463812. Then it uses '%' to get the remainder of the division by 10. So 7463812 divided by 10 is 746381 with a remainder of 2. So the returned value is 2.
Hope that explains it.
Pre-empting your question, I might use for in this case, instead of the while:
for _ in 0..<digitIndex {
decimalBase *= 10
}
I haven't thought too much about how often the above loops, it might run once to often or once too few, but you get the idea.
Even better would be to use the 'raising to the power' operator (not really sure what it's called).
decimalBase = 10 ^^ digitIndex
Then the whole definition could boil down to:
return (self / (10 ^^ digitIndex)) % 10
I will leave it to you to decide whether that's better or not.
Either way, I wouldn't really create this extension, and I assume it was just done for the purpose of demonstration.
Simply put, decimalBase is calculated to be 1 with an index of 0, 10 with an index of 1, 100 with an index of 2, 1,000 with an index of 3, and so on. In other words, decimalBase ends up equal to 10 ^ digitIndex.
So look at the case where digitIndex is 3, for instance. decimalBase will end up being 1,000, so:
746381259 / 1000 == 746381
and then:
746381 % 10 == 1
so that's how you get from 746381259[3] to 1.

Swift Dictionary.reduce() - different number of iterations reported using full vs. short syntax

I'm trying to get the hang of Swift, and am looking to understand why the following two method calls on a Dictionary, though they produce the same output, are reported as undergoing a different number of iterations by the Swift Playground.
var chocolates = ["Ram's Bladder Cup": 1, "Spring Surprise": 2, "Crunchy Frog": 3]
let chocolatesString = chocolates.reduce("", combine: {$0 + "\($1.0), "})
// The Playground says (4 times)
let newerChocolatesString = chocolates.reduce("") { (var sum: String, keyValue: (String, Int)) -> String in
return sum + "\(keyValue.0), "
// The Playground says (3 times)
print(chocolatesString)
print(newerChocolatesString)
// The output from both is however identical and as expected...
I'd be very grateful to understand this - I can see obviously that there is no difference in the result, but I would like to understand why the Playground reports a difference.
Playgrounds use the "n times" notation whenever a line of code is "visited" more than once during execution. This happens in lieu of showing a result because a line that has executed more than once — or a line that has executed more than one statement — can have more than one result.
When the closure body is on its own line, the playground reports that said line executed 3 times. When the closure body is in the same line as the reduce call to which it's passed, it says "4 times" because that line of code was "visited" 4 times during execution — once for the reduce call itself, and three more times for the closure body.
Note this happens regardless of which closure syntax you use — it's entirely a matter of where you put line breaks.
chocolates.reduce("", combine: {
$0 + "\($1.0), " // (3 times)
})
chocolates.reduce("") { (var sum: String, keyValue: (String, Int)) -> String in
return sum + "\(keyValue.0), " // (3 times)
}
chocolates.reduce("", combine: {$0 + "\($1.0), "})
// (4 times)
chocolates.reduce("") { (var sum: String, keyValue: (String, Int)) -> String in return sum + "\(keyValue.0), "}
// (4 times)
I don't have Xcode in front of me, but IIRC you'll see this even when you put multiple statements on one line with ;. It has nothing to do with closure syntax and everything to do with line breaks vs statements:
let a = 1 // 1
let b = a + 1 // 2
let a = 1; let b = a + 1 // (2 times)
var chocolates = ["Ram's Bladder Cup": 1, "Spring Surprise": 2, "Crunchy Frog": 3]
let chocolatesString = chocolates.reduce("", combine: {
$0 + "\($1.0), " // (3 times)
})
let newerChocolatesString = chocolates.reduce("") { (var sum: String, keyValue: (String, Int)) -> String in
return sum + "\(keyValue.0), "
// The Playground says (3 times)
}
print(chocolatesString)
print(newerChocolatesString)
// The output from both is however identical and as expected...
.. the number doesn't reflect number of iterations, it reflects number of expression evaluation

Removing Digits from a Number

Does anybody know if there is a way of removing (trimming) the last two digits or first two digits from a number. I have the number 4131 and I want to separate that into 41 and 31, but after searching the Internet, I've only managed to find how to remove characters from a string, not a number. I tried converting my number to a string, then removing characters, and then converting it back to a number, but I keep receiving errors.
I believe I will be able to receive the first two digit by dividing the number by 100 and then rounding the number down, but I don't have an idea of how to get the last two digits?
Does anybody know the function to use to achieve what I'm trying to do, or can anybody point me in the right direction.
Try this:
var num = 1234
var first = num/100
var last = num%100
The playground's output is what you need.
You can use below methods to find the last two digits
func getLatTwoDigits(number : Int) -> Int {
return number%100; //4131%100 = 31
}
func getFirstTwoDigits(number : Int) -> Int {
return number/100; //4131/100 = 41
}
To find the first two digit you might need to change the logic on the basis of face value of number. Below method is generalise method to find each digit of a number.
func printDigits(number : Int) {
var num = number
while num > 0 {
var digit = num % 10 //get the last digit
println("\(digit)")
num = num / 10 //remove the last digit
}
}

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.