Table of content

What is this?

The rules of the game are explained in my original post.

3rd Challenge

Challenge

Create a complex number which can be added, subtracted and multiplied.

Solution

I chose to do this with operator overloading on a struct type. I forgot about borrowing for a moment and implemented the operators by value and not by reference meaning I had to add clone and copy for it to work.

	use std::ops;
	use std::fmt;

	#[derive(Clone, Copy)]
	struct ComplexNumber {
	    re: i32,
	    im: i32
	}

	fn main() {
	    let a = ComplexNumber { re: 1, im: 2 };
	    let b = ComplexNumber { re: 3, im: 4 };

	    println!("({})+({}) = {}",a,b,a+b);
	    println!("({})-({}) = {}",a,b,a-b);
	    println!("({})*({}) = {}",a,b,a*b);
	}

	impl ops::Add<ComplexNumber> for ComplexNumber {
	    type Output = ComplexNumber;

	    fn add(self, b: ComplexNumber) -> ComplexNumber {
	        let mut x:ComplexNumber = ComplexNumber { re: 0, im: 0 };
	        x.im = self.im + b.im;
	        x.re = self.re + b.im;
	        x
	    }
	}

	impl ops::Sub<ComplexNumber> for ComplexNumber {
	    type Output = ComplexNumber;

	    fn sub(self, b: ComplexNumber) -> ComplexNumber {
	        let mut x:ComplexNumber = ComplexNumber { re: 0, im: 0 };
	        x.im = self.im - b.im;
	        x.re = self.re - b.im;
	        x
	    }
	}

	impl ops::Mul<ComplexNumber> for ComplexNumber {
	    type Output = ComplexNumber;

	    fn mul(self, b: ComplexNumber) -> ComplexNumber {
	        let mut x:ComplexNumber = ComplexNumber { re: 0, im: 0 };
	        x.im = self.im * b.re + self.re * b.im;
	        x.re = self.re * b.re - self.im * b.im;
	        x
	    }
	}

	impl fmt::Display for ComplexNumber {
	    // This trait requires `fmt` with this exact signature.
	    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
	        write!(f, "{}+{}i", self.re,self.im)
	    }
	}
	

The better implementation by value is as follows, note if you want to really implement the operators you must implement all four cases of pointer and value type (see stackverflow on the use of impl_ops crate

	use std::ops;
	use std::fmt;


	struct ComplexNumber {
	    re: i32,
	    im: i32
	}

	fn main() {
	    let a = ComplexNumber { re: 1, im: 2 };
	    let b = ComplexNumber { re: 3, im: 4 };

	    println!("({})+({}) = {}",a,b,&a+&b);
	    println!("({})-({}) = {}",a,b,&a-&b);
	    println!("({})*({}) = {}",a,b,&a*&b);
	}

	impl ops::Add<& ComplexNumber> for &ComplexNumber {
	    type Output = ComplexNumber;

	    fn add(self, b: &ComplexNumber) -> ComplexNumber {
	        let mut x:ComplexNumber = ComplexNumber { re: 0, im: 0 };
	        x.im = &self.im + &b.im;
	        x.re = &self.re + &b.im;
	        x
	    }
	}

	impl ops::Sub<& ComplexNumber> for &ComplexNumber {
	    type Output = ComplexNumber;

	    fn sub(self, b: &ComplexNumber) -> ComplexNumber {
	        let mut x:ComplexNumber = ComplexNumber { re: 0, im: 0 };
	        x.im = &self.im - &b.im;
	        x.re = &self.re - &b.im;
	        x
	    }
	}

	impl ops::Mul<& ComplexNumber> for &ComplexNumber {
	    type Output = ComplexNumber;

	    fn mul(self, b: &ComplexNumber) -> ComplexNumber {
	        let mut x:ComplexNumber = ComplexNumber { re: 0, im: 0 };
	        x.im = &self.im * &b.re + &self.re * &b.im;
	        x.re = &self.re * &b.re - &self.im * &b.im;
	        x
	    }
	}

	impl fmt::Display for ComplexNumber {
	    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
	        write!(f, "{}+{}i", self.re,self.im)
	    }
	}
	

Permalink running on Playground and source on github