trackler 2.2.1.49 → 2.2.1.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/verify-configs +1 -1
- data/lib/trackler/version.rb +1 -1
- data/problem-specifications/exercises/kindergarten-garden/canonical-data.json +0 -37
- data/tracks/c/exercises/allergies/test/test_allergies.c +41 -41
- data/tracks/common-lisp/config.json +266 -252
- data/tracks/common-lisp/config/maintainers.json +23 -23
- data/tracks/common-lisp/exercises/allergies/README.md +0 -1
- data/tracks/common-lisp/exercises/atbash-cipher/README.md +2 -1
- data/tracks/common-lisp/exercises/beer-song/README.md +1 -1
- data/tracks/common-lisp/exercises/binary/README.md +2 -0
- data/tracks/common-lisp/exercises/collatz-conjecture/README.md +4 -8
- data/tracks/common-lisp/exercises/crypto-square/README.md +4 -4
- data/tracks/common-lisp/exercises/etl/README.md +2 -0
- data/tracks/common-lisp/exercises/grade-school/README.md +0 -1
- data/tracks/common-lisp/exercises/grains/README.md +0 -1
- data/tracks/common-lisp/exercises/leap/README.md +1 -1
- data/tracks/common-lisp/exercises/meetup/README.md +1 -2
- data/tracks/common-lisp/exercises/nucleotide-count/README.md +8 -22
- data/tracks/common-lisp/exercises/pascals-triangle/README.md +1 -1
- data/tracks/common-lisp/exercises/perfect-numbers/README.md +3 -4
- data/tracks/common-lisp/exercises/phone-number/README.md +3 -2
- data/tracks/common-lisp/exercises/roman-numerals/README.md +1 -1
- data/tracks/common-lisp/exercises/scrabble-score/README.md +3 -1
- data/tracks/common-lisp/exercises/space-age/README.md +2 -1
- data/tracks/common-lisp/exercises/sublist/README.md +65 -0
- data/tracks/common-lisp/exercises/sublist/example.lisp +24 -0
- data/tracks/common-lisp/exercises/sublist/sublist-test.lisp +87 -0
- data/tracks/common-lisp/exercises/sublist/sublist.lisp +8 -0
- data/tracks/common-lisp/exercises/triangle/README.md +9 -6
- data/tracks/common-lisp/exercises/trinary/README.md +1 -1
- data/tracks/common-lisp/exercises/word-count/README.md +1 -2
- data/tracks/ecmascript/config.json +30 -0
- data/tracks/ecmascript/exercises/bowling/README.md +80 -0
- data/tracks/ecmascript/exercises/bowling/bowling.spec.js +159 -0
- data/tracks/ecmascript/exercises/bowling/example.js +67 -0
- data/tracks/ecmascript/exercises/bowling/package.json +71 -0
- data/tracks/ecmascript/exercises/two-fer/README.md +47 -0
- data/tracks/ecmascript/exercises/two-fer/example.js +4 -0
- data/tracks/ecmascript/exercises/two-fer/package.json +69 -0
- data/tracks/ecmascript/exercises/two-fer/two-fer.spec.js +18 -0
- data/tracks/fsharp/exercises/pascals-triangle/Example.fs +12 -8
- data/tracks/fsharp/exercises/pascals-triangle/PascalsTriangle.fs +2 -2
- data/tracks/fsharp/exercises/pascals-triangle/PascalsTriangleTest.fs +15 -12
- data/tracks/fsharp/generators/Generators.fs +19 -0
- data/tracks/fsharp/generators/Templates/_AssertThrows.liquid +1 -0
- data/tracks/java/docs/ABOUT.md +13 -31
- data/tracks/java/exercises/bracket-push/.meta/version +1 -1
- data/tracks/java/exercises/bracket-push/src/test/java/BracketCheckerTest.java +7 -1
- data/tracks/java/exercises/collatz-conjecture/.meta/version +1 -1
- data/tracks/java/exercises/etl/README.md +1 -1
- data/tracks/java/exercises/ocr-numbers/README.md +1 -1
- data/tracks/java/exercises/pascals-triangle/README.md +1 -1
- data/tracks/java/exercises/perfect-numbers/.meta/version +1 -1
- data/tracks/java/exercises/rna-transcription/README.md +1 -1
- data/tracks/java/exercises/secret-handshake/.meta/version +1 -1
- data/tracks/java/exercises/secret-handshake/src/test/java/HandshakeCalculatorTest.java +1 -9
- data/tracks/java/scripts/canonical_data_check.sh +104 -0
- data/tracks/javascript/exercises/twelve-days/example.js +23 -25
- data/tracks/julia/.travis.yml +1 -0
- data/tracks/kotlin/exercises/all-your-base/.meta/version +1 -0
- data/tracks/kotlin/exercises/all-your-base/src/test/kotlin/BaseConverterTest.kt +0 -3
- data/tracks/kotlin/exercises/change/.meta/version +1 -0
- data/tracks/kotlin/exercises/change/src/test/kotlin/ChangeCalculatorTest.kt +0 -3
- data/tracks/kotlin/exercises/clock/.meta/version +1 -0
- data/tracks/kotlin/exercises/clock/src/test/kotlin/ClockAddTest.kt +1 -4
- data/tracks/kotlin/exercises/clock/src/test/kotlin/ClockCreationTest.kt +1 -4
- data/tracks/kotlin/exercises/clock/src/test/kotlin/ClockEqualTest.kt +1 -4
- data/tracks/kotlin/exercises/collatz-conjecture/.meta/version +1 -0
- data/tracks/kotlin/exercises/collatz-conjecture/src/test/kotlin/CollatzCalculatorTest.kt +0 -3
- data/tracks/kotlin/exercises/complex-numbers/.meta/version +1 -0
- data/tracks/kotlin/exercises/complex-numbers/src/test/kotlin/ComplexNumberTest.kt +0 -3
- data/tracks/kotlin/exercises/diamond/.meta/version +1 -0
- data/tracks/kotlin/exercises/diamond/src/test/kotlin/DiamondPrinterTest.kt +0 -3
- data/tracks/kotlin/exercises/etl/README.md +1 -1
- data/tracks/kotlin/exercises/forth/.meta/version +1 -0
- data/tracks/kotlin/exercises/forth/src/test/kotlin/ForthEvaluatorTest.kt +0 -3
- data/tracks/kotlin/exercises/grains/.meta/version +1 -0
- data/tracks/kotlin/exercises/grains/src/test/kotlin/BoardTest.kt +0 -3
- data/tracks/kotlin/exercises/hamming/.meta/version +1 -0
- data/tracks/kotlin/exercises/hamming/src/test/kotlin/HammingTest.kt +0 -3
- data/tracks/kotlin/exercises/list-ops/.meta/version +1 -0
- data/tracks/kotlin/exercises/list-ops/src/test/kotlin/ListExtensionsTest.kt +0 -3
- data/tracks/kotlin/exercises/meetup/.meta/version +1 -0
- data/tracks/kotlin/exercises/meetup/src/test/kotlin/MeetupTest.kt +0 -3
- data/tracks/kotlin/exercises/minesweeper/.meta/version +1 -0
- data/tracks/kotlin/exercises/minesweeper/src/test/kotlin/MinesweeperBoardTest.kt +0 -3
- data/tracks/kotlin/exercises/pangram/.meta/version +1 -0
- data/tracks/kotlin/exercises/pangram/src/test/kotlin/PangramTest.kt +0 -3
- data/tracks/kotlin/exercises/pascals-triangle/README.md +1 -1
- data/tracks/kotlin/exercises/prime-factors/.meta/version +1 -0
- data/tracks/kotlin/exercises/prime-factors/src/test/kotlin/PrimeFactorCalculatorTest.kt +0 -3
- data/tracks/kotlin/exercises/rna-transcription/.meta/version +1 -0
- data/tracks/kotlin/exercises/rna-transcription/README.md +1 -1
- data/tracks/kotlin/exercises/rna-transcription/src/test/kotlin/RnaTranscriptionTest.kt +0 -3
- data/tracks/kotlin/exercises/robot-simulator/.meta/version +1 -0
- data/tracks/kotlin/exercises/robot-simulator/src/test/kotlin/RobotTest.kt +0 -3
- data/tracks/kotlin/exercises/rotational-cipher/.meta/version +1 -0
- data/tracks/kotlin/exercises/rotational-cipher/src/test/kotlin/RotationalCipherTest.kt +0 -3
- data/tracks/kotlin/exercises/saddle-points/.meta/version +1 -0
- data/tracks/kotlin/exercises/saddle-points/src/test/kotlin/MatrixTest.kt +0 -3
- data/tracks/kotlin/exercises/say/.meta/version +1 -0
- data/tracks/kotlin/exercises/say/src/test/kotlin/NumberSpellerTest.kt +0 -3
- data/tracks/kotlin/exercises/secret-handshake/.meta/version +1 -0
- data/tracks/kotlin/exercises/secret-handshake/src/test/kotlin/HandshakeCalculatorTest.kt +0 -3
- data/tracks/kotlin/exercises/spiral-matrix/.meta/version +1 -0
- data/tracks/kotlin/exercises/spiral-matrix/src/test/kotlin/SpiralMatrixTest.kt +0 -3
- data/tracks/kotlin/exercises/sublist/.meta/version +1 -0
- data/tracks/kotlin/exercises/sublist/src/test/kotlin/SublistTest.kt +0 -3
- data/tracks/kotlin/scripts/canonical_data_check.sh +104 -0
- data/tracks/perl6/exercises/accumulate/accumulate.t +2 -3
- data/tracks/perl6/exercises/all-your-base/all-your-base.t +17 -18
- data/tracks/perl6/exercises/allergies/allergies.t +17 -18
- data/tracks/perl6/exercises/anagram/anagram.t +17 -18
- data/tracks/perl6/exercises/atbash-cipher/atbash-cipher.t +17 -18
- data/tracks/perl6/exercises/bob/bob.t +20 -22
- data/tracks/perl6/exercises/bob/example.yaml +1 -2
- data/tracks/perl6/exercises/clock/clock.t +17 -18
- data/tracks/perl6/exercises/flatten-array/flatten-array.t +17 -18
- data/tracks/perl6/exercises/grade-school/grade-school.t +2 -3
- data/tracks/perl6/exercises/grains/grains.t +17 -18
- data/tracks/perl6/exercises/hello-world/example.yaml +1 -2
- data/tracks/perl6/exercises/hello-world/hello-world.t +20 -22
- data/tracks/perl6/exercises/leap/leap.t +17 -18
- data/tracks/perl6/exercises/linked-list/linked-list.t +2 -3
- data/tracks/perl6/exercises/luhn/luhn.t +17 -18
- data/tracks/perl6/exercises/phone-number/phone-number.t +17 -18
- data/tracks/perl6/exercises/raindrops/raindrops.t +17 -18
- data/tracks/perl6/exercises/rna-transcription/rna-transcription.t +17 -18
- data/tracks/perl6/exercises/robot-name/robot-name.t +2 -3
- data/tracks/perl6/exercises/scrabble-score/scrabble-score.t +17 -18
- data/tracks/perl6/exercises/space-age/space-age.t +17 -18
- data/tracks/perl6/exercises/word-count/word-count.t +17 -18
- data/tracks/perl6/exercises/wordy/wordy.t +17 -18
- data/tracks/perl6/templates/test.mustache +9 -10
- data/tracks/purescript/config.json +11 -0
- data/tracks/purescript/exercises/rna-transcription/README.md +25 -0
- data/tracks/purescript/exercises/rna-transcription/bower.json +26 -0
- data/tracks/purescript/exercises/rna-transcription/examples/src/RNATranscription.purs +18 -0
- data/tracks/purescript/exercises/rna-transcription/src/RNATranscription.purs +3 -0
- data/tracks/purescript/exercises/rna-transcription/test/Main.purs +48 -0
- data/tracks/python/exercises/variable-length-quantity/example.py +6 -6
- data/tracks/python/exercises/variable-length-quantity/variable_length_quantity.py +2 -2
- data/tracks/ruby/config.json +6 -0
- data/tracks/ruby/exercises/complex-numbers/.meta/.version +1 -0
- data/tracks/ruby/exercises/complex-numbers/.meta/generator/complex_numbers_case.rb +44 -0
- data/tracks/ruby/exercises/complex-numbers/.meta/solutions/complex_numbers.rb +49 -0
- data/tracks/ruby/exercises/complex-numbers/README.md +64 -0
- data/tracks/ruby/exercises/complex-numbers/complex_numbers_test.rb +207 -0
- data/tracks/ruby/exercises/crypto-square/.meta/.version +1 -0
- data/tracks/ruby/exercises/crypto-square/.meta/generator/crypto_square_case.rb +19 -0
- data/tracks/ruby/exercises/crypto-square/.meta/solutions/crypto_square.rb +20 -15
- data/tracks/ruby/exercises/crypto-square/README.md +10 -8
- data/tracks/ruby/exercises/crypto-square/crypto_square_test.rb +45 -81
- data/tracks/ruby/exercises/flatten-array/.meta/.version +1 -0
- data/tracks/ruby/exercises/flatten-array/.meta/generator/flatten_array_case.rb +11 -0
- data/tracks/ruby/exercises/flatten-array/.meta/solutions/flatten_array.rb +5 -2
- data/tracks/ruby/exercises/flatten-array/flatten_array_test.rb +32 -7
- data/tracks/ruby/exercises/hamming/hamming_test.rb +3 -3
- data/tracks/ruby/exercises/isogram/isogram_test.rb +4 -4
- data/tracks/ruby/exercises/leap/leap_test.rb +2 -2
- data/tracks/ruby/exercises/pig-latin/.meta/.version +1 -1
- data/tracks/ruby/exercises/pig-latin/.meta/solutions/pig_latin.rb +2 -2
- data/tracks/ruby/exercises/pig-latin/pig_latin_test.rb +17 -7
- data/tracks/ruby/exercises/queen-attack/.meta/generator/queen_attack_case.rb +1 -1
- data/tracks/ruby/exercises/queen-attack/queen_attack_test.rb +7 -7
- data/tracks/ruby/exercises/sum-of-multiples/.meta/.version +1 -1
- data/tracks/ruby/exercises/sum-of-multiples/.meta/solutions/sum_of_multiples.rb +1 -1
- data/tracks/ruby/exercises/sum-of-multiples/sum_of_multiples_test.rb +7 -2
- metadata +53 -2
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "rna-transcription",
|
|
3
|
+
"ignore": [
|
|
4
|
+
"**/.*",
|
|
5
|
+
"node_modules",
|
|
6
|
+
"bower_components",
|
|
7
|
+
"output"
|
|
8
|
+
],
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"purescript-console": "^3.0.0",
|
|
11
|
+
"purescript-datetime": "^3.4.0",
|
|
12
|
+
"purescript-either": "^3.1.0",
|
|
13
|
+
"purescript-enums": "^3.2.1",
|
|
14
|
+
"purescript-integers": "^3.1.0",
|
|
15
|
+
"purescript-lists": "^4.10.0",
|
|
16
|
+
"purescript-maps": "^3.5.2",
|
|
17
|
+
"purescript-prelude": "^3.1.0",
|
|
18
|
+
"purescript-sets": "^3.0.0",
|
|
19
|
+
"purescript-strings": "^3.3.1",
|
|
20
|
+
"purescript-unicode": "^3.0.1"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"purescript-psci-support": "^3.0.0",
|
|
24
|
+
"purescript-test-unit": "^13.0.0"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module RNATranscription
|
|
2
|
+
( toRNA
|
|
3
|
+
) where
|
|
4
|
+
|
|
5
|
+
import Prelude
|
|
6
|
+
import Data.Maybe (Maybe(..))
|
|
7
|
+
import Data.String (fromCharArray, toCharArray)
|
|
8
|
+
import Data.Traversable (traverse)
|
|
9
|
+
|
|
10
|
+
toRNA :: String -> Maybe String
|
|
11
|
+
toRNA dna = fromCharArray <$> traverse complement (toCharArray dna)
|
|
12
|
+
|
|
13
|
+
complement :: Char -> Maybe Char
|
|
14
|
+
complement 'C' = Just 'G'
|
|
15
|
+
complement 'G' = Just 'C'
|
|
16
|
+
complement 'A' = Just 'U'
|
|
17
|
+
complement 'T' = Just 'A'
|
|
18
|
+
complement _ = Nothing
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module Test.Main where
|
|
2
|
+
|
|
3
|
+
import Prelude
|
|
4
|
+
import Control.Monad.Eff (Eff)
|
|
5
|
+
import Control.Monad.Eff.AVar (AVAR)
|
|
6
|
+
import Control.Monad.Eff.Console (CONSOLE)
|
|
7
|
+
import Data.Maybe (Maybe(..))
|
|
8
|
+
import Test.Unit (TestSuite, suite, test)
|
|
9
|
+
import Test.Unit.Assert as Assert
|
|
10
|
+
import Test.Unit.Console (TESTOUTPUT)
|
|
11
|
+
import Test.Unit.Main (runTest)
|
|
12
|
+
import RNATranscription (toRNA)
|
|
13
|
+
|
|
14
|
+
main :: forall eff
|
|
15
|
+
. Eff ( avar :: AVAR
|
|
16
|
+
, console :: CONSOLE
|
|
17
|
+
, testOutput :: TESTOUTPUT
|
|
18
|
+
| eff
|
|
19
|
+
)
|
|
20
|
+
Unit
|
|
21
|
+
main = runTest suites
|
|
22
|
+
|
|
23
|
+
suites :: forall e. TestSuite e
|
|
24
|
+
suites =
|
|
25
|
+
suite "RNATranscription.toRNA" do
|
|
26
|
+
test "RNA complement of cytosine is guanine" $
|
|
27
|
+
Assert.equal (Just "G") (toRNA "C")
|
|
28
|
+
|
|
29
|
+
test "RNA complement of guanine is cytosine" $
|
|
30
|
+
Assert.equal (Just "C") (toRNA "G")
|
|
31
|
+
|
|
32
|
+
test "RNA complement of thymine is adenine" $
|
|
33
|
+
Assert.equal (Just "A") (toRNA "T")
|
|
34
|
+
|
|
35
|
+
test "RNA complement of adenine is uracil" $
|
|
36
|
+
Assert.equal (Just "U") (toRNA "A")
|
|
37
|
+
|
|
38
|
+
test "RNA complement" $
|
|
39
|
+
Assert.equal (Just "UGCACCAGAAUU") (toRNA "ACGTGGTCTTAA")
|
|
40
|
+
|
|
41
|
+
test "correctly handles invalid input (RNA instead of DNA)" $
|
|
42
|
+
Assert.equal Nothing (toRNA "U")
|
|
43
|
+
|
|
44
|
+
test "correctly handles completely invalid DNA input" $
|
|
45
|
+
Assert.equal Nothing (toRNA "XXX")
|
|
46
|
+
|
|
47
|
+
test "correctly handles partially invalid DNA input" $
|
|
48
|
+
Assert.equal Nothing (toRNA "ACGTXXXCTTAA")
|
|
@@ -3,32 +3,32 @@ SEVENBITSMASK = 0x7f
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
def encode_single(n):
|
|
6
|
-
|
|
6
|
+
bytes_ = [n & SEVENBITSMASK]
|
|
7
7
|
n >>= 7
|
|
8
8
|
|
|
9
9
|
while n > 0:
|
|
10
|
-
|
|
10
|
+
bytes_.append(n & SEVENBITSMASK | EIGHTBITMASK)
|
|
11
11
|
n >>= 7
|
|
12
12
|
|
|
13
|
-
return
|
|
13
|
+
return bytes_[::-1]
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
def encode(numbers):
|
|
17
17
|
return sum((encode_single(n) for n in numbers), [])
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
def decode(
|
|
20
|
+
def decode(bytes_):
|
|
21
21
|
values = []
|
|
22
22
|
n = 0
|
|
23
23
|
|
|
24
|
-
for i, byte in enumerate(
|
|
24
|
+
for i, byte in enumerate(bytes_):
|
|
25
25
|
n <<= 7
|
|
26
26
|
n += (byte & SEVENBITSMASK)
|
|
27
27
|
|
|
28
28
|
if byte & EIGHTBITMASK == 0:
|
|
29
29
|
values.append(n)
|
|
30
30
|
n = 0
|
|
31
|
-
elif i == len(
|
|
31
|
+
elif i == len(bytes_) - 1:
|
|
32
32
|
raise ValueError('incomplete byte sequence')
|
|
33
33
|
|
|
34
34
|
return values
|
data/tracks/ruby/config.json
CHANGED
|
@@ -895,6 +895,12 @@
|
|
|
895
895
|
"uuid": "89bd3d71-000f-4cd9-9a84-ad1b22ddbd33",
|
|
896
896
|
"slug": "point-mutations",
|
|
897
897
|
"deprecated": true
|
|
898
|
+
},
|
|
899
|
+
{
|
|
900
|
+
"uuid": "4ca1322e-0c39-1e80-91e9-6b3f9ccf894f9058490",
|
|
901
|
+
"slug": "complex-numbers",
|
|
902
|
+
"difficulty": 3,
|
|
903
|
+
"topics": [ "Mathematics" ]
|
|
898
904
|
}
|
|
899
905
|
],
|
|
900
906
|
"foregone": [
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require 'generator/exercise_case'
|
|
2
|
+
|
|
3
|
+
class ComplexNumbersCase < Generator::ExerciseCase
|
|
4
|
+
|
|
5
|
+
def workload
|
|
6
|
+
indent_text(4, testcase)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def number
|
|
10
|
+
(respond_to? :input) ? input : z1
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def operation
|
|
14
|
+
case property
|
|
15
|
+
when "add" then " + #{construct_complex(z2)}"
|
|
16
|
+
when "sub" then " - #{construct_complex(z2)}"
|
|
17
|
+
when "mul" then " * #{construct_complex(z2)}"
|
|
18
|
+
when "div" then " / #{construct_complex(z2)}"
|
|
19
|
+
else ".#{property}"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def testcase
|
|
24
|
+
"expected = #{expected_value}\n" +
|
|
25
|
+
"assert_equal expected, #{construct_complex(number)}#{operation}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def construct_complex(value)
|
|
29
|
+
"ComplexNumber.new(#{parse_number(value)})"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def expected_value
|
|
33
|
+
(expected.is_a? Numeric) ? expected : construct_complex(expected)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def parse_number(number)
|
|
37
|
+
return number if number.is_a? Numeric
|
|
38
|
+
Array(number).map do |elem|
|
|
39
|
+
(elem.is_a? Numeric) ? elem.to_s : "Math::#{elem.upcase}"
|
|
40
|
+
end.join(", ")
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
class ComplexNumber
|
|
2
|
+
attr_reader :real, :imaginary
|
|
3
|
+
|
|
4
|
+
def initialize(real, imaginary = 0)
|
|
5
|
+
@real = real
|
|
6
|
+
@imaginary = imaginary
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def ==(other)
|
|
10
|
+
(self - other).abs < 1e-15
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def +(other)
|
|
14
|
+
self.class.new(@real + other.real, @imaginary + other.imaginary)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def -(other)
|
|
18
|
+
self.class.new(@real - other.real, @imaginary - other.imaginary)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def *(other)
|
|
22
|
+
self.class.new(@real * other.real - @imaginary * other.imaginary,
|
|
23
|
+
@real * other.imaginary + @imaginary * other.real)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def /(other)
|
|
27
|
+
self*other.inv
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def abs
|
|
31
|
+
Math.sqrt((self*self.conjugate).real)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def conjugate
|
|
35
|
+
self.class.new(@real, -@imaginary)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def inv
|
|
39
|
+
self.class.new(@real / abs**2, -@imaginary / abs**2)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def exp
|
|
43
|
+
self.class.new(Math.exp(@real)) * self.class.new(Math.cos(@imaginary), Math.sin(@imaginary))
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
module BookKeeping
|
|
48
|
+
VERSION = 1
|
|
49
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Complex Numbers
|
|
2
|
+
|
|
3
|
+
A complex number is a number in the form `z = a + b * i` where `a` and `b` are real and `i` satisfies `i^2 = -1`.
|
|
4
|
+
|
|
5
|
+
`a` is called the real part and `b` is called the imaginary part of `z`.
|
|
6
|
+
The conjugate of the number `a + b * i` is the number `a - b * i`.
|
|
7
|
+
The absolute value of a complex number `z = a + b * i` is a real number `|z| = sqrt(a^2 + b^2)`. The square of the absolute value `|z|^2` is the result of multiplication of `z` by its complex conjugate.
|
|
8
|
+
|
|
9
|
+
The sum / difference of two complex numbers involves adding / subtracting their real and imaginary parts separately:
|
|
10
|
+
`(a + i * b) + (c + i * d) = (a + c) + (b + d) * i`,
|
|
11
|
+
`(a + i * b) - (c + i * d) = (a - c) + (b - d) * i`.
|
|
12
|
+
|
|
13
|
+
Multiplication result is by definition
|
|
14
|
+
`(a + i * b) * (c + i * d) = (a * c - b * d) + (b * c + a * d) * i`.
|
|
15
|
+
|
|
16
|
+
The reciprocal of a non-zero complex number is
|
|
17
|
+
`1 / (a + i * b) = a/(a^2 + b^2) - b/(a^2 + b^2) * i`.
|
|
18
|
+
|
|
19
|
+
Dividing a complex number `a + i * b` by another `c + i * d` gives:
|
|
20
|
+
`(a + i * b) / (c + i * d) = (a * c + b * d)/(c^2 + d^2) + (b * c - a * d)/(c^2 + d^2) * i`.
|
|
21
|
+
|
|
22
|
+
Exponent of a complex number can be expressed as
|
|
23
|
+
`exp(a + i * b) = exp(a) * exp(i * b)`,
|
|
24
|
+
and the last term is given by Euler's formula `exp(i * b) = cos(b) + i * sin(b)`.
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
Implement the following operations:
|
|
28
|
+
- addition, subtraction, multiplication and division of two complex numbers,
|
|
29
|
+
- conjugate, absolute value, exponent of a given complex number.
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
Assume the programming language you are using does not have an implementation of complex numbers.
|
|
33
|
+
|
|
34
|
+
* * * *
|
|
35
|
+
|
|
36
|
+
For installation and learning resources, refer to the
|
|
37
|
+
[exercism help page](http://exercism.io/languages/ruby).
|
|
38
|
+
|
|
39
|
+
For running the tests provided, you will need the Minitest gem. Open a
|
|
40
|
+
terminal window and run the following command to install minitest:
|
|
41
|
+
|
|
42
|
+
gem install minitest
|
|
43
|
+
|
|
44
|
+
If you would like color output, you can `require 'minitest/pride'` in
|
|
45
|
+
the test file, or note the alternative instruction, below, for running
|
|
46
|
+
the test file.
|
|
47
|
+
|
|
48
|
+
In order to run the test, you can run the test file from the exercise
|
|
49
|
+
directory. For example, if the test suite is called
|
|
50
|
+
`hello_world_test.rb`, you can run the following command:
|
|
51
|
+
|
|
52
|
+
ruby hello_world_test.rb
|
|
53
|
+
|
|
54
|
+
To include color from the command line:
|
|
55
|
+
|
|
56
|
+
ruby -r minitest/pride hello_world_test.rb
|
|
57
|
+
|
|
58
|
+
## Source
|
|
59
|
+
|
|
60
|
+
Wikipedia [https://en.wikipedia.org/wiki/Complex_number](https://en.wikipedia.org/wiki/Complex_number)
|
|
61
|
+
|
|
62
|
+
## Submitting Incomplete Solutions
|
|
63
|
+
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
64
|
+
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
require 'minitest/autorun'
|
|
2
|
+
require_relative 'complex_numbers'
|
|
3
|
+
|
|
4
|
+
# Common test data version: 1.0.0 '117d062'
|
|
5
|
+
class ComplexNumbersTest < Minitest::Test
|
|
6
|
+
def test_imaginary_unit
|
|
7
|
+
# skip
|
|
8
|
+
expected = ComplexNumber.new(-1, 0)
|
|
9
|
+
assert_equal expected, ComplexNumber.new(0, 1) * ComplexNumber.new(0, 1)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_add_purely_real_numbers
|
|
13
|
+
skip
|
|
14
|
+
expected = ComplexNumber.new(3, 0)
|
|
15
|
+
assert_equal expected, ComplexNumber.new(1, 0) + ComplexNumber.new(2, 0)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def test_add_purely_imaginary_numbers
|
|
19
|
+
skip
|
|
20
|
+
expected = ComplexNumber.new(0, 3)
|
|
21
|
+
assert_equal expected, ComplexNumber.new(0, 1) + ComplexNumber.new(0, 2)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def test_add_numbers_with_real_and_imaginary_part
|
|
25
|
+
skip
|
|
26
|
+
expected = ComplexNumber.new(4, 6)
|
|
27
|
+
assert_equal expected, ComplexNumber.new(1, 2) + ComplexNumber.new(3, 4)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def test_subtract_purely_real_numbers
|
|
31
|
+
skip
|
|
32
|
+
expected = ComplexNumber.new(-1, 0)
|
|
33
|
+
assert_equal expected, ComplexNumber.new(1, 0) - ComplexNumber.new(2, 0)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_subtract_purely_imaginary_numbers
|
|
37
|
+
skip
|
|
38
|
+
expected = ComplexNumber.new(0, -1)
|
|
39
|
+
assert_equal expected, ComplexNumber.new(0, 1) - ComplexNumber.new(0, 2)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def test_subtract_numbers_with_real_and_imaginary_part
|
|
43
|
+
skip
|
|
44
|
+
expected = ComplexNumber.new(-2, -2)
|
|
45
|
+
assert_equal expected, ComplexNumber.new(1, 2) - ComplexNumber.new(3, 4)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def test_multiply_purely_real_numbers
|
|
49
|
+
skip
|
|
50
|
+
expected = ComplexNumber.new(2, 0)
|
|
51
|
+
assert_equal expected, ComplexNumber.new(1, 0) * ComplexNumber.new(2, 0)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def test_multiply_purely_imaginary_numbers
|
|
55
|
+
skip
|
|
56
|
+
expected = ComplexNumber.new(-2, 0)
|
|
57
|
+
assert_equal expected, ComplexNumber.new(0, 1) * ComplexNumber.new(0, 2)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def test_multiply_numbers_with_real_and_imaginary_part
|
|
61
|
+
skip
|
|
62
|
+
expected = ComplexNumber.new(-5, 10)
|
|
63
|
+
assert_equal expected, ComplexNumber.new(1, 2) * ComplexNumber.new(3, 4)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def test_divide_purely_real_numbers
|
|
67
|
+
skip
|
|
68
|
+
expected = ComplexNumber.new(0.5, 0)
|
|
69
|
+
assert_equal expected, ComplexNumber.new(1, 0) / ComplexNumber.new(2, 0)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def test_divide_purely_imaginary_numbers
|
|
73
|
+
skip
|
|
74
|
+
expected = ComplexNumber.new(0.5, 0)
|
|
75
|
+
assert_equal expected, ComplexNumber.new(0, 1) / ComplexNumber.new(0, 2)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def test_divide_numbers_with_real_and_imaginary_part
|
|
79
|
+
skip
|
|
80
|
+
expected = ComplexNumber.new(0.44, 0.08)
|
|
81
|
+
assert_equal expected, ComplexNumber.new(1, 2) / ComplexNumber.new(3, 4)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def test_absolute_value_of_a_positive_purely_real_number
|
|
85
|
+
skip
|
|
86
|
+
expected = 5
|
|
87
|
+
assert_equal expected, ComplexNumber.new(5, 0).abs
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def test_absolute_value_of_a_negative_purely_real_number
|
|
91
|
+
skip
|
|
92
|
+
expected = 5
|
|
93
|
+
assert_equal expected, ComplexNumber.new(-5, 0).abs
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def test_absolute_value_of_a_purely_imaginary_number_with_positive_imaginary_part
|
|
97
|
+
skip
|
|
98
|
+
expected = 5
|
|
99
|
+
assert_equal expected, ComplexNumber.new(0, 5).abs
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def test_absolute_value_of_a_purely_imaginary_number_with_negative_imaginary_part
|
|
103
|
+
skip
|
|
104
|
+
expected = 5
|
|
105
|
+
assert_equal expected, ComplexNumber.new(0, -5).abs
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def test_absolute_value_of_a_number_with_real_and_imaginary_part
|
|
109
|
+
skip
|
|
110
|
+
expected = 5
|
|
111
|
+
assert_equal expected, ComplexNumber.new(3, 4).abs
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def test_conjugate_a_purely_real_number
|
|
115
|
+
skip
|
|
116
|
+
expected = ComplexNumber.new(5, 0)
|
|
117
|
+
assert_equal expected, ComplexNumber.new(5, 0).conjugate
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def test_conjugate_a_purely_imaginary_number
|
|
121
|
+
skip
|
|
122
|
+
expected = ComplexNumber.new(0, -5)
|
|
123
|
+
assert_equal expected, ComplexNumber.new(0, 5).conjugate
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def test_conjugate_a_number_with_real_and_imaginary_part
|
|
127
|
+
skip
|
|
128
|
+
expected = ComplexNumber.new(1, -1)
|
|
129
|
+
assert_equal expected, ComplexNumber.new(1, 1).conjugate
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def test_real_part_of_a_purely_real_number
|
|
133
|
+
skip
|
|
134
|
+
expected = 1
|
|
135
|
+
assert_equal expected, ComplexNumber.new(1, 0).real
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def test_real_part_of_a_purely_imaginary_number
|
|
139
|
+
skip
|
|
140
|
+
expected = 0
|
|
141
|
+
assert_equal expected, ComplexNumber.new(0, 1).real
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def test_real_part_of_a_number_with_real_and_imaginary_part
|
|
145
|
+
skip
|
|
146
|
+
expected = 1
|
|
147
|
+
assert_equal expected, ComplexNumber.new(1, 2).real
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def test_imaginary_part_of_a_purely_real_number
|
|
151
|
+
skip
|
|
152
|
+
expected = 0
|
|
153
|
+
assert_equal expected, ComplexNumber.new(1, 0).imaginary
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def test_imaginary_part_of_a_purely_imaginary_number
|
|
157
|
+
skip
|
|
158
|
+
expected = 1
|
|
159
|
+
assert_equal expected, ComplexNumber.new(0, 1).imaginary
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def test_imaginary_part_of_a_number_with_real_and_imaginary_part
|
|
163
|
+
skip
|
|
164
|
+
expected = 2
|
|
165
|
+
assert_equal expected, ComplexNumber.new(1, 2).imaginary
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def test_eulers_identityformula
|
|
169
|
+
skip
|
|
170
|
+
expected = ComplexNumber.new(-1, 0)
|
|
171
|
+
assert_equal expected, ComplexNumber.new(0, Math::PI).exp
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def test_exponential_of_0
|
|
175
|
+
skip
|
|
176
|
+
expected = ComplexNumber.new(1, 0)
|
|
177
|
+
assert_equal expected, ComplexNumber.new(0, 0).exp
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def test_exponential_of_a_purely_real_number
|
|
181
|
+
skip
|
|
182
|
+
expected = ComplexNumber.new(Math::E, 0)
|
|
183
|
+
assert_equal expected, ComplexNumber.new(1, 0).exp
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# Problems in exercism evolve over time, as we find better ways to ask
|
|
187
|
+
# questions.
|
|
188
|
+
# The version number refers to the version of the problem you solved,
|
|
189
|
+
# not your solution.
|
|
190
|
+
#
|
|
191
|
+
# Define a constant named VERSION inside of the top level BookKeeping
|
|
192
|
+
# module, which may be placed near the end of your file.
|
|
193
|
+
#
|
|
194
|
+
# In your file, it will look like this:
|
|
195
|
+
#
|
|
196
|
+
# module BookKeeping
|
|
197
|
+
# VERSION = 1 # Where the version number matches the one in the test.
|
|
198
|
+
# end
|
|
199
|
+
#
|
|
200
|
+
# If you are curious, read more about constants on RubyDoc:
|
|
201
|
+
# http://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/constants.html
|
|
202
|
+
|
|
203
|
+
def test_bookkeeping
|
|
204
|
+
skip
|
|
205
|
+
assert_equal 1, BookKeeping::VERSION
|
|
206
|
+
end
|
|
207
|
+
end
|