Skip to content

Commit 9540d06

Browse files
authored
complex-numbers (#61)
1 parent 0024536 commit 9540d06

10 files changed

Lines changed: 650 additions & 0 deletions

File tree

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,14 @@
470470
"practices": [],
471471
"prerequisites": [],
472472
"difficulty": 6
473+
},
474+
{
475+
"slug": "complex-numbers",
476+
"name": "Complex Numbers",
477+
"uuid": "29567d07-2cf5-444b-aa82-5cbd6a9820d0",
478+
"practices": [],
479+
"prerequisites": [],
480+
"difficulty": 6
473481
}
474482
]
475483
},
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
return {
2+
default = {
3+
ROOT = { '.' }
4+
}
5+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# dummy
2+
3+
## MoonScript-specific instructions
4+
5+
This is an object-oriented exercise: you're implementing ComplexNumbers as a class.
6+
7+
The tests will be comparing two complex number instances for equality.
8+
This means your class will have to implement the `__eq` [metamethod][metamethods].
9+
10+
The tests also perform arithmetic operations on complex numbers, so there are arithmetic metamethods to implement.
11+
12+
~~~~exercism/caution
13+
Some of the complex number functions will be doing math with floating point numbers.
14+
Your "equality" will have to deal with numbers being _approximately equal_.
15+
~~~~
16+
17+
[metamethods]: https://www.lua.org/manual/5.4/manual.html#2.4
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# Instructions
2+
3+
A **complex number** is expressed in the form `z = a + b * i`, where:
4+
5+
- `a` is the **real part** (a real number),
6+
7+
- `b` is the **imaginary part** (also a real number), and
8+
9+
- `i` is the **imaginary unit** satisfying `i^2 = -1`.
10+
11+
## Operations on Complex Numbers
12+
13+
### Conjugate
14+
15+
The conjugate of the complex number `z = a + b * i` is given by:
16+
17+
```text
18+
zc = a - b * i
19+
```
20+
21+
### Absolute Value
22+
23+
The absolute value (or modulus) of `z` is defined as:
24+
25+
```text
26+
|z| = sqrt(a^2 + b^2)
27+
```
28+
29+
The square of the absolute value is computed as the product of `z` and its conjugate `zc`:
30+
31+
```text
32+
|z|^2 = z * zc = a^2 + b^2
33+
```
34+
35+
### Addition
36+
37+
The sum of two complex numbers `z1 = a + b * i` and `z2 = c + d * i` is computed by adding their real and imaginary parts separately:
38+
39+
```text
40+
z1 + z2 = (a + b * i) + (c + d * i)
41+
= (a + c) + (b + d) * i
42+
```
43+
44+
### Subtraction
45+
46+
The difference of two complex numbers is obtained by subtracting their respective parts:
47+
48+
```text
49+
z1 - z2 = (a + b * i) - (c + d * i)
50+
= (a - c) + (b - d) * i
51+
```
52+
53+
### Multiplication
54+
55+
The product of two complex numbers is defined as:
56+
57+
```text
58+
z1 * z2 = (a + b * i) * (c + d * i)
59+
= (a * c - b * d) + (b * c + a * d) * i
60+
```
61+
62+
### Reciprocal
63+
64+
The reciprocal of a non-zero complex number is given by:
65+
66+
```text
67+
1 / z = 1 / (a + b * i)
68+
= a / (a^2 + b^2) - b / (a^2 + b^2) * i
69+
```
70+
71+
### Division
72+
73+
The division of one complex number by another is given by:
74+
75+
```text
76+
z1 / z2 = z1 * (1 / z2)
77+
= (a + b * i) / (c + d * i)
78+
= (a * c + b * d) / (c^2 + d^2) + (b * c - a * d) / (c^2 + d^2) * i
79+
```
80+
81+
### Exponentiation
82+
83+
Raising _e_ (the base of the natural logarithm) to a complex exponent can be expressed using Euler's formula:
84+
85+
```text
86+
e^(a + b * i) = e^a * e^(b * i)
87+
= e^a * (cos(b) + i * sin(b))
88+
```
89+
90+
## Implementation Requirements
91+
92+
Given that you should not use built-in support for complex numbers, implement the following operations:
93+
94+
- **addition** of two complex numbers
95+
- **subtraction** of two complex numbers
96+
- **multiplication** of two complex numbers
97+
- **division** of two complex numbers
98+
- **conjugate** of a complex number
99+
- **absolute value** of a complex number
100+
- **exponentiation** of _e_ (the base of the natural logarithm) to a complex number
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"authors": [
3+
"glennj"
4+
],
5+
"files": {
6+
"solution": [
7+
"complex_numbers.moon"
8+
],
9+
"test": [
10+
"complex_numbers_spec.moon"
11+
],
12+
"example": [
13+
".meta/example.moon"
14+
]
15+
},
16+
"blurb": "Implement complex numbers.",
17+
"source": "Wikipedia",
18+
"source_url": "https://en.wikipedia.org/wiki/Complex_number"
19+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
class ComplexNumber
2+
new: (@r, @i = 0) =>
3+
4+
real: => @r
5+
imaginary: => @i
6+
7+
conjugate: => @@ @r, -@i
8+
9+
abs: => math.sqrt(@r^2 + @i^2)
10+
11+
__add: (other) =>
12+
@@ (@r + other.r), (@i + other.i)
13+
14+
__sub: (other) =>
15+
@@ (@r - other.r), (@i - other.i)
16+
17+
__mul: (other) =>
18+
a = @r * other.r - @i * other.i
19+
b = @i * other.r + @r * other.i
20+
@@ a, b
21+
22+
reciprocal: =>
23+
denom = @r^2 + @i^2
24+
@@ @r / denom, -@i / denom
25+
26+
__div: (other) => self * other\reciprocal!
27+
28+
exp: =>
29+
factor = math.exp(@r)
30+
@@ factor * math.cos(@i), factor * math.sin(@i)
31+
32+
__eq: (other) =>
33+
approx_equal = (a, b) -> math.abs(a - b) <= 1e-15
34+
approx_equal(@r, other.r) and approx_equal(@i, other.i)
35+
36+
37+
tocomplex = (a) -> if type(a) == 'number' then ComplexNumber a else a
38+
39+
add = (a, b) -> tocomplex(a) + tocomplex(b)
40+
sub = (a, b) -> tocomplex(a) - tocomplex(b)
41+
mul = (a, b) -> tocomplex(a) * tocomplex(b)
42+
div = (a, b) -> tocomplex(a) / tocomplex(b)
43+
44+
{ :ComplexNumber, :add, :sub, :mul, :div }
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
op = add: '+', sub: '-', mul: '*', div: '/'
2+
3+
cn = (z) ->
4+
switch type(z)
5+
when 'number' then z
6+
when 'table' then "ComplexNumber(#{z[1]}, #{z[2]})"
7+
8+
9+
require 'moon.all'
10+
{
11+
module_imports: {'ComplexNumber', 'add', 'sub', 'mul', 'div'},
12+
13+
test_helpers: [[
14+
pi = math.pi
15+
e = math.exp(1)
16+
ln = math.log
17+
]]
18+
19+
generate_test: (case, level) ->
20+
local lines
21+
switch case.property
22+
when 'real', 'imaginary', 'abs'
23+
lines = {
24+
"c = #{cn case.input.z}",
25+
"result = c\\#{case.property}!",
26+
"assert.are.equal #{case.expected}, result"
27+
}
28+
when 'add', 'sub', 'mul', 'div'
29+
if type(case.input.z1) == 'number' or type(case.input.z2) == 'number'
30+
lines = {
31+
"result = #{case.property} #{cn case.input.z1}, #{cn case.input.z2}",
32+
"expected = #{cn case.expected}",
33+
"assert.are.equal expected, result"
34+
}
35+
else
36+
lines = {
37+
"c1 = #{cn case.input.z1}",
38+
"c2 = #{cn case.input.z2}",
39+
"result = c1 #{op[case.property]} c2",
40+
"expected = #{cn case.expected}",
41+
"assert.are.equal expected, result"
42+
}
43+
when 'conjugate', 'exp'
44+
lines = {
45+
"c = #{cn case.input.z}",
46+
"result = c\\#{case.property}!",
47+
"expected = #{cn case.expected}",
48+
"assert.are.equal expected, result"
49+
}
50+
51+
table.concat [indent line, level for line in *lines], '\n'
52+
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# This is an auto-generated file.
2+
#
3+
# Regenerating this file via `configlet sync` will:
4+
# - Recreate every `description` key/value pair
5+
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
6+
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
7+
# - Preserve any other key/value pair
8+
#
9+
# As user-added comments (using the # character) will be removed when this file
10+
# is regenerated, comments can be added via a `comment` key.
11+
12+
[9f98e133-eb7f-45b0-9676-cce001cd6f7a]
13+
description = "Real part -> Real part of a purely real number"
14+
15+
[07988e20-f287-4bb7-90cf-b32c4bffe0f3]
16+
description = "Real part -> Real part of a purely imaginary number"
17+
18+
[4a370e86-939e-43de-a895-a00ca32da60a]
19+
description = "Real part -> Real part of a number with real and imaginary part"
20+
21+
[9b3fddef-4c12-4a99-b8f8-e3a42c7ccef6]
22+
description = "Imaginary part -> Imaginary part of a purely real number"
23+
24+
[a8dafedd-535a-4ed3-8a39-fda103a2b01e]
25+
description = "Imaginary part -> Imaginary part of a purely imaginary number"
26+
27+
[0f998f19-69ee-4c64-80ef-01b086feab80]
28+
description = "Imaginary part -> Imaginary part of a number with real and imaginary part"
29+
30+
[a39b7fd6-6527-492f-8c34-609d2c913879]
31+
description = "Imaginary unit"
32+
33+
[9a2c8de9-f068-4f6f-b41c-82232cc6c33e]
34+
description = "Arithmetic -> Addition -> Add purely real numbers"
35+
36+
[657c55e1-b14b-4ba7-bd5c-19db22b7d659]
37+
description = "Arithmetic -> Addition -> Add purely imaginary numbers"
38+
39+
[4e1395f5-572b-4ce8-bfa9-9a63056888da]
40+
description = "Arithmetic -> Addition -> Add numbers with real and imaginary part"
41+
42+
[1155dc45-e4f7-44b8-af34-a91aa431475d]
43+
description = "Arithmetic -> Subtraction -> Subtract purely real numbers"
44+
45+
[f95e9da8-acd5-4da4-ac7c-c861b02f774b]
46+
description = "Arithmetic -> Subtraction -> Subtract purely imaginary numbers"
47+
48+
[f876feb1-f9d1-4d34-b067-b599a8746400]
49+
description = "Arithmetic -> Subtraction -> Subtract numbers with real and imaginary part"
50+
51+
[8a0366c0-9e16-431f-9fd7-40ac46ff4ec4]
52+
description = "Arithmetic -> Multiplication -> Multiply purely real numbers"
53+
54+
[e560ed2b-0b80-4b4f-90f2-63cefc911aaf]
55+
description = "Arithmetic -> Multiplication -> Multiply purely imaginary numbers"
56+
57+
[4d1d10f0-f8d4-48a0-b1d0-f284ada567e6]
58+
description = "Arithmetic -> Multiplication -> Multiply numbers with real and imaginary part"
59+
60+
[b0571ddb-9045-412b-9c15-cd1d816d36c1]
61+
description = "Arithmetic -> Division -> Divide purely real numbers"
62+
63+
[5bb4c7e4-9934-4237-93cc-5780764fdbdd]
64+
description = "Arithmetic -> Division -> Divide purely imaginary numbers"
65+
66+
[c4e7fef5-64ac-4537-91c2-c6529707701f]
67+
description = "Arithmetic -> Division -> Divide numbers with real and imaginary part"
68+
69+
[c56a7332-aad2-4437-83a0-b3580ecee843]
70+
description = "Absolute value -> Absolute value of a positive purely real number"
71+
72+
[cf88d7d3-ee74-4f4e-8a88-a1b0090ecb0c]
73+
description = "Absolute value -> Absolute value of a negative purely real number"
74+
75+
[bbe26568-86c1-4bb4-ba7a-da5697e2b994]
76+
description = "Absolute value -> Absolute value of a purely imaginary number with positive imaginary part"
77+
78+
[3b48233d-468e-4276-9f59-70f4ca1f26f3]
79+
description = "Absolute value -> Absolute value of a purely imaginary number with negative imaginary part"
80+
81+
[fe400a9f-aa22-4b49-af92-51e0f5a2a6d3]
82+
description = "Absolute value -> Absolute value of a number with real and imaginary part"
83+
84+
[fb2d0792-e55a-4484-9443-df1eddfc84a2]
85+
description = "Complex conjugate -> Conjugate a purely real number"
86+
87+
[e37fe7ac-a968-4694-a460-66cb605f8691]
88+
description = "Complex conjugate -> Conjugate a purely imaginary number"
89+
90+
[f7704498-d0be-4192-aaf5-a1f3a7f43e68]
91+
description = "Complex conjugate -> Conjugate a number with real and imaginary part"
92+
93+
[6d96d4c6-2edb-445b-94a2-7de6d4caaf60]
94+
description = "Complex exponential function -> Euler's identity/formula"
95+
96+
[2d2c05a0-4038-4427-a24d-72f6624aa45f]
97+
description = "Complex exponential function -> Exponential of 0"
98+
99+
[ed87f1bd-b187-45d6-8ece-7e331232c809]
100+
description = "Complex exponential function -> Exponential of a purely real number"
101+
102+
[08eedacc-5a95-44fc-8789-1547b27a8702]
103+
description = "Complex exponential function -> Exponential of a number with real and imaginary part"
104+
105+
[d2de4375-7537-479a-aa0e-d474f4f09859]
106+
description = "Complex exponential function -> Exponential resulting in a number with real and imaginary part"
107+
108+
[06d793bf-73bd-4b02-b015-3030b2c952ec]
109+
description = "Operations between real numbers and complex numbers -> Add real number to complex number"
110+
111+
[d77dbbdf-b8df-43f6-a58d-3acb96765328]
112+
description = "Operations between real numbers and complex numbers -> Add complex number to real number"
113+
114+
[20432c8e-8960-4c40-ba83-c9d910ff0a0f]
115+
description = "Operations between real numbers and complex numbers -> Subtract real number from complex number"
116+
117+
[b4b38c85-e1bf-437d-b04d-49bba6e55000]
118+
description = "Operations between real numbers and complex numbers -> Subtract complex number from real number"
119+
120+
[dabe1c8c-b8f4-44dd-879d-37d77c4d06bd]
121+
description = "Operations between real numbers and complex numbers -> Multiply complex number by real number"
122+
123+
[6c81b8c8-9851-46f0-9de5-d96d314c3a28]
124+
description = "Operations between real numbers and complex numbers -> Multiply real number by complex number"
125+
126+
[8a400f75-710e-4d0c-bcb4-5e5a00c78aa0]
127+
description = "Operations between real numbers and complex numbers -> Divide complex number by real number"
128+
129+
[9a867d1b-d736-4c41-a41e-90bd148e9d5e]
130+
description = "Operations between real numbers and complex numbers -> Divide real number by complex number"

0 commit comments

Comments
 (0)