trackler 2.0.6.34 → 2.0.6.35
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/common/exercises/change/canonical-data.json +6 -0
- data/common/exercises/luhn/canonical-data.json +35 -0
- data/common/exercises/rotational-cipher/cannonical-data.json +70 -0
- data/common/exercises/rotational-cipher/description.md +30 -0
- data/common/exercises/rotational-cipher/metadata.yml +4 -0
- data/common/exercises/run-length-encoding/description.md +7 -1
- data/lib/trackler/version.rb +1 -1
- data/tracks/elixir/exercises/run-length-encoding/example.exs +15 -4
- data/tracks/elixir/exercises/run-length-encoding/rle.exs +2 -2
- data/tracks/elixir/exercises/run-length-encoding/rle_test.exs +28 -11
- data/tracks/go/exercises/bob/bob_test.go +4 -1
- data/tracks/go/exercises/bracket-push/bracket_push_test.go +5 -2
- data/tracks/go/exercises/circular-buffer/circular_buffer_test.go +6 -6
- data/tracks/go/exercises/clock/clock_test.go +4 -1
- data/tracks/go/exercises/connect/connect_test.go +4 -1
- data/tracks/go/exercises/crypto-square/crypto_square_test.go +5 -2
- data/tracks/go/exercises/luhn/luhn_test.go +1 -1
- data/tracks/javascript/exercises/leap/leap.js +1 -1
- data/tracks/julia/.travis.yml +0 -2
- data/tracks/julia/config.json +41 -0
- data/tracks/julia/exercises/custom-set/HINTS.md +1 -0
- data/tracks/julia/exercises/custom-set/custom-set.jl +0 -0
- data/tracks/julia/exercises/custom-set/example.jl +51 -0
- data/tracks/julia/exercises/custom-set/runtests.jl +200 -0
- data/tracks/julia/exercises/isogram/example.jl +11 -0
- data/tracks/julia/exercises/isogram/isogram.jl +3 -0
- data/tracks/julia/exercises/isogram/runtests.jl +35 -0
- data/tracks/julia/exercises/luhn/example.jl +16 -0
- data/tracks/julia/exercises/luhn/luhn.jl +0 -0
- data/tracks/julia/exercises/luhn/runtests.jl +31 -0
- data/tracks/julia/exercises/nucleotide-count/example.jl +8 -0
- data/tracks/julia/exercises/nucleotide-count/nucleotide-count.jl +3 -0
- data/tracks/julia/exercises/nucleotide-count/runtests.jl +19 -0
- data/tracks/kotlin/.travis.yml +9 -1
- data/tracks/kotlin/README.md +117 -11
- data/tracks/kotlin/bin/journey-test.sh +279 -0
- data/tracks/kotlin/docs/INSTALLATION.md +193 -97
- data/tracks/kotlin/docs/TESTS.md +72 -137
- data/tracks/kotlin/exercises/hello-world/GETTING_STARTED.md +50 -0
- data/tracks/kotlin/exercises/hello-world/TUTORIAL.md +693 -0
- data/tracks/kotlin/exercises/hello-world/src/example/kotlin/HelloWorld.kt +2 -30
- data/tracks/kotlin/exercises/hello-world/src/main/kotlin/HelloWorld.kt +2 -30
- data/tracks/kotlin/exercises/hello-world/src/test/kotlin/HelloWorldTest.kt +11 -19
- data/tracks/objective-c/circle.yml +1 -1
- data/tracks/perl6/exercises/atbash-cipher/{cipher.t → atbash-cipher.t} +0 -0
- data/tracks/perl6/exercises/linked-list/linked-list.t +0 -0
- data/tracks/perl6/exercises/phone-number/{phone.t → phone-number.t} +0 -0
- data/tracks/perl6/exercises/rna-transcription/{rna_transcription.t → rna-transcription.t} +0 -0
- data/tracks/perl6/exercises/robot-name/{robot.t → robot-name.t} +0 -0
- data/tracks/perl6/exercises/scrabble-score/{scrabble_score.t → scrabble-score.t} +0 -0
- data/tracks/perl6/exercises/word-count/{word_count.t → word-count.t} +0 -0
- data/tracks/pony/config.json +9 -0
- data/tracks/pony/exercises/pascals-triangle/example.pony +18 -0
- data/tracks/pony/exercises/pascals-triangle/test.pony +31 -0
- data/tracks/r/config.json +20 -0
- data/tracks/r/exercises/grains/example.R +16 -0
- data/tracks/r/exercises/grains/grains.R +7 -0
- data/tracks/r/exercises/grains/test_grains.R +49 -0
- data/tracks/r/exercises/phone-number/example.R +30 -0
- data/tracks/r/exercises/phone-number/phone-number.R +3 -0
- data/tracks/r/exercises/phone-number/test_phone-number.R +44 -0
- data/tracks/r/exercises/secret-handshake/example.R +26 -0
- data/tracks/r/exercises/secret-handshake/secret-handshake.R +3 -0
- data/tracks/r/exercises/secret-handshake/test_secret-handshake.R +52 -0
- data/tracks/r/exercises/sieve/example.R +16 -0
- data/tracks/r/exercises/sieve/sieve.R +3 -0
- data/tracks/r/exercises/sieve/test_sieve.R +37 -0
- data/tracks/rust/config.json +11 -0
- data/tracks/rust/exercises/rotational-cipher/Cargo.lock +4 -0
- data/tracks/rust/exercises/rotational-cipher/Cargo.toml +4 -0
- data/tracks/rust/exercises/rotational-cipher/example.rs +16 -0
- data/tracks/rust/exercises/rotational-cipher/tests/rotational-cipher.rs +61 -0
- data/tracks/swift/circle.yml +6 -0
- metadata +46 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b60180d66cb803d7af0b313725e9f050d9dc61b0
|
4
|
+
data.tar.gz: cba72b210897ddba5ce87dc79ca7541e9615ab43
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cdaf21409803ea63c534daeca46434a8463f75b65a8e4a3908b924598786f69e90e4c7335b344ba48a60098215eac3c11ec510820e3f36081e1c9baddd23a8b7
|
7
|
+
data.tar.gz: a0b9a0e0ce5411a07b0a5e3221fcebe7da097c20cb83843fb3252d4c9d72f6a44d8861c7925eaf88738fcaff3011cf7e0141c82c38d7a7b2d0b5e45b1cc96bcd
|
@@ -48,6 +48,12 @@
|
|
48
48
|
"target": 3,
|
49
49
|
"expected": -1
|
50
50
|
},
|
51
|
+
{
|
52
|
+
"description": "error if no combination can add up to target",
|
53
|
+
"coins": [5, 10],
|
54
|
+
"target": 94,
|
55
|
+
"expected": -1
|
56
|
+
},
|
51
57
|
{
|
52
58
|
"description": "cannot find negative change values",
|
53
59
|
"coins": [1, 2, 5],
|
@@ -10,6 +10,11 @@
|
|
10
10
|
"input": "0",
|
11
11
|
"expected": false
|
12
12
|
},
|
13
|
+
{
|
14
|
+
"description": "simple valid sin",
|
15
|
+
"input": " 5 9 ",
|
16
|
+
"expected": true
|
17
|
+
},
|
13
18
|
{
|
14
19
|
"description": "valid Canadian SIN",
|
15
20
|
"input": "046 454 286",
|
@@ -29,6 +34,36 @@
|
|
29
34
|
"description": "valid strings with a non-digit added become invalid",
|
30
35
|
"input": "046a 454 286",
|
31
36
|
"expected": false
|
37
|
+
},
|
38
|
+
{
|
39
|
+
"description": "punctuation is not allowed",
|
40
|
+
"input": "055-444-285",
|
41
|
+
"expected": false
|
42
|
+
},
|
43
|
+
{
|
44
|
+
"description": "symbols are not allowed",
|
45
|
+
"input": "055£ 444$ 285",
|
46
|
+
"expected": false
|
47
|
+
},
|
48
|
+
{
|
49
|
+
"description": "single zero with space is invalid",
|
50
|
+
"input": " 0",
|
51
|
+
"expected": false
|
52
|
+
},
|
53
|
+
{
|
54
|
+
"description": "lots of zeros are valid",
|
55
|
+
"input": " 00000",
|
56
|
+
"expected": true
|
57
|
+
},
|
58
|
+
{
|
59
|
+
"description": "another valid sin",
|
60
|
+
"input": "055 444 285",
|
61
|
+
"expected": true
|
62
|
+
},
|
63
|
+
{
|
64
|
+
"description": "nine doubled is nine",
|
65
|
+
"input": "091",
|
66
|
+
"expected": true
|
32
67
|
}
|
33
68
|
]
|
34
69
|
}
|
@@ -0,0 +1,70 @@
|
|
1
|
+
{
|
2
|
+
"#": [
|
3
|
+
"The tests are a series of rotation tests: "
|
4
|
+
],
|
5
|
+
"rotate": {
|
6
|
+
"description": ["Test rotation from English to ROTn"],
|
7
|
+
"cases": [
|
8
|
+
{
|
9
|
+
"description": "rotate a by 1",
|
10
|
+
"text": "a",
|
11
|
+
"shift_key": 1,
|
12
|
+
"expected": "b"
|
13
|
+
},
|
14
|
+
{
|
15
|
+
"description": "rotate a by 26, same output as input",
|
16
|
+
"text": "a",
|
17
|
+
"shift_key": 26,
|
18
|
+
"expected": "a"
|
19
|
+
},
|
20
|
+
{
|
21
|
+
"description": "rotate a by 0, same output as input",
|
22
|
+
"text": "a",
|
23
|
+
"shift_key": 26,
|
24
|
+
"expected": "a"
|
25
|
+
},
|
26
|
+
{
|
27
|
+
"description": "rotate m by 13",
|
28
|
+
"text": "m",
|
29
|
+
"shift_key": 13,
|
30
|
+
"expected": "z"
|
31
|
+
},
|
32
|
+
{
|
33
|
+
"description": "rotate n by 13 with wrap around alphabet",
|
34
|
+
"text": "n",
|
35
|
+
"shift_key": 13,
|
36
|
+
"expected": "a"
|
37
|
+
},
|
38
|
+
{
|
39
|
+
"description": "rotate capital letters",
|
40
|
+
"text": "OMG",
|
41
|
+
"shift_key": 5,
|
42
|
+
"expected": "TRL"
|
43
|
+
},
|
44
|
+
{
|
45
|
+
"description": "rotate spaces",
|
46
|
+
"text": "O M G",
|
47
|
+
"shift_key": 5,
|
48
|
+
"expected": "T R L"
|
49
|
+
},
|
50
|
+
{
|
51
|
+
"description": "rotate numbers",
|
52
|
+
"text": "Testing 1 2 3 testing",
|
53
|
+
"shift_key": 4,
|
54
|
+
"expected": "Xiwxmrk 1 2 3 xiwxmrk"
|
55
|
+
},
|
56
|
+
{
|
57
|
+
"description": "rotate punctuation",
|
58
|
+
"text": "Let's eat, Grandma!",
|
59
|
+
"shift_key": 21,
|
60
|
+
"expected": "Gzo'n zvo, Bmviyhv!"
|
61
|
+
},
|
62
|
+
{
|
63
|
+
"description": "rotate all letters",
|
64
|
+
"text": "The quick brown fox jumps over the lazy dog.",
|
65
|
+
"shift_key": 13,
|
66
|
+
"expected": "Gur dhvpx oebja sbk whzcf bire gur ynml qbt."
|
67
|
+
}
|
68
|
+
]
|
69
|
+
}
|
70
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Rotational Cipher
|
2
|
+
|
3
|
+
Create an implementation of the rotational cipher, also sometimes called the Caesar cipher.
|
4
|
+
|
5
|
+
The Caesar cipher is a simple shift cipher that relies on
|
6
|
+
transposing all the letters in the alphabet using an integer key
|
7
|
+
between `0` and `26`. Using a key of `0` or `26` will always yield
|
8
|
+
the same output due to modular arithmetic. The letter is shifted
|
9
|
+
for as many values as the value of the key.
|
10
|
+
|
11
|
+
The general notation for rotational ciphers is `ROT + <key>`.
|
12
|
+
The most commonly used rotational cipher is `ROT13`.
|
13
|
+
|
14
|
+
A `ROT13` on the Latin alphabet would be as follows:
|
15
|
+
|
16
|
+
```plain
|
17
|
+
Plain: abcdefghijklmnopqrstuvwxyz
|
18
|
+
Cipher: nopqrstuvwxyzabcdefghijklm
|
19
|
+
```
|
20
|
+
|
21
|
+
It is stronger than the Atbash cipher because it has 27 possible keys, and 25 usable keys.
|
22
|
+
|
23
|
+
Ciphertext is written out in the same formatting as the input including spaces and punctuation.
|
24
|
+
|
25
|
+
## Examples
|
26
|
+
- ROT5 `omg` gives `trl`
|
27
|
+
- ROT0 `c` gives `c`
|
28
|
+
- ROT26 `Cool` gives `Cool`
|
29
|
+
- ROT13 `The quick brown fox jumps over the lazy dog.` gives `Gur dhvpx oebja sbk whzcf bire gur ynml qbt.`
|
30
|
+
- ROT13 `Gur dhvpx oebja sbk whzcf bire gur ynml qbt.` gives `The quick brown fox jumps over the lazy dog.`
|
@@ -14,5 +14,11 @@ the compressed data, which makes it a lossless data compression.
|
|
14
14
|
"AABCCCDEEEE" -> "2AB3CD4E" -> "AABCCCDEEEE"
|
15
15
|
```
|
16
16
|
|
17
|
+
If the string contains any whitespace, it should be passed through unchanged:
|
18
|
+
|
19
|
+
```
|
20
|
+
"aabc dddef" -> "2abc 3def"
|
21
|
+
```
|
22
|
+
|
17
23
|
For simplicity, you can assume that the unencoded string will only contain
|
18
|
-
the letters A through Z.
|
24
|
+
the letters A through Z (either lower or uppercase) and whitespace.
|
data/lib/trackler/version.rb
CHANGED
@@ -2,13 +2,24 @@ defmodule RunLengthEncoder do
|
|
2
2
|
|
3
3
|
@spec encode(String.t) :: String.t
|
4
4
|
def encode(string) do
|
5
|
-
Regex.scan(~r/([
|
6
|
-
|> Enum.map_join(fn([run, c]) ->
|
5
|
+
Regex.scan(~r/([a-zA-Z ])\1*/, string)
|
6
|
+
|> Enum.map_join(fn([run, c]) ->
|
7
|
+
if String.match?(run, ~r/\s+/) do
|
8
|
+
run
|
9
|
+
else
|
10
|
+
times = String.length(run)
|
11
|
+
number = if times == 1 do "" else times end
|
12
|
+
"#{number}#{c}"
|
13
|
+
end
|
14
|
+
end)
|
7
15
|
end
|
8
16
|
|
9
17
|
@spec decode(String.t) :: String.t
|
10
18
|
def decode(string) do
|
11
|
-
Regex.scan(~r/(\d
|
12
|
-
|> Enum.map_join(fn [_,n,c] ->
|
19
|
+
Regex.scan(~r/(\d*)(.)/, string)
|
20
|
+
|> Enum.map_join(fn [_,n,c] ->
|
21
|
+
times = if n == "" do 1 else String.to_integer(n) end
|
22
|
+
String.duplicate(c, times)
|
23
|
+
end)
|
13
24
|
end
|
14
25
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
defmodule RunLengthEncoder do
|
2
2
|
@doc """
|
3
3
|
Generates a string where consecutive elements are represented as a data value and count.
|
4
|
-
"
|
4
|
+
"AABBBCCCC" => "2A3B4C"
|
5
5
|
For this example, assume all input are strings, that are all uppercase letters.
|
6
6
|
It should also be able to reconstruct the data into its original form.
|
7
|
-
"
|
7
|
+
"2A3B4C" => "AABBBCCCC"
|
8
8
|
"""
|
9
9
|
@spec encode(String.t) :: String.t
|
10
10
|
def encode(string) do
|
@@ -8,32 +8,49 @@ ExUnit.configure exclude: :pending, trace: true
|
|
8
8
|
defmodule RunLengthEncoderTest do
|
9
9
|
use ExUnit.Case
|
10
10
|
|
11
|
-
test "empty string
|
11
|
+
test "encode empty string" do
|
12
12
|
assert RunLengthEncoder.encode("") === ""
|
13
13
|
end
|
14
14
|
|
15
15
|
@tag :pending
|
16
|
-
test "
|
17
|
-
assert RunLengthEncoder.encode("
|
16
|
+
test "encode single characters only" do
|
17
|
+
assert RunLengthEncoder.encode("XYZ") === "XYZ"
|
18
18
|
end
|
19
19
|
|
20
20
|
@tag :pending
|
21
|
-
test "
|
22
|
-
assert RunLengthEncoder.
|
21
|
+
test "decode empty string" do
|
22
|
+
assert RunLengthEncoder.decode("") === ""
|
23
23
|
end
|
24
24
|
|
25
25
|
@tag :pending
|
26
|
-
test "
|
27
|
-
assert RunLengthEncoder.
|
26
|
+
test "decode single characters only" do
|
27
|
+
assert RunLengthEncoder.decode("XYZ") === "XYZ"
|
28
28
|
end
|
29
29
|
|
30
30
|
@tag :pending
|
31
|
-
test "
|
32
|
-
assert RunLengthEncoder.
|
31
|
+
test "encode simple" do
|
32
|
+
assert RunLengthEncoder.encode("AABBBCCCC") == "2A3B4C"
|
33
33
|
end
|
34
34
|
|
35
35
|
@tag :pending
|
36
|
-
test "
|
37
|
-
assert RunLengthEncoder.decode("
|
36
|
+
test "decode simple" do
|
37
|
+
assert RunLengthEncoder.decode("2A3B4C") == "AABBBCCCC"
|
38
|
+
end
|
39
|
+
|
40
|
+
@tag :pending
|
41
|
+
test "encode with single values" do
|
42
|
+
assert RunLengthEncoder.encode("WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB") === "12WB12W3B24WB"
|
43
|
+
end
|
44
|
+
|
45
|
+
@tag :pending
|
46
|
+
test "decode with single values" do
|
47
|
+
assert RunLengthEncoder.decode("12WB12W3B24WB") === "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB"
|
48
|
+
end
|
49
|
+
|
50
|
+
@tag :pending
|
51
|
+
test "decode(encode(...)) combination" do
|
52
|
+
original = "zzz ZZ zZ"
|
53
|
+
encoded = RunLengthEncoder.encode(original)
|
54
|
+
assert RunLengthEncoder.decode(encoded) === original
|
38
55
|
end
|
39
56
|
end
|
@@ -4,10 +4,13 @@ import "testing"
|
|
4
4
|
|
5
5
|
const targetTestVersion = 2
|
6
6
|
|
7
|
-
func
|
7
|
+
func TestTestVersion(t *testing.T) {
|
8
8
|
if testVersion != targetTestVersion {
|
9
9
|
t.Fatalf("Found testVersion = %v, want %v", testVersion, targetTestVersion)
|
10
10
|
}
|
11
|
+
}
|
12
|
+
|
13
|
+
func TestHeyBob(t *testing.T) {
|
11
14
|
for _, tt := range testCases {
|
12
15
|
actual := Hey(tt.input)
|
13
16
|
if actual != tt.expected {
|
@@ -48,10 +48,13 @@ var testCases = []struct {
|
|
48
48
|
},
|
49
49
|
}
|
50
50
|
|
51
|
-
func
|
51
|
+
func TestTestVersion(t *testing.T) {
|
52
52
|
if testVersion != targetTestVersion {
|
53
|
-
t.Fatalf("Found testVersion = %v, want %v
|
53
|
+
t.Fatalf("Found testVersion = %v, want %v", testVersion, targetTestVersion)
|
54
54
|
}
|
55
|
+
}
|
56
|
+
|
57
|
+
func TestBracket(t *testing.T) {
|
55
58
|
for _, tt := range testCases {
|
56
59
|
actual, err := Bracket(tt.input)
|
57
60
|
// We don't expect errors for any of the test cases
|
@@ -21,12 +21,6 @@ import (
|
|
21
21
|
|
22
22
|
const targetTestVersion = 4
|
23
23
|
|
24
|
-
func TestTestVersion(t *testing.T) {
|
25
|
-
if testVersion != targetTestVersion {
|
26
|
-
t.Errorf("Found testVersion = %v, want %v.", testVersion, targetTestVersion)
|
27
|
-
}
|
28
|
-
}
|
29
|
-
|
30
24
|
// Here is one way you can have a test case verify that the expected
|
31
25
|
// interfaces are implemented.
|
32
26
|
|
@@ -94,6 +88,12 @@ func (tb testBuffer) overwrite(c byte) {
|
|
94
88
|
|
95
89
|
// tests. separate functions so log will have descriptive test name.
|
96
90
|
|
91
|
+
func TestTestVersion(t *testing.T) {
|
92
|
+
if testVersion != targetTestVersion {
|
93
|
+
t.Fatalf("Found testVersion = %v, want %v.", testVersion, targetTestVersion)
|
94
|
+
}
|
95
|
+
}
|
96
|
+
|
97
97
|
func TestReadEmptyBuffer(t *testing.T) {
|
98
98
|
tb := nb(1, t)
|
99
99
|
tb.readFail()
|
@@ -29,10 +29,13 @@ import (
|
|
29
29
|
|
30
30
|
const targetTestVersion = 4
|
31
31
|
|
32
|
-
func
|
32
|
+
func TestTestVersion(t *testing.T) {
|
33
33
|
if testVersion != targetTestVersion {
|
34
34
|
t.Fatalf("Found testVersion = %v, want %v", testVersion, targetTestVersion)
|
35
35
|
}
|
36
|
+
}
|
37
|
+
|
38
|
+
func TestCreateClock(t *testing.T) {
|
36
39
|
for _, n := range timeTests {
|
37
40
|
if got := New(n.h, n.m); got.String() != n.want {
|
38
41
|
t.Fatalf("New(%d, %d) = %q, want %q", n.h, n.m, got, n.want)
|
@@ -17,10 +17,13 @@ func prepare(lines []string) []string {
|
|
17
17
|
|
18
18
|
const targetTestVersion = 3
|
19
19
|
|
20
|
-
func
|
20
|
+
func TestTestVersion(t *testing.T) {
|
21
21
|
if testVersion != targetTestVersion {
|
22
22
|
t.Fatalf("Found testVersion = %v, want %v", testVersion, targetTestVersion)
|
23
23
|
}
|
24
|
+
}
|
25
|
+
|
26
|
+
func TestResultOf(t *testing.T) {
|
24
27
|
for _, tt := range testCases {
|
25
28
|
actual, err := ResultOf(prepare(tt.board))
|
26
29
|
// We don't expect errors for any of the test cases
|
@@ -86,10 +86,13 @@ var tests = []struct {
|
|
86
86
|
},
|
87
87
|
}
|
88
88
|
|
89
|
-
func
|
89
|
+
func TestTestVersion(t *testing.T) {
|
90
90
|
if testVersion != targetTestVersion {
|
91
|
-
t.
|
91
|
+
t.Fatalf("Found testVersion = %v, want %v", testVersion, targetTestVersion)
|
92
92
|
}
|
93
|
+
}
|
94
|
+
|
95
|
+
func TestEncode(t *testing.T) {
|
93
96
|
for _, test := range tests {
|
94
97
|
if ct := Encode(test.pt); ct != test.ct {
|
95
98
|
t.Fatalf(`Encode(%q):
|
@@ -26,7 +26,7 @@ func TestTestVersion(t *testing.T) {
|
|
26
26
|
func TestValid(t *testing.T) {
|
27
27
|
for _, test := range testCases {
|
28
28
|
if ok := Valid(test.input); ok != test.ok {
|
29
|
-
t.Fatalf("Valid(%s): %s\n\t Expected: %t\n\t Got: %t", test.input, test.description, ok,
|
29
|
+
t.Fatalf("Valid(%s): %s\n\t Expected: %t\n\t Got: %t", test.input, test.description, test.ok, ok)
|
30
30
|
}
|
31
31
|
}
|
32
32
|
}
|