From 8e98e1fea3bec2ec65cc4c5b1ffe5aacc3879610 Mon Sep 17 00:00:00 2001 From: Anthony Cicchetti Date: Sun, 13 Aug 2017 17:40:01 -0400 Subject: [PATCH] Kotlin - Complex Numbers WIP --- kotlin/complex-numbers/README.md | 14 + kotlin/complex-numbers/build.gradle | 28 ++ kotlin/complex-numbers/complex-numbers.iml | 13 + .../src/main/kotlin/ComplexNumber.kt | 53 ++++ .../src/test/kotlin/ComplexNumberTest.kt | 266 ++++++++++++++++++ 5 files changed, 374 insertions(+) create mode 100644 kotlin/complex-numbers/README.md create mode 100644 kotlin/complex-numbers/build.gradle create mode 100644 kotlin/complex-numbers/complex-numbers.iml create mode 100644 kotlin/complex-numbers/src/main/kotlin/ComplexNumber.kt create mode 100644 kotlin/complex-numbers/src/test/kotlin/ComplexNumberTest.kt diff --git a/kotlin/complex-numbers/README.md b/kotlin/complex-numbers/README.md new file mode 100644 index 0000000..950f8f0 --- /dev/null +++ b/kotlin/complex-numbers/README.md @@ -0,0 +1,14 @@ +# Complex Numbers + +A complex number is a number in the form `a + b * i` where `a` and `b` are real and `i` satisfies `i^2 = -1`. + +Assume the programming language you are using does not have an implementation of complex numbers. + + + +## Source + +Wikipedia [https://en.wikipedia.org/wiki/Complex_number](https://en.wikipedia.org/wiki/Complex_number) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/kotlin/complex-numbers/build.gradle b/kotlin/complex-numbers/build.gradle new file mode 100644 index 0000000..16c36c0 --- /dev/null +++ b/kotlin/complex-numbers/build.gradle @@ -0,0 +1,28 @@ +buildscript { + ext.kotlin_version = '1.1.1' + repositories { + mavenCentral() + } + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +apply plugin: 'kotlin' + +repositories { + mavenCentral() +} + +dependencies { + compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + + testCompile 'junit:junit:4.12' + testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version" +} +test { + testLogging { + exceptionFormat = 'full' + events = ["passed", "failed", "skipped"] + } +} diff --git a/kotlin/complex-numbers/complex-numbers.iml b/kotlin/complex-numbers/complex-numbers.iml new file mode 100644 index 0000000..e6e1008 --- /dev/null +++ b/kotlin/complex-numbers/complex-numbers.iml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/kotlin/complex-numbers/src/main/kotlin/ComplexNumber.kt b/kotlin/complex-numbers/src/main/kotlin/ComplexNumber.kt new file mode 100644 index 0000000..c16aa51 --- /dev/null +++ b/kotlin/complex-numbers/src/main/kotlin/ComplexNumber.kt @@ -0,0 +1,53 @@ +data class ComplexNumber(val real: Double = 0.0, val imag: Double = 0.0){ + operator fun plus(other: ComplexNumber): ComplexNumber{ + return ComplexNumber(real = this.real + other.real, imag = this.imag + other.imag) + } + + operator fun times(other: ComplexNumber): ComplexNumber{ + val a = this.real + val b = this.imag + val c = other.real + val d = other.imag + + return ComplexNumber(a*c - b*d, b*c + a * d) + } + + operator fun minus(other: ComplexNumber): ComplexNumber{ + return ComplexNumber(real = this.real - other.real, imag = this.imag - other.imag) + } + + operator fun div(other: ComplexNumber): ComplexNumber{ + val a = this.real + val b = this.imag + val c = other.real + val d = other.imag + + return ComplexNumber(real = (a * c + b * d)/(c * c + d * d), imag = (b * c - a * d)/(c * c + d * d)) + } + + val abs: Double = Math.sqrt((real * real) + (imag * imag)) + fun conjugate(): ComplexNumber { + return ComplexNumber(real = this.real, imag = this.imag.unaryMinus()) + } + + fun cos(): ComplexNumber{ + val x = this.real + val y = this.imag + return ComplexNumber(Math.cos(x) * Math.cosh(y), (Math.sin(x) * Math.sinh(y)).unaryMinus()) + } + + fun sin(): ComplexNumber{ + val x = this.real + val y = this.imag + return ComplexNumber(Math.sin(x) * Math.cosh(y), (Math.cos(x) * Math.sinh(y))) + } +} + +// This implementation is silly, there is no documentation for it +fun exponential(num: ComplexNumber): ComplexNumber{ + val x = num.real + val y = num.imag + + + return ComplexNumber(real = Math.pow(Math.E, x), imag = 1.0) * ComplexNumber(real = 1.0, imag = Math.pow(Math.E, y)) +} \ No newline at end of file diff --git a/kotlin/complex-numbers/src/test/kotlin/ComplexNumberTest.kt b/kotlin/complex-numbers/src/test/kotlin/ComplexNumberTest.kt new file mode 100644 index 0000000..0a554d8 --- /dev/null +++ b/kotlin/complex-numbers/src/test/kotlin/ComplexNumberTest.kt @@ -0,0 +1,266 @@ +import org.junit.Assert.assertEquals +import org.junit.Ignore +import org.junit.Test + +/* + * version: 1.0.0 + */ +class ComplexNumberTest { + + // Test helpers + + companion object { + private const val DOUBLE_EQUALITY_TOLERANCE = 1e-15 + } + + private fun assertDoublesEqual(d1: Double, d2: Double) { + assertEquals(d1, d2, DOUBLE_EQUALITY_TOLERANCE) + } + + private fun assertComplexNumbersEqual(c1: ComplexNumber, c2: ComplexNumber) { + assertDoublesEqual(c1.real, c2.real) + assertDoublesEqual(c1.imag, c2.imag) + } + + // Tests + + @Test + fun testImaginaryUnitExhibitsDefiningProperty() { + val expected = ComplexNumber(real = -1.0) + val actual = ComplexNumber(imag = 1.0) * ComplexNumber(imag = 1.0) + assertComplexNumbersEqual(expected, actual) + } + + @Ignore + @Test + fun testAdditionWithPurelyRealNumbers() { + val expected = ComplexNumber(real = 3.0) + val actual = ComplexNumber(real = 1.0) + ComplexNumber(real = 2.0) + assertComplexNumbersEqual(expected, actual) + } + + @Ignore + @Test + fun testAdditionWithPurelyImaginaryNumbers() { + val expected = ComplexNumber(imag = 3.0) + val actual = ComplexNumber(imag = 1.0) + ComplexNumber(imag = 2.0) + assertComplexNumbersEqual(expected, actual) + } + + @Ignore + @Test + fun testAdditionWithRealAndImaginaryParts() { + val expected = ComplexNumber(real = 4.0, imag = 6.0) + val actual = ComplexNumber(real = 1.0, imag = 2.0) + ComplexNumber(real = 3.0, imag = 4.0) + assertComplexNumbersEqual(expected, actual) + } + + @Ignore + @Test + fun testSubtractionWithPurelyRealNumbers() { + val expected = ComplexNumber(real = -1.0, imag = 0.0) + val actual = ComplexNumber(real = 1.0, imag = 0.0) - ComplexNumber(real = 2.0, imag = 0.0) + assertComplexNumbersEqual(expected, actual) + } + + @Ignore + @Test + fun testSubtractionWithPurelyImaginaryNumbers() { + val expected = ComplexNumber(imag = -1.0) + val actual = ComplexNumber(imag = 1.0) - ComplexNumber(imag = 2.0) + assertComplexNumbersEqual(expected, actual) + } + + @Ignore + @Test + fun testSubtractionWithRealAndImaginaryParts() { + val expected = ComplexNumber(real = -2.0, imag = -2.0) + val actual = ComplexNumber(real = 1.0, imag = 2.0) - ComplexNumber(real = 3.0, imag = 4.0) + assertComplexNumbersEqual(expected, actual) + } + + @Ignore + @Test + fun testMultiplicationWithPurelyRealNumbers() { + val expected = ComplexNumber(real = 2.0) + val actual = ComplexNumber(real = 1.0) * ComplexNumber(real = 2.0) + assertComplexNumbersEqual(expected, actual) + } + + @Ignore + @Test + fun testMultiplicationWithPurelyImaginaryNumbers() { + val expected = ComplexNumber(real = -2.0) + val actual = ComplexNumber(imag = 1.0) * ComplexNumber(imag = 2.0) + assertComplexNumbersEqual(expected, actual) + } + + @Ignore + @Test + fun testMultiplicationWithRealAndImaginaryParts() { + val expected = ComplexNumber(real = -5.0, imag = 10.0) + val actual = ComplexNumber(real = 1.0, imag = 2.0) * ComplexNumber(real = 3.0, imag = 4.0) + assertComplexNumbersEqual(expected, actual) + } + + @Ignore + @Test + fun testDivisionWithPurelyRealNumbers() { + val expected = ComplexNumber(real = 0.5) + val actual = ComplexNumber(real = 1.0) / ComplexNumber(real = 2.0) + assertComplexNumbersEqual(expected, actual) + } + + @Ignore + @Test + fun testDivisionWithPurelyImaginaryNumbers() { + val expected = ComplexNumber(real = 0.5) + val actual = ComplexNumber(imag = 1.0) / ComplexNumber(imag = 2.0) + assertComplexNumbersEqual(expected, actual) + } + + @Ignore + @Test + fun testDivisionWithRealAndImaginaryParts() { + val expected = ComplexNumber(real = 0.44, imag = 0.08) + val actual = ComplexNumber(real = 1.0, imag = 2.0) / ComplexNumber(real = 3.0, imag = 4.0) + assertComplexNumbersEqual(expected, actual) + } + + @Ignore + @Test + fun testAbsoluteValueOfPositivePurelyRealNumber() { + val expected = 5.0 + val actual = ComplexNumber(real = 5.0).abs + assertDoublesEqual(expected, actual) + } + + @Ignore + @Test + fun testAbsoluteValueOfNegativePurelyRealNumber() { + val expected = 5.0 + val actual = ComplexNumber(real = -5.0).abs + assertDoublesEqual(expected, actual) + } + + @Ignore + @Test + fun testAbsoluteValueOfPurelyImaginaryNumberWithPositiveImaginaryPart() { + val expected = 5.0 + val actual = ComplexNumber(imag = 5.0).abs + assertDoublesEqual(expected, actual) + } + + @Ignore + @Test + fun testAbsoluteValueOfPurelyImaginaryNumberWithNegativeImaginaryPart() { + val expected = 5.0 + val actual = ComplexNumber(imag = -5.0).abs + assertDoublesEqual(expected, actual) + } + + @Ignore + @Test + fun testAbsoluteValueOfNumberWithRealAndImaginaryParts() { + val expected = 5.0 + val actual = ComplexNumber(real = 3.0, imag = 4.0).abs + assertDoublesEqual(expected, actual) + } + + @Ignore + @Test + fun testConjugationOfPurelyRealNumber() { + val expected = ComplexNumber(real = 5.0) + val actual = ComplexNumber(real = 5.0).conjugate() + assertComplexNumbersEqual(expected, actual) + } + + @Ignore + @Test + fun testConjugationOfPurelyImaginaryNumber() { + val expected = ComplexNumber(imag = -5.0) + val actual = ComplexNumber(imag = 5.0).conjugate() + assertComplexNumbersEqual(expected, actual) + } + + @Ignore + @Test + fun testConjugationOfNumberWithRealAndImaginaryParts() { + val expected = ComplexNumber(real = 1.0, imag = -1.0) + val actual = ComplexNumber(real = 1.0, imag = 1.0).conjugate() + assertComplexNumbersEqual(expected, actual) + } + + @Ignore + @Test + fun testRealPartOfPurelyRealNumber() { + val expected = 1.0 + val actual = ComplexNumber(real = 1.0).real + assertDoublesEqual(expected, actual) + } + + @Ignore + @Test + fun testRealPartOfPurelyImaginaryNumber() { + val expected = 0.0 + val actual = ComplexNumber(imag = 1.0).real + assertDoublesEqual(expected, actual) + } + + @Ignore + @Test + fun testRealPartOfNumberWithRealAndImaginaryParts() { + val expected = 1.0 + val actual = ComplexNumber(real = 1.0, imag = 2.0).real + assertDoublesEqual(expected, actual) + } + + @Ignore + @Test + fun testImaginaryPartOfPurelyRealNumber() { + val expected = 0.0 + val actual = ComplexNumber(real = 1.0).imag + assertDoublesEqual(expected, actual) + } + + @Ignore + @Test + fun testImaginaryPartOfPurelyImaginaryNumber() { + val expected = 1.0 + val actual = ComplexNumber(imag = 1.0).imag + assertDoublesEqual(expected, actual) + } + + @Ignore + @Test + fun testImaginaryPartOfNumberWithRealAndImaginaryParts() { + val expected = 2.0 + val actual = ComplexNumber(real = 1.0, imag = 2.0).imag + assertDoublesEqual(expected, actual) + } + + @Ignore + @Test + fun testExponentialOfPurelyImaginaryNumber() { + val expected = ComplexNumber(real = -1.0) + val actual = exponential(ComplexNumber(imag = Math.PI)) + assertComplexNumbersEqual(expected, actual) + } + + @Ignore + @Test + fun testExponentialOfZero() { + val expected = ComplexNumber(real = 1.0) + val actual = exponential(ComplexNumber()) + assertComplexNumbersEqual(expected, actual) + } + + @Ignore + @Test + fun testExponentialOfPurelyRealNumber() { + val expected = ComplexNumber(real = Math.E) + val actual = exponential(ComplexNumber(real = 1.0)) + assertComplexNumbersEqual(expected, actual) + } + +}