trackler 2.0.8.2 → 2.0.8.3
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/bowling/canonical-data.json +166 -128
- data/lib/trackler/version.rb +1 -1
- data/tracks/java/exercises/pangram/src/test/java/PangramsTest.java +10 -10
- data/tracks/kotlin/config.json +5 -0
- data/tracks/kotlin/exercises/settings.gradle +2 -1
- data/tracks/kotlin/exercises/triangle/build.gradle +29 -0
- data/tracks/kotlin/exercises/triangle/src/example/kotlin/Triangle.kt +15 -0
- data/tracks/kotlin/exercises/triangle/src/main/kotlin/.keep +0 -0
- data/tracks/kotlin/exercises/triangle/src/test/kotlin/TriangleTest.kt +109 -0
- data/tracks/scala/config.json +8 -0
- data/tracks/scala/exercises/isogram/build.sbt +3 -0
- data/tracks/scala/exercises/isogram/example.scala +8 -0
- data/tracks/scala/exercises/isogram/src/main/scala/Isogram.scala +0 -0
- data/tracks/scala/exercises/isogram/src/test/scala/IsogramTest.scala +52 -0
- data/tracks/scala/testgen/src/main/scala/IsogramTestGenerator.scala +37 -0
- data/tracks/typescript/Makefile +0 -8
- metadata +11 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f0c444d7b94d362ffd61d031a2c19aa0648aec67
|
|
4
|
+
data.tar.gz: b89e89a7208130f5c3609cdfc7d489b9049ceb7e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 04579958808938ab72cb8921a7c432c814a219a283b375a732da663b2060cf688640a7cd7ca0f185af4d8c5d2874fcd88c51be3ec0db0f39dde08c46f8203e4a
|
|
7
|
+
data.tar.gz: 4b4b7d1cde0197fba10b59031fb9355ee2fa4e4a36f5a131b198df6129516e7891ef05f10f3d4117b909a71d6c3ef27b5b91b1bed520d4288159c294427779cb
|
|
@@ -1,134 +1,172 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
2
|
+
"exercise": "bowling",
|
|
3
|
+
"version": "1",
|
|
4
|
+
"comments": [
|
|
3
5
|
"Students should implement roll and score methods.",
|
|
4
6
|
"Roll should accept a single integer.",
|
|
5
7
|
"Score should return the game's final score, when possible",
|
|
6
|
-
"For brevity the tests display all the rolls in an array;",
|
|
7
|
-
"each element of the
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
8
|
+
"For brevity the tests display all the previous rolls in an array;",
|
|
9
|
+
"each element of the previous_rolls array should be passed to the roll method",
|
|
10
|
+
"and each of those previous rolls is expected to succeed.",
|
|
11
|
+
"",
|
|
12
|
+
"Two properties are tested:",
|
|
13
|
+
"",
|
|
14
|
+
"`score`: All rolls succeed, and taking the score gives the expected result.",
|
|
15
|
+
"The expected result may be an integer score or an error.",
|
|
16
|
+
"",
|
|
17
|
+
"`roll`: All previous_rolls succeed, and rolling the number of pins in `roll` produces the expected result.",
|
|
18
|
+
"Currently, all cases of this type result in errors.",
|
|
19
|
+
"",
|
|
20
|
+
"In all error cases you should expect an error as is idiomatic for your language",
|
|
21
|
+
"whether that be via exceptions, optional values, or otherwise."
|
|
15
22
|
],
|
|
16
|
-
"
|
|
17
|
-
"description":
|
|
18
|
-
|
|
19
|
-
],
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
}
|
|
23
|
+
"cases": [{
|
|
24
|
+
"description": "should be able to score a game with all zeros",
|
|
25
|
+
"property": "score",
|
|
26
|
+
"previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
27
|
+
"expected": 0
|
|
28
|
+
}, {
|
|
29
|
+
"description": "should be able to score a game with no strikes or spares",
|
|
30
|
+
"property": "score",
|
|
31
|
+
"previous_rolls": [3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6],
|
|
32
|
+
"expected": 90
|
|
33
|
+
}, {
|
|
34
|
+
"description": "a spare followed by zeros is worth ten points",
|
|
35
|
+
"property": "score",
|
|
36
|
+
"previous_rolls": [6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
37
|
+
"expected": 10
|
|
38
|
+
}, {
|
|
39
|
+
"description": "points scored in the roll after a spare are counted twice",
|
|
40
|
+
"property": "score",
|
|
41
|
+
"previous_rolls": [6, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
42
|
+
"expected": 16
|
|
43
|
+
}, {
|
|
44
|
+
"description": "consecutive spares each get a one roll bonus",
|
|
45
|
+
"property": "score",
|
|
46
|
+
"previous_rolls": [5, 5, 3, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
47
|
+
"expected": 31
|
|
48
|
+
}, {
|
|
49
|
+
"description": "a spare in the last frame gets a one roll bonus that is counted once",
|
|
50
|
+
"property": "score",
|
|
51
|
+
"previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 7],
|
|
52
|
+
"expected": 17
|
|
53
|
+
}, {
|
|
54
|
+
"description": "a strike earns ten points in a frame with a single roll",
|
|
55
|
+
"property": "score",
|
|
56
|
+
"previous_rolls": [10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
57
|
+
"expected": 10
|
|
58
|
+
}, {
|
|
59
|
+
"description": "points scored in the two rolls after a strike are counted twice as a bonus",
|
|
60
|
+
"property": "score",
|
|
61
|
+
"previous_rolls": [10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
62
|
+
"expected": 26
|
|
63
|
+
}, {
|
|
64
|
+
"description": "consecutive strikes each get the two roll bonus",
|
|
65
|
+
"property": "score",
|
|
66
|
+
"previous_rolls": [10, 10, 10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
67
|
+
"expected": 81
|
|
68
|
+
}, {
|
|
69
|
+
"description": "a strike in the last frame gets a two roll bonus that is counted once",
|
|
70
|
+
"property": "score",
|
|
71
|
+
"previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 1],
|
|
72
|
+
"expected": 18
|
|
73
|
+
}, {
|
|
74
|
+
"description": "rolling a spare with the two roll bonus does not get a bonus roll",
|
|
75
|
+
"property": "score",
|
|
76
|
+
"previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 3],
|
|
77
|
+
"expected": 20
|
|
78
|
+
}, {
|
|
79
|
+
"description": "strikes with the two roll bonus do not get bonus rolls",
|
|
80
|
+
"property": "score",
|
|
81
|
+
"previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10],
|
|
82
|
+
"expected": 30
|
|
83
|
+
}, {
|
|
84
|
+
"description": "a strike with the one roll bonus after a spare in the last frame does not get a bonus",
|
|
85
|
+
"property": "score",
|
|
86
|
+
"previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 10],
|
|
87
|
+
"expected": 20
|
|
88
|
+
}, {
|
|
89
|
+
"description": "all strikes is a perfect game",
|
|
90
|
+
"property": "score",
|
|
91
|
+
"previous_rolls": [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10],
|
|
92
|
+
"expected": 300
|
|
93
|
+
}, {
|
|
94
|
+
"description": "rolls can not score negative points",
|
|
95
|
+
"property": "roll",
|
|
96
|
+
"previous_rolls": [],
|
|
97
|
+
"roll": -1,
|
|
98
|
+
"expected": {"error": "Negative roll is invalid"}
|
|
99
|
+
}, {
|
|
100
|
+
"description": "a roll can not score more than 10 points",
|
|
101
|
+
"property": "roll",
|
|
102
|
+
"previous_rolls": [],
|
|
103
|
+
"roll": 11,
|
|
104
|
+
"expected": {"error": "Pin count exceeds pins on the lane"}
|
|
105
|
+
}, {
|
|
106
|
+
"description": "two rolls in a frame can not score more than 10 points",
|
|
107
|
+
"property": "roll",
|
|
108
|
+
"previous_rolls": [5],
|
|
109
|
+
"roll": 6,
|
|
110
|
+
"expected": {"error": "Pin count exceeds pins on the lane"}
|
|
111
|
+
}, {
|
|
112
|
+
"description": "bonus roll after a strike in the last frame can not score more than 10 points",
|
|
113
|
+
"property": "roll",
|
|
114
|
+
"previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10],
|
|
115
|
+
"roll": 11,
|
|
116
|
+
"expected": {"error": "Pin count exceeds pins on the lane"}
|
|
117
|
+
}, {
|
|
118
|
+
"description": "two bonus rolls after a strike in the last frame can not score more than 10 points",
|
|
119
|
+
"property": "roll",
|
|
120
|
+
"previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5],
|
|
121
|
+
"roll": 6,
|
|
122
|
+
"expected": {"error": "Pin count exceeds pins on the lane"}
|
|
123
|
+
}, {
|
|
124
|
+
"description": "two bonus rolls after a strike in the last frame can score more than 10 points if one is a strike",
|
|
125
|
+
"property": "score",
|
|
126
|
+
"previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 6],
|
|
127
|
+
"expected": 26
|
|
128
|
+
}, {
|
|
129
|
+
"description": "the second bonus rolls after a strike in the last frame can not be a strike if the first one is not a strike",
|
|
130
|
+
"property": "roll",
|
|
131
|
+
"previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 6],
|
|
132
|
+
"roll": 10,
|
|
133
|
+
"expected": {"error": "Pin count exceeds pins on the lane"}
|
|
134
|
+
}, {
|
|
135
|
+
"description": "second bonus roll after a strike in the last frame can not score than 10 points",
|
|
136
|
+
"property": "roll",
|
|
137
|
+
"previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10],
|
|
138
|
+
"roll": 11,
|
|
139
|
+
"expected": {"error": "Pin count exceeds pins on the lane"}
|
|
140
|
+
}, {
|
|
141
|
+
"description": "an unstarted game can not be scored",
|
|
142
|
+
"property": "score",
|
|
143
|
+
"previous_rolls": [],
|
|
144
|
+
"expected": {"error": "Score cannot be taken until the end of the game"}
|
|
145
|
+
}, {
|
|
146
|
+
"description": "an incomplete game can not be scored",
|
|
147
|
+
"property": "score",
|
|
148
|
+
"previous_rolls": [0, 0],
|
|
149
|
+
"expected": {"error": "Score cannot be taken until the end of the game"}
|
|
150
|
+
}, {
|
|
151
|
+
"description": "cannot roll if game already has ten frames",
|
|
152
|
+
"property": "roll",
|
|
153
|
+
"previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
154
|
+
"roll": 0,
|
|
155
|
+
"expected": {"error": "Cannot roll after game is over"}
|
|
156
|
+
}, {
|
|
157
|
+
"description": "bonus rolls for a strike in the last frame must be rolled before score can be calculated",
|
|
158
|
+
"property": "score",
|
|
159
|
+
"previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10],
|
|
160
|
+
"expected": {"error": "Score cannot be taken until the end of the game"}
|
|
161
|
+
}, {
|
|
162
|
+
"description": "both bonus rolls for a strike in the last frame must be rolled before score can be calculated",
|
|
163
|
+
"property": "score",
|
|
164
|
+
"previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10],
|
|
165
|
+
"expected": {"error": "Score cannot be taken until the end of the game"}
|
|
166
|
+
}, {
|
|
167
|
+
"description": "bonus roll for a spare in the last frame must be rolled before score can be calculated",
|
|
168
|
+
"property": "score",
|
|
169
|
+
"previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3],
|
|
170
|
+
"expected": {"error": "Score cannot be taken until the end of the game"}
|
|
171
|
+
}]
|
|
134
172
|
}
|
data/lib/trackler/version.rb
CHANGED
|
@@ -8,62 +8,62 @@ public class PangramsTest {
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
@Test
|
|
11
|
-
public void
|
|
11
|
+
public void emptySentenceIsNotPangram() {
|
|
12
12
|
assertFalse(Pangrams.isPangram(""));
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
@Ignore
|
|
16
16
|
@Test
|
|
17
|
-
public void
|
|
17
|
+
public void pangramWithOnlyLowerCaseLettersIsRecognizedAsPangram() {
|
|
18
18
|
assertTrue(Pangrams.isPangram("the quick brown fox jumps over the lazy dog"));
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
@Ignore
|
|
22
22
|
@Test
|
|
23
|
-
public void
|
|
23
|
+
public void phraseMissingCharacterXIsNotPangram() {
|
|
24
24
|
assertFalse(Pangrams.isPangram("a quick movement of the enemy will jeopardize five gunboats"));
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
@Ignore
|
|
28
28
|
@Test
|
|
29
|
-
public void
|
|
29
|
+
public void anotherPhraseMissingCharacterXIsNotPangram() {
|
|
30
30
|
assertFalse(Pangrams.isPangram("the quick brown fish jumps over the lazy dog"));
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
@Ignore
|
|
34
34
|
@Test
|
|
35
|
-
public void
|
|
35
|
+
public void pangramWithUnderscoresIsRecognizedAsPangram() {
|
|
36
36
|
assertTrue(Pangrams.isPangram("\"the_quick_brown_fox_jumps_over_the_lazy_dog\""));
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
@Ignore
|
|
40
40
|
@Test
|
|
41
|
-
public void
|
|
41
|
+
public void pangramWithNumbersIsRecognizedAsPangram() {
|
|
42
42
|
assertTrue(Pangrams.isPangram("\"the 1 quick brown fox jumps over the 2 lazy dogs\""));
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
@Ignore
|
|
46
46
|
@Test
|
|
47
|
-
public void
|
|
47
|
+
public void phraseWithMissingLettersReplacedByNumbersIsNotPangram() {
|
|
48
48
|
assertFalse(Pangrams.isPangram("\"7h3 qu1ck brown fox jumps ov3r 7h3 lazy dog\""));
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
@Ignore
|
|
52
52
|
@Test
|
|
53
|
-
public void
|
|
53
|
+
public void pangramWithMixedCaseAndPunctuationIsRecognizedAsPangram() {
|
|
54
54
|
assertTrue(Pangrams.isPangram("\"Five quacking Zephyrs jolt my wax bed.\""));
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
@Ignore
|
|
58
58
|
@Test
|
|
59
|
-
public void
|
|
59
|
+
public void pangramWithNonAsciiCharactersIsRecognizedAsPangram() {
|
|
60
60
|
assertTrue(Pangrams.isPangram("Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich."));
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
|
|
64
64
|
@Ignore
|
|
65
65
|
@Test
|
|
66
|
-
public void
|
|
66
|
+
public void panagramInAlphabetOtherThanAsciiIsNotRecognizedAsPangram() {
|
|
67
67
|
assertFalse(Pangrams.isPangram("Широкая электрификация южных губерний даст мощный толчок подъёму сельского хозяйства."));
|
|
68
68
|
}
|
|
69
69
|
|
data/tracks/kotlin/config.json
CHANGED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
buildscript {
|
|
2
|
+
ext.kotlin_version = '1.0.6'
|
|
3
|
+
repositories {
|
|
4
|
+
mavenCentral()
|
|
5
|
+
}
|
|
6
|
+
dependencies {
|
|
7
|
+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
apply plugin: 'kotlin'
|
|
12
|
+
|
|
13
|
+
repositories {
|
|
14
|
+
mavenCentral()
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
dependencies {
|
|
18
|
+
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
19
|
+
|
|
20
|
+
testCompile 'junit:junit:4.12'
|
|
21
|
+
testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version"
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
test {
|
|
25
|
+
testLogging {
|
|
26
|
+
exceptionFormat = 'full'
|
|
27
|
+
events = ["passed", "failed", "skipped"]
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
class Triangle<out T: Number>(val a: T, val b: T, val c: T) {
|
|
2
|
+
|
|
3
|
+
init {
|
|
4
|
+
require(a > 0 && b > 0 && c > 0, {"Sides must be > 0"})
|
|
5
|
+
require(a + b >= c && b + c >= a && c + a >= b, { "Sides must satisfy triangle inequality"})
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
val isEquilateral = a == b && b == c
|
|
9
|
+
val isIsosceles = a == b || b == c || c == a
|
|
10
|
+
val isScalene = !isIsosceles
|
|
11
|
+
|
|
12
|
+
private infix operator fun <T: Number> T.compareTo(other: T): Int = this.toDouble().compareTo(other.toDouble())
|
|
13
|
+
private infix operator fun <T: Number> T.plus(b: T): Double = this.toDouble().plus(b.toDouble())
|
|
14
|
+
|
|
15
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import org.junit.Ignore
|
|
2
|
+
import org.junit.Test
|
|
3
|
+
import kotlin.test.assertFalse
|
|
4
|
+
import kotlin.test.assertTrue
|
|
5
|
+
|
|
6
|
+
class TriangleTest {
|
|
7
|
+
|
|
8
|
+
@Test
|
|
9
|
+
fun equilateralIfAllSidesAreEqual() {
|
|
10
|
+
assertTrue(Triangle(2, 2, 2).isEquilateral)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@Ignore
|
|
14
|
+
@Test
|
|
15
|
+
fun notEquilateralIfAnySideIsUnequal() {
|
|
16
|
+
assertFalse(Triangle(2, 3, 2).isEquilateral)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@Ignore
|
|
20
|
+
@Test
|
|
21
|
+
fun notEquilateralIfNoSidesAreEqual() {
|
|
22
|
+
assertFalse(Triangle(5, 4, 6).isEquilateral)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@Ignore
|
|
26
|
+
@Test(expected = IllegalArgumentException::class)
|
|
27
|
+
fun allZeroSidesAreIllegalSoNotEquilateral() {
|
|
28
|
+
assertFalse(Triangle(0, 0, 0).isEquilateral)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@Ignore
|
|
32
|
+
@Test
|
|
33
|
+
fun equilateralSidesMayBeFloatingPoint() {
|
|
34
|
+
assertTrue(Triangle(0.5, 0.5, 0.5).isEquilateral)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@Ignore
|
|
38
|
+
@Test
|
|
39
|
+
fun isoscelesIfLastTwoSidesAreEqual() {
|
|
40
|
+
assertTrue(Triangle(3, 4, 4).isIsosceles)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@Ignore
|
|
44
|
+
@Test
|
|
45
|
+
fun isoscelesIfFirstTwoSidesAreEqual() {
|
|
46
|
+
assertTrue(Triangle(4, 4, 3).isIsosceles)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@Ignore
|
|
50
|
+
@Test
|
|
51
|
+
fun isoscelesIfFirstAndLastSidesAreEqual() {
|
|
52
|
+
assertTrue(Triangle(4, 3, 4).isIsosceles)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@Ignore
|
|
56
|
+
@Test
|
|
57
|
+
fun equilateralIsAlsoIsosceles() {
|
|
58
|
+
assertTrue(Triangle(4, 4, 4).isIsosceles)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@Ignore
|
|
62
|
+
@Test
|
|
63
|
+
fun notIsoscelesIfNoSidesAreEqual() {
|
|
64
|
+
assertFalse(Triangle(2, 3, 4).isIsosceles)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@Ignore
|
|
68
|
+
@Test(expected = IllegalArgumentException::class)
|
|
69
|
+
fun sidesViolateTriangleInequalitySoNotIsosceles() {
|
|
70
|
+
assertFalse(Triangle(1, 1, 3).isIsosceles)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@Ignore
|
|
74
|
+
@Test
|
|
75
|
+
fun isoscelesSidesMayBeFloatingPoint() {
|
|
76
|
+
assertTrue(Triangle(0.5, 0.4, 0.5).isIsosceles)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@Ignore
|
|
80
|
+
@Test
|
|
81
|
+
fun scaleneIfNoSidesAreEqual() {
|
|
82
|
+
assertTrue(Triangle(5, 4, 6).isScalene)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@Ignore
|
|
86
|
+
@Test
|
|
87
|
+
fun notScaleneIfAllSidesAreEqual() {
|
|
88
|
+
assertFalse(Triangle(4, 4, 4).isScalene)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@Ignore
|
|
92
|
+
@Test
|
|
93
|
+
fun notScaleneIfTwoSidesAreEqual() {
|
|
94
|
+
assertFalse(Triangle(4, 4, 3).isScalene)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@Ignore
|
|
98
|
+
@Test(expected = IllegalArgumentException::class)
|
|
99
|
+
fun sidesViolateTriangleInequalitySoNotScalene() {
|
|
100
|
+
assertFalse(Triangle(7, 3, 2).isScalene)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
@Ignore
|
|
104
|
+
@Test
|
|
105
|
+
fun scaleneSidesMayBeFloatingPoint() {
|
|
106
|
+
assertTrue(Triangle(0.5, 0.4, 0.6).isScalene)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
}
|
data/tracks/scala/config.json
CHANGED
|
File without changes
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import org.scalatest.{FunSuite, Matchers}
|
|
2
|
+
|
|
3
|
+
class IsogramTest extends FunSuite with Matchers {
|
|
4
|
+
|
|
5
|
+
test("empty string") {
|
|
6
|
+
val result = Isogram.isIsogram("")
|
|
7
|
+
result should be (true)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
test("isogram with only lower case characters") {
|
|
11
|
+
pending
|
|
12
|
+
val result = Isogram.isIsogram("isogram")
|
|
13
|
+
result should be (true)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
test("word with one duplicated character") {
|
|
17
|
+
pending
|
|
18
|
+
val result = Isogram.isIsogram("eleven")
|
|
19
|
+
result should be (false)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
test("longest reported english isogram") {
|
|
23
|
+
pending
|
|
24
|
+
val result = Isogram.isIsogram("subdermatoglyphic")
|
|
25
|
+
result should be (true)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
test("word with duplicated character in mixed case") {
|
|
29
|
+
pending
|
|
30
|
+
val result = Isogram.isIsogram("Alphabet")
|
|
31
|
+
result should be (false)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
test("hypothetical isogrammic word with hyphen") {
|
|
35
|
+
pending
|
|
36
|
+
val result = Isogram.isIsogram("thumbscrew-japingly")
|
|
37
|
+
result should be (true)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
test("isogram with duplicated non letter character") {
|
|
41
|
+
pending
|
|
42
|
+
val result = Isogram.isIsogram("Hjelmqvist-Gryb-Zock-Pfund-Wax")
|
|
43
|
+
result should be (true)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
test("made-up name that is an isogram") {
|
|
47
|
+
pending
|
|
48
|
+
val result = Isogram.isIsogram("Emily Jung Schwartzkopf")
|
|
49
|
+
result should be (true)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import play.api.libs.json.Json
|
|
2
|
+
|
|
3
|
+
import scala.io.Source
|
|
4
|
+
|
|
5
|
+
class IsogramTestGenerator {
|
|
6
|
+
implicit val testCaseReader = Json.reads[IsogramTestCase]
|
|
7
|
+
|
|
8
|
+
private val filename = "isogram.json"
|
|
9
|
+
private val fileContents = Source.fromFile(filename).getLines.mkString
|
|
10
|
+
private val json = Json.parse(fileContents)
|
|
11
|
+
|
|
12
|
+
def write {
|
|
13
|
+
val testCases = (json \ "cases").get.as[List[IsogramTestCase]]
|
|
14
|
+
|
|
15
|
+
implicit def testCaseToGen(tc: IsogramTestCase): TestCaseGen = {
|
|
16
|
+
val callSUT =
|
|
17
|
+
s"""Isogram.isIsogram("${tc.input}")"""
|
|
18
|
+
val expected = tc.expected.toString
|
|
19
|
+
|
|
20
|
+
TestCaseGen(tc.description, callSUT, expected)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
val testBuilder = new TestBuilder("IsogramTest")
|
|
24
|
+
testBuilder.addTestCases(testCases)
|
|
25
|
+
testBuilder.toFile
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
case class IsogramTestCase(description: String,
|
|
30
|
+
input: String,
|
|
31
|
+
expected: Boolean)
|
|
32
|
+
|
|
33
|
+
object IsogramTestGenerator {
|
|
34
|
+
def main(args: Array[String]): Unit = {
|
|
35
|
+
new IsogramTestGenerator().write
|
|
36
|
+
}
|
|
37
|
+
}
|
data/tracks/typescript/Makefile
CHANGED
|
@@ -44,11 +44,7 @@ moveAllIntoCommonDir:
|
|
|
44
44
|
moveCommonIntoSubDir:
|
|
45
45
|
@for assignment in $(ASSIGNMENTS); do ASSIGNMENT=$$assignment $(MAKE) moveAssigmentToSub || exit 1; done
|
|
46
46
|
|
|
47
|
-
<<<<<<< HEAD
|
|
48
|
-
all: replacePackageFileFromCommonToSubFolders
|
|
49
|
-
=======
|
|
50
47
|
all: replacePackageFilesFromCommonToSubFolders
|
|
51
|
-
>>>>>>> f5528ecd7751462ac6590cc77304a7ac2489c895
|
|
52
48
|
|
|
53
49
|
copyPackageFilesToSubFolder:
|
|
54
50
|
@cp ./common/package.json exercises/$(ASSIGNMENT)/package.json
|
|
@@ -56,10 +52,6 @@ copyPackageFilesToSubFolder:
|
|
|
56
52
|
@cp ./common/tslint.json exercises/$(ASSIGNMENT)/tslint.json
|
|
57
53
|
@cp ./common/yarn.lock exercises/$(ASSIGNMENT)/yarn.lock
|
|
58
54
|
|
|
59
|
-
<<<<<<< HEAD
|
|
60
|
-
replacePackageFileFromCommonToSubFolders:
|
|
61
|
-
=======
|
|
62
55
|
replacePackageFilesFromCommonToSubFolders:
|
|
63
|
-
>>>>>>> f5528ecd7751462ac6590cc77304a7ac2489c895
|
|
64
56
|
@for assignment in $(ASSIGNMENTS); do ASSIGNMENT=$$assignment $(MAKE) copyPackageFilesToSubFolder || exit 1; done
|
|
65
57
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: trackler
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.8.
|
|
4
|
+
version: 2.0.8.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Katrina Owen
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-02-
|
|
11
|
+
date: 2017-02-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rubyzip
|
|
@@ -4602,6 +4602,10 @@ files:
|
|
|
4602
4602
|
- tracks/kotlin/exercises/strain/src/example/kotlin/Strain.kt
|
|
4603
4603
|
- tracks/kotlin/exercises/strain/src/main/kotlin/.keep
|
|
4604
4604
|
- tracks/kotlin/exercises/strain/src/test/kotlin/StrainTest.kt
|
|
4605
|
+
- tracks/kotlin/exercises/triangle/build.gradle
|
|
4606
|
+
- tracks/kotlin/exercises/triangle/src/example/kotlin/Triangle.kt
|
|
4607
|
+
- tracks/kotlin/exercises/triangle/src/main/kotlin/.keep
|
|
4608
|
+
- tracks/kotlin/exercises/triangle/src/test/kotlin/TriangleTest.kt
|
|
4605
4609
|
- tracks/kotlin/exercises/word-count/build.gradle
|
|
4606
4610
|
- tracks/kotlin/exercises/word-count/src/example/kotlin/WordCount.kt
|
|
4607
4611
|
- tracks/kotlin/exercises/word-count/src/main/kotlin/.keep
|
|
@@ -7175,6 +7179,10 @@ files:
|
|
|
7175
7179
|
- tracks/scala/exercises/house/example.scala
|
|
7176
7180
|
- tracks/scala/exercises/house/src/main/scala/.keep
|
|
7177
7181
|
- tracks/scala/exercises/house/src/test/scala/HouseTest.scala
|
|
7182
|
+
- tracks/scala/exercises/isogram/build.sbt
|
|
7183
|
+
- tracks/scala/exercises/isogram/example.scala
|
|
7184
|
+
- tracks/scala/exercises/isogram/src/main/scala/Isogram.scala
|
|
7185
|
+
- tracks/scala/exercises/isogram/src/test/scala/IsogramTest.scala
|
|
7178
7186
|
- tracks/scala/exercises/kindergarten-garden/build.sbt
|
|
7179
7187
|
- tracks/scala/exercises/kindergarten-garden/example.scala
|
|
7180
7188
|
- tracks/scala/exercises/kindergarten-garden/src/main/scala/.keep
|
|
@@ -7388,6 +7396,7 @@ files:
|
|
|
7388
7396
|
- tracks/scala/testgen/src/main/scala/BowlingTestGenerator.scala
|
|
7389
7397
|
- tracks/scala/testgen/src/main/scala/BracketPushTestGenerator.scala
|
|
7390
7398
|
- tracks/scala/testgen/src/main/scala/CustomSetTestGenerator.scala
|
|
7399
|
+
- tracks/scala/testgen/src/main/scala/IsogramTestGenerator.scala
|
|
7391
7400
|
- tracks/scala/testgen/src/main/scala/PangramsTestGenerator.scala
|
|
7392
7401
|
- tracks/scala/testgen/src/main/scala/RailFenceCipherTestGenerator.scala
|
|
7393
7402
|
- tracks/scala/testgen/src/main/scala/TestBuilder.scala
|