/* CSC 123/252 Assignment, due one week from date assigned. There are 4 types of numbers: integers, rationals, reals and complex numbers. You want to test for equality between them, and add them *without loss of precision* whenever possible. That is, only convert to a float (used in real and complex numbers) when necessary. Note that the visitor pattern approach (by itself) won't be enough because instead of double dispatch, you'll need triple dispatch. Each visitor (equality or addition) will need to visit two visitees. There are two parts to this assignment. Part 1, REQUIRED: complete all cases of the functions eq and add inside the class challenge for at least integer, rational and real (complex is optional). Try to compile the program in main (with test for part 1 uncommented). It won't compile. Please EXPLAIN WHY IT DOESN'T WORK. Part 2 (challenge): get the program to work. You can write a single function number add(number x, number y), or modify the "dummy filler" implementations of .equals and .add inside each concrete number class so that they would work properly. The code inside Main should compile and run as expected with the test for part 2 uncommented. *** Try to avoid if or switch statements in your program as much as possible *** Hint: create 2D array in C# with int[,] A = new int[rows,columns]; use A[i,j] instead of A[i][j]. It's a "real" 2D array, unlike in Java This assignment is due before it's discussed in class. */ using System; public interface number { bool equals(number x); number add(number x); // non-destructive addition } public class integer : number { public int val; public integer(int v) {val=v;} public override string ToString() { return val+"";} public bool equals(number x) { return false; } // dummy filler public number add(number x) { return this; } // dummy filler }//integer public class rational : number // fraction like 1/2 { public int n; //numerator and denominator public int d; public rational(int a, int b) { if (b!=0) { n=a; d=b;} else throw new Exception("bad rational"); } public override string ToString() { return n+"/"+d; } public bool equals(number x) { return false; } // dummy filler public number add(number x) { return this; } // dummy filler } public class real : number // approximate real number using a float { public double val; public real(double v) { val=v; } public override string ToString() { return val+""; } public bool equals(number x) { return false; } // dummy filler public number add(number x) { return this; } // dummy filler } public class complex : number // complex number 2+3i { public double r; // real part public double i; // imaginary part public complex(double a, double b) {r=a; i=b; } public override string ToString() { return r+"+"+i+"i"; } public bool equals(number x) { return false; } // dummy filler public number add(number x) { return this; } // dummy filler /* rules of complex arithmetic: (a+bi) + (c+di) = (a+c) + (b+d)i (a+bi) * (c+di) = (ac-bd)i + (bc+ad)i a+bi == c+di if a==c and b==d. A real number r can be cast to complex r+0i. */ }//complex public class challenge { static bool eq(integer x, integer y) { return x.val==y.val; } static bool eq(integer x, rational y) { return x.val*y.d == y.n; } static bool eq(rational a, rational b) {return a.n*b.d==a.d*b.n;} static bool eq(rational a, real b) => a.n/a.d == b.val; // new syntax static number add(integer a, real b) { return new real(a.val+b.val); } static number add(rational a, rational b) { return new rational(a.n*b.d + b.n*a.d, a.d*b.d); } // rational addition //.... EVEN IF YOU WRITE ALL THE CASES, //.... THIS APPROACH ALONE WON'T WORK. Why? //Want this to work: public static void Main() { number[] N = {new rational(1,2),new integer(3),new real(3.14)}; number sum = new integer(0); // foreach(number x in N) sum = add(sum,x); // test for Part 1 foreach(number x in N) sum = sum.add(x); // test for Part 2 Console.WriteLine(sum); } } /* The .add method must keep the same level of precision. e.g., adding an integer to a rational should return a rational, not a real. rational(1/3) is more precise than 0.3333... In other words, you can return a real when adding an integer to a real but not when you're adding a rational to another integer or rational. */ // This assignment may also be done in Kotlin