Does D automatically rewrite opBinary to opOpAssign? - operator-overloading

for example, assuming that T implements the right operator overloads:
T t1, t2, t3;
t3 = t1 + t2; // t3.opAssign(t1.opBinary!"+"(t2)) for sure
t3 = t3 + t2; // rewritten to t3.opOpAssign!"+"(t2) ?
Is the last operation optimized by D ?

No, it is not. It is not possible, because opBinary and opOpAssign could have different semantic:
struct S
{
int val = 5;
S opBinary(string op)(S rhs) if (op == "+")
{
return S(val + rhs.val);
}
void opOpAssign(string op)(S rhs) if (op == "+")
{
val = val - rhs.val;
}
}
void main()
{
import std.stdio;
S s1, s2, s3;
writeln(s3); // S(5)
s3 = s3 + s2;
writeln(s3); // S(10)
s3.val = 5;
writeln(s3); // S(5)
s3 += s2;
writeln(s3); // S(0)
}

What is opOpBinary? Did you mean opOpAssign?
And no, it doesn't. For example, appending (~=) and concatenating (~) arrays are different operations (the former preallocates extra space at the end and the latter will always reallocate).

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}
}

Extract coefficients from binomial expression entered as a string in Scala

I am trying to write a program that can find the roots of a quadratic equation using Scala. The input should be a quadratic equation in the form ax^2+bx+c (e.g: 5x^2+2x+3) as a string.
I managed to code the calculation of the roots but am having trouble extracting the coefficients from the input. Here's the code I wrote for extracting the coefficients so far:
def getCoef(poly: String) = {
var aT: String = ""
var bT: String = ""
var cT: String = ""
var x: Int = 2
for (i <- poly.length - 1 to 0) {
val t: String = poly(i).toString
if (x == 2) {
if (t forall Character.isDigit) aT = aT + t(i)
else if (t == "^") {i = i + 1; x = 1}
}
else if (x == 1) {
if (t forall Character.isDigit) bT = bT + t(i)
else if (t == "+" || t == "-") x = 0
}
else if (x == 0) {
if (t forall Character.isDigit) cT = cT + t(i)
}
val a: Int = aT.toInt
val b: Int = bT.toInt
val c: Int = cT.toInt
(a, b, c)
}
}
Simple solution with regex:
def getCoef(poly: String) = {
val polyPattern = """(\d+)x\^2\+(\d+)x\+(\d+)""".r
val matcher = polyPattern.findFirstMatchIn(poly).get
(matcher.group(1).toInt, matcher.group(2).toInt, matcher.group(3).toInt)
}
Does not handle all cases (e.g.: minus) and just throws an error if the input does not match the pattern, but it should get you going.

Simplifying nested ifs with multiple exit points in Scala?

There has to be a better way to do this.. I'm testing for a ray-triangle intersection and my code looks something like this
if(some condition) fail
else {
...
if(some other condition) fail
else {
...
intersection
}
}
with many nested ifs. It's disgusting. I'm doing this not to use any return statements. Is there an alternate control structure I could use here to manage the various method exit points?
You could use for comprehension:
val result: Option[BasicIntersection] = for {
edge1 <- Some(vertices(1) - vertices(0))
edge2 = vertices(2) - vertices(0)
P = ray.v cross edge2
determinant = edge1 dot P
if !(determinant > -Utils.EPSILON && determinant < Utils.EPSILON)
inv_determinant = 1.0/determinant
T = ray.p - vertices(0)
u = (T dot P) * inv_determinant
if !(u < 0 || u > 1)
Q = T cross edge1
v = (ray.v dot Q) * inv_determinant
if !(v < 0 || u + v > 1)
t = (edge2 dot Q) * inv_determinant
if !(t < Utils.EPSILON)
hit = ray.p + ray.v*t
} yield
if (hasUV) {
val d0 = Math.abs((hit - vertices(0)).length)
val d1 = Math.abs((hit - vertices(1)).length)
val d2 = Math.abs((hit - vertices(2)).length)
val uvAvg = (uv(0)*d0 + uv(1)*d1 + uv(2)*d2) / (d0 + d1 + d2)
new BasicIntersection(hit, edge1 cross edge2, t, uvAvg)
} else {
new BasicIntersection(hit, edge1 cross edge2, t)
}
result.getOrElse(new BasicIntersection()) // Your failure case

How to get unique elements from two lists of strings in scala?

I have two list to compare:
List one:
List("one","two","three","four")
List two:
List("one","two")
how can I get the unique values from these two lists?
If your two lists are r1 and r2, and assuming you want the values in each list that are not present in the other:
r1.filterNot(r2.contains) ::: r2.filterNot(r1.contains)
or
r1.diff(r2) ::: r2.diff(r1)
Turn them into sets, and get the intersection. You may then turn it back to Seq if you want, but first ask yourself if they had to be Seq in first place, instead of Set.
scala> List("one","two","three","four").toSet & List("one","two").toSet
res0: scala.collection.immutable.Set[String] = Set(one, two)
Use The difference operator for Set &~
http://www.scala-lang.org/api/current/scala/collection/immutable/Set.html
I use List(1, 2, 3, 4) ::: List(1, 2, 5) distinct for this issue. It returns List(1, 2, 3, 4, 5).
I would suggest using the following for O(m+n) running time (assumes input arrays are sorted).
def mergeUniqueSortedArrays( A: Array[String], B: Array[String] ): Array[String]= {
val n = A.length
val m = B.length
var C = Array[String]()
var i = 0
var j = 0
while (i < n && j < m) {
if (i == n) {
if ( B(j) != A(i-1) ) {
C :+= B(j)
}
j+=1
}
else if (j == m) {
if ( A(i) != B(j-1) ) {
C :+= A(j)
}
i+=1
}
else {
if ( A(i) < B(j) ) {
if (C.length == 0 || A(i) != C(C.length-1)) {
C :+= A(i)
}
i+=1
}
else if ( B(j) < A(i) ) {
if (C.length == 0 || B(j) != C(C.length-1)) {
C :+= B(j)
}
j+=1
}
else {
if (C.length == 0 || A(i) != C(C.length-1)) {
C :+= A(i)
}
i+=1
j+=1
}
}
}
return C
}
--
NOTE: If the input arrays are not sorted, then you can easily sort the input arrays and it will run in in O( max{(n + m), (n log n)}) time, assuming n>m.
NOTE: O(n + m) time technically assumes that string length is bounded by constant k, but you aren't going to get around that anyway.