How does the while loop in this code work? - swift

I am trying to complete a problem on LeetCode and I have found this solution in Swift but I am really not sure what happens in this while loop of the code :
func getSum(a: Int, _ b: Int) -> Int {
var a = a
var b = b
while b != 0 {
(a, b) = (a ^ b, (a & b) << 1)
}
return a
}
Thank you for any help.

(a, b) = (a ^ b, (a & b) << 1) is doing a tuple assignment. It can be broken down into:
let oldA = a
let oldB = b
a = oldA ^ oldB
b = (oldA & oldB) << 1
^ is the bit-wist exclusive-or (XOR) operator in Swift (and most C-like languages)
& is the bit-wise and (AND) operator in Swift (and most C-Like languages)
<< is the left bit shift operator. x << 1 means "bit-shift x to the left by 1"

As complement to #Alexander Momchliov's answer—which explains the bit-wise operators used—note also that you needn't use mutable local scope variables and a while loop in the getSum(...) function, but can use the same bit-operator calculations in recursive calls to the function itself, e.g.
func getSum(a: Int, _ b: Int) -> Int {
if b == 0 { return a }
return getSum(a ^ b, (a & b) << 1)
}

Related

Swift ^ Operation on Double

I am trying to solve a challenge but the code keeps failing.
I need to perform a ^ operation on doubles. Challenge was if I call a function calculate(3,2,^) then I should get the result 9.
I tried the below code but failed with this error:
error: binary operator '^' cannot be applied to two 'Double' operands
Below is my Code:
func calc(a: Double, b: Double, op: Character) -> Double {
var c:Double
c = 0
if op == "+"
{
c = a + b
}
else if op == "-"
{
c = a - b
}
else if op == "*"
{
c = a * b
}
else if op == "/"
{
c = a / b
}
else if op == "%"
{
let rem = a.truncatingRemainder(dividingBy: b)
c = rem
}
else if op == "^"
{
let z = a ^ b
c = z
}
return c
}
^ is the bitwise XOR operator, not exponentiation.
Use the pow(_:_:) method instead:
else if op == "^"
{
c = pow(a, b)
}
try to use boucle For
for (let index = 0; index < b; index++) {
c= a*index;
}

How to ceil the result for UInt division in Chisel

As the title stated, how to do that?
val a = 3.U
val result = a / 2.U
result would be 1.U
However I want to apply ceil on division.
val result = ceil(a / 2.U )
Therefore, I could get 2.U of the result value.
When dividing a by b, if you know that a is not too big (namely that a <= UInt.MaxValue - (b - 1)), then you can do
def ceilUIntDiv(a: UInt, b: UInt): UInt =
(a + b - 1.U) / b
If a is potentially too big, then the above can overflow, and you'll need to adapt the result after the fact instead:
def ceilUIntDiv(a: UInt, b: UInt): UInt = {
val c = a / b
if (b * c == a) c else c + 1.U
}
The problem is the expression a / 2.U is indeed 1.U: if you apply ceil to 1.U you'll get 1.U.
Recall that this happens to Ints as well, as they use integer division:
scala> val result = Math.ceil(3 / 2)
result: Double = 1.0
What you should do is to enforce one of the division operands to be a Double likewise:
scala> val result = Math.ceil(3 / (2: Double))
result: Double = 2.0
And then just convert it back to UInt.
def ceilUIntDiv(a: UInt, b: UInt): UInt = {
(a / b) + {if (a % b == 0.U) 0.U else 1.U}
}

Jenkins Hash in Scala

I'm trying to write the Jenkins Hash (http://burtleburtle.net/bob/hash/doobs.html) in Scala. This bit is tricky...
switch(len) /* all the case statements fall through */
{
case 11: c+=((ub4)k[10]<<24);
case 10: c+=((ub4)k[9]<<16);
case 9 : c+=((ub4)k[8]<<8);
/* the first byte of c is reserved for the length */
case 8 : b+=((ub4)k[7]<<24);
case 7 : b+=((ub4)k[6]<<16);
case 6 : b+=((ub4)k[5]<<8);
case 5 : b+=k[4];
case 4 : a+=((ub4)k[3]<<24);
case 3 : a+=((ub4)k[2]<<16);
case 2 : a+=((ub4)k[1]<<8);
case 1 : a+=k[0];
/* case 0: nothing left to add */
}
match statements don't fall through in Scala (which is an excellent design decision). So best way to do this I can think of is to have one if statement per case. I'm hoping someone can see a more pithy solution…
Something like this perhaps?
val (a,b,c) = k
.zipWithIndex
.foldLeft((0,0,0)) { case ((a,b,c), (v, index)) =>
index match {
case i if i < 4 => (a + (v << i*8), b, c)
case i if i < 8 => (a, b + (v << (i-4)*8), b, c)
case i => (a, b, c + (v << (i-7)*8))
}
}
I haven't tested the result, but this is one way to implement it. Drop and take the bytes of the array needed for each value. Also fold from right in order to rotate the rightmost value from 0 to 8 to 16 to 24.
Working with unsigned in JVM is a bit cumbersome and requires that we transform it to a wider data type, i.e. byte to int and int to long). Therefore we use longify to convert to byte to long. We also need to account for half the byte values being negative.
val longify = ((n: Byte) => n.toLong) andThen (n => if (n < 0) n + 256 else n)
def sum(m: Int, n: Int) =
k.drop(m).take(n).foldRight(0L)((b, s) => longify(b) + (s << 8))
val a = sum(0, 4)
val b = sum(4, 4)
val c = (sum(9, 3) << 8) + k.size

println in scala for-comprehension

In a for-comprehension, I can't just put a print statement:
def prod (m: Int) = {
for (a <- 2 to m/(2*3);
print (a + " ");
b <- (a+1) to m/a;
c = (a*b)
if (c < m)) yield c
}
but I can circumvent it easily with a dummy assignment:
def prod (m: Int) = {
for (a <- 2 to m/(2*3);
dummy = print (a + " ");
b <- (a+1) to m/a;
c = (a*b)
if (c < m)) yield c
}
Being a side effect, and only used (so far) in code under development, is there a better ad hoc solution?
Is there a serious problem why I shouldn't use it, beside being a side effect?
update showing the real code, where adapting one solution is harder than expected:
From the discussion with Rex Kerr, the necessity has risen to show the original code, which is a bit more complicated, but did not seem to be relevant for the question (2x .filter, calling a method in the end), but when I tried to apply Rex' pattern to it I failed, so I post it here:
def prod (p: Array[Boolean], max: Int) = {
for (a <- (2 to max/(2*3)).
filter (p);
dummy = print (a + " ");
b <- (((a+1) to max/a).
filter (p));
if (a*b <= max))
yield (em (a, b, max)) }
Here is my attempt -- (b * a).filter is wrong, because the result is an int, not a filterable collection of ints:
// wrong:
def prod (p: Array[Boolean], max: Int) = {
(2 to max/(2*3)).filter (p).flatMap { a =>
print (a + " ")
((a+1) to max/a).filter (p). map { b =>
(b * a).filter (_ <= max).map (em (a, b, max))
}
}
}
Part II belongs to the comments, but can't be read, if written there - maybe I delete it in the end. Please excuse.
Ok - here is Rex last answer in code layout:
def prod (p: Array[Boolean], max: Int) = {
(2 to max/(2*3)).filter (p).flatMap { a =>
print (a + " ")
((a+1) to max/a).filter (b => p (b)
&& b * a < max).map { b => (m (a, b, max))
}
}
}
This is how you need to write it:
scala> def prod(m: Int) = {
| for {
| a <- 2 to m / (2 * 3)
| _ = print(a + " ")
| b <- (a + 1) to (m / a)
| c = a * b
| if c < m
| } yield c
| }
prod: (m: Int)scala.collection.immutable.IndexedSeq[Int]
scala> prod(20)
2 3 res159: scala.collection.immutable.IndexedSeq[Int] = Vector(6, 8, 10, 12, 14
, 16, 18, 12, 15, 18)
Starting Scala 2.13, the chaining operation tap, has been included in the standard library, and can be used with minimum intrusiveness wherever we need to print some intermediate state of a pipeline:
import util.chaining._
def prod(m: Int) =
for {
a <- 2 to m / (2 * 3)
b <- (a + 1) to (m / a.tap(println)) // <- a.tap(println)
c = a * b
if c < m
} yield c
prod(20)
// 2
// 3
// res0: IndexedSeq[Int] = Vector(6, 8, 10, 12, 14, 16, 18, 12, 15, 18)
The tap chaining operation applies a side effect (in this case println) on a value (in this case a) while returning the value (a) untouched:
def tap[U](f: (A) => U): A
It's very convenient when debugging as you can use a bunch of taps without having to modify the code:
def prod(m: Int) =
for {
a <- (2 to m.tap(println) / (2 * 3)).tap(println)
b <- (a + 1) to (m / a.tap(println))
c = (a * b).tap(println)
if c < m
} yield c
I generally find that style of coding rather difficult to follow, since loops and intermediate results and such get all mixed in with each other. I would, instead of a for loop, write something like
def prod(m: Int) = {
(2 to m/(2*3)).flatMap { a =>
print(a + " ")
((a+1) to m/a).map(_ * a).filter(_ < m)
}
}
This also makes adding print statements and such easier.
It doesn't seem like good style to put a side-effecting statement within a for-comprehension (or indeed in the middle of any function), execept for debugging in which case it doesn't really matter what you call it ("debug" seems like a good name).
If you really need to, I think you'd be better separating your concerns somewhat by assigning an intermediate val, e.g. (your original laid out more nicely):
def prod (p: Array[Boolean], max: Int) = {
for {
a <- (2 to max / (2 * 3)) filter p
debug = print (a + " ")
b <- ((a + 1) to max / a) filter p
if a * b <= max
} yield em(a, b, max)
}
becomes
def prod2 (p: Array[Boolean], max: Int) = {
val as = (2 to max / (2 * 3)) filter p
for(a <- as) print(a + " ")
as flatMap {a =>
for {
b <- ((a + 1) to max / a) filter p
if a * b <= max
} yield em(a, b, max)
}
}

How do I match multiple arguments?

I have a function:
def func(a: int, b: int, c: double): int
And I want to match various possible scenarios
Wherever c is 0, return b-a
Wherever c > 9, return 0
Wherever a=b return 0
And so on, before doing some more complex logic if none of the above are satisfied.
Do I have to match c separately first, or can I match on a,b,c, like _,_,0?
You can pattern match all described cases like this:
def func(a: Int, b: Int, c: Double) = (a, b, c) match {
case (a, b, 0) => b - a
case (a, b, c) if c > 9 || a == b => 0
case _ => 1 // add your logic here
}
Following on from my comments to Easy Angel's answer, I still feel this
if (c == 0)
b -a
else if (c > 9)
0
else if (a == b)
0
else
1 // your logic here
is clearer. Basically because there isn't really any pattern to match here.