trackler 2.0.6.16 → 2.0.6.17
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/tracks/ecmascript/exercises/luhn/example.js +28 -51
- data/tracks/ecmascript/exercises/luhn/luhn.spec.js +16 -41
- data/tracks/fsharp/exercises/simple-cipher/SimpleCipherTest.fs +3 -2
- data/tracks/go/exercises/custom-set/cases_test.go +80 -225
- data/tracks/go/exercises/custom-set/custom_set_test.go +46 -106
- data/tracks/go/exercises/custom-set/example.go +39 -78
- data/tracks/go/exercises/custom-set/example_gen.go +43 -63
- data/tracks/go/exercises/custom-set/example_slice.go +52 -70
- data/tracks/javascript/exercises/luhn/example.js +28 -57
- data/tracks/javascript/exercises/luhn/luhn.spec.js +16 -41
- data/tracks/ruby/README.md +1 -0
- data/tracks/swift/docs/TESTS.md +4 -4
- metadata +2 -2
@@ -5,19 +5,25 @@ package stringset
|
|
5
5
|
// Example based on slices rather than maps, to validate that such a solution
|
6
6
|
// can pass the tests.
|
7
7
|
//
|
8
|
-
// The API is a little
|
8
|
+
// The API is a little awkward for this because it has value receivers but
|
9
9
|
// a pointer in a struct works okay.
|
10
10
|
|
11
11
|
import "fmt"
|
12
12
|
|
13
|
-
const testVersion =
|
13
|
+
const testVersion = 4
|
14
14
|
|
15
|
-
|
15
|
+
// Set represents some properties of a mathematical set.
|
16
|
+
// Sets are finite and all elements are unique string values.
|
17
|
+
type Set struct {
|
18
|
+
s *[]string
|
19
|
+
}
|
16
20
|
|
21
|
+
// New constructs a new Set representing an empty set.
|
17
22
|
func New() Set {
|
18
23
|
return Set{new([]string)}
|
19
24
|
}
|
20
25
|
|
26
|
+
// NewFromSlice constructs a new Set populated from elements of a slice.
|
21
27
|
func NewFromSlice(l []string) Set {
|
22
28
|
s := New()
|
23
29
|
for _, e := range l {
|
@@ -26,27 +32,26 @@ func NewFromSlice(l []string) Set {
|
|
26
32
|
return s
|
27
33
|
}
|
28
34
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
35
|
+
// String returns a printable representation of s.
|
36
|
+
func (s Set) String() string {
|
37
|
+
r := "{"
|
38
|
+
i := 0
|
39
|
+
for _, v := range *s.s {
|
40
|
+
if i > 0 {
|
41
|
+
r += ", "
|
33
42
|
}
|
43
|
+
r += fmt.Sprintf("%q", v)
|
44
|
+
i++
|
34
45
|
}
|
35
|
-
|
46
|
+
return r + "}"
|
36
47
|
}
|
37
48
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
if e == v {
|
42
|
-
last := len(ss) - 1
|
43
|
-
ss[i] = ss[last]
|
44
|
-
*s.s = ss[:last]
|
45
|
-
return
|
46
|
-
}
|
47
|
-
}
|
49
|
+
// IsEmpty returns true if s represents the empty set.
|
50
|
+
func (s Set) IsEmpty() bool {
|
51
|
+
return len(*s.s) == 0
|
48
52
|
}
|
49
53
|
|
54
|
+
// Has returns true if e is an element of s.
|
50
55
|
func (s Set) Has(v string) bool {
|
51
56
|
for _, e := range *s.s {
|
52
57
|
if e == v {
|
@@ -56,31 +61,28 @@ func (s Set) Has(v string) bool {
|
|
56
61
|
return false
|
57
62
|
}
|
58
63
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
}
|
66
|
-
|
67
|
-
|
68
|
-
return append([]string{}, *s.s...)
|
64
|
+
// Add adds element e to Set s.
|
65
|
+
// If e is already in s, s is unchanged.
|
66
|
+
func (s Set) Add(v string) {
|
67
|
+
for _, e := range *s.s {
|
68
|
+
if e == v {
|
69
|
+
return
|
70
|
+
}
|
71
|
+
}
|
72
|
+
*s.s = append(*s.s, v)
|
69
73
|
}
|
70
74
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
r += ", "
|
75
|
+
// Subset returns true if all elements of s1 are also in s2.
|
76
|
+
func Subset(s1, s2 Set) bool {
|
77
|
+
for _, v := range *s1.s {
|
78
|
+
if !s2.Has(v) {
|
79
|
+
return false
|
77
80
|
}
|
78
|
-
r += fmt.Sprintf("%q", v)
|
79
|
-
i++
|
80
81
|
}
|
81
|
-
return
|
82
|
+
return true
|
82
83
|
}
|
83
84
|
|
85
|
+
// Disjoint returns true if s1 and s2 have no elements in common.
|
84
86
|
func Disjoint(s1, s2 Set) bool {
|
85
87
|
for _, v := range *s1.s {
|
86
88
|
if s2.Has(v) {
|
@@ -90,10 +92,13 @@ func Disjoint(s1, s2 Set) bool {
|
|
90
92
|
return true
|
91
93
|
}
|
92
94
|
|
95
|
+
// Equal returns true if s1 and s2 contain the same elements.
|
93
96
|
func Equal(s1, s2 Set) bool {
|
94
|
-
return s1
|
97
|
+
return Subset(s1, s2) && Subset(s2, s1)
|
95
98
|
}
|
96
99
|
|
100
|
+
// Intersection constructs a new Set populated with the elements common to
|
101
|
+
// both s1 and s2
|
97
102
|
func Intersection(s1, s2 Set) Set {
|
98
103
|
var i []string
|
99
104
|
for _, v := range *s1.s {
|
@@ -104,15 +109,8 @@ func Intersection(s1, s2 Set) Set {
|
|
104
109
|
return Set{&i}
|
105
110
|
}
|
106
111
|
|
107
|
-
|
108
|
-
|
109
|
-
u := Set{&s}
|
110
|
-
for _, v := range *s2.s {
|
111
|
-
u.Add(v)
|
112
|
-
}
|
113
|
-
return u
|
114
|
-
}
|
115
|
-
|
112
|
+
// Difference returns a new Set populated with elements that appear in s1
|
113
|
+
// but not in s2.
|
116
114
|
func Difference(s1, s2 Set) Set {
|
117
115
|
var d []string
|
118
116
|
for _, v := range *s1.s {
|
@@ -123,29 +121,13 @@ func Difference(s1, s2 Set) Set {
|
|
123
121
|
return Set{&d}
|
124
122
|
}
|
125
123
|
|
126
|
-
//
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
}
|
132
|
-
}
|
133
|
-
return true
|
134
|
-
}
|
135
|
-
|
136
|
-
// SymmetricDifference constructs a new set populated with elements that are
|
137
|
-
// members of s1 or s2 but not both.
|
138
|
-
func SymmetricDifference(s1, s2 Set) Set {
|
139
|
-
var s []string
|
140
|
-
for _, v := range *s1.s {
|
141
|
-
if !s2.Has(v) {
|
142
|
-
s = append(s, v)
|
143
|
-
}
|
144
|
-
}
|
124
|
+
// Union constructs a new Set populated with elements that appear in s1, s2,
|
125
|
+
// or both.
|
126
|
+
func Union(s1, s2 Set) Set {
|
127
|
+
s := append([]string{}, *s1.s...)
|
128
|
+
u := Set{&s}
|
145
129
|
for _, v := range *s2.s {
|
146
|
-
|
147
|
-
s = append(s, v)
|
148
|
-
}
|
130
|
+
u.Add(v)
|
149
131
|
}
|
150
|
-
return
|
132
|
+
return u
|
151
133
|
}
|
@@ -1,63 +1,34 @@
|
|
1
1
|
'use strict';
|
2
2
|
|
3
|
-
function
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
var numbers = numberAsString.split('');
|
15
|
-
var addends = [];
|
16
|
-
|
17
|
-
for (var i = 0; i < numbers.length; i++) {
|
18
|
-
var index = numbers.length - 1 - i;
|
19
|
-
|
20
|
-
var currentAddend = parseInt(numbers[index], 10);
|
21
|
-
|
22
|
-
if ((i + 1) % 2 === 0) {
|
23
|
-
currentAddend = currentAddend * 2;
|
24
|
-
if (currentAddend > 10) {
|
25
|
-
currentAddend = currentAddend - 9;
|
26
|
-
}
|
3
|
+
function isValid(number) {
|
4
|
+
number = number.replace(/\s/g, '');
|
5
|
+
const digits = [...number];
|
6
|
+
|
7
|
+
const sum = digits
|
8
|
+
// convert to integers
|
9
|
+
.map(d => parseInt(d, 10))
|
10
|
+
// double even positions (odd indexes)
|
11
|
+
.map((d, i) => {
|
12
|
+
if (i % 2 !== 0) {
|
13
|
+
return d * 2;
|
27
14
|
}
|
15
|
+
return d;
|
16
|
+
})
|
17
|
+
// limit to digits less than 10
|
18
|
+
.map(d => {
|
19
|
+
if (d > 9) {
|
20
|
+
return d - 9;
|
21
|
+
}
|
22
|
+
return d;
|
23
|
+
})
|
24
|
+
// sum all digits
|
25
|
+
.reduce((d, acc) => d + acc, 0);
|
28
26
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
return addends.reverse();
|
33
|
-
|
34
|
-
},
|
35
|
-
calculateChecksum: function(numbers) {
|
36
|
-
var sum = 0;
|
37
|
-
for (var i = 0; i < numbers.length; i++) {
|
38
|
-
sum += numbers[i];
|
39
|
-
}
|
40
|
-
|
41
|
-
return sum;
|
42
|
-
},
|
43
|
-
determineIfValid: function(sum) {
|
44
|
-
return (sum % 10 === 0);
|
45
|
-
}
|
46
|
-
};
|
47
|
-
|
48
|
-
Luhn.create = function(number) {
|
49
|
-
var finalNumber = number * 10;
|
50
|
-
var luhnNumber = new Luhn(finalNumber);
|
51
|
-
var index = 0;
|
52
|
-
|
53
|
-
while(!luhnNumber.valid) {
|
54
|
-
finalNumber = number * 10 + index;
|
55
|
-
luhnNumber = new Luhn(finalNumber);
|
56
|
-
if (luhnNumber.valid) { break; }
|
57
|
-
index += 1;
|
58
|
-
}
|
27
|
+
return sum > 0 && sum % 10 === 0;
|
28
|
+
}
|
59
29
|
|
60
|
-
|
61
|
-
|
30
|
+
function Luhn(number) {
|
31
|
+
this.valid = isValid(number);
|
32
|
+
}
|
62
33
|
|
63
|
-
module.exports = Luhn;
|
34
|
+
module.exports = Luhn;
|
@@ -2,59 +2,34 @@ var Luhn = require('./luhn');
|
|
2
2
|
|
3
3
|
describe('Luhn',function() {
|
4
4
|
|
5
|
-
it('
|
6
|
-
|
7
|
-
expect(luhn.
|
8
|
-
});
|
9
|
-
|
10
|
-
xit('check digit again',function() {
|
11
|
-
var luhn = new Luhn(91370);
|
12
|
-
expect(luhn.checkDigit).toEqual(0);
|
13
|
-
});
|
14
|
-
|
15
|
-
xit('addends',function() {
|
16
|
-
var luhn = new Luhn(12121);
|
17
|
-
expect(luhn.addends).toEqual([1, 4, 1, 4, 1]);
|
18
|
-
});
|
19
|
-
|
20
|
-
xit('too large addend',function() {
|
21
|
-
var luhn = new Luhn(8631);
|
22
|
-
expect(luhn.addends).toEqual([7, 6, 6, 1]);
|
23
|
-
});
|
24
|
-
|
25
|
-
xit('checksum',function() {
|
26
|
-
var luhn = new Luhn(4913);
|
27
|
-
expect(luhn.checksum).toEqual(22);
|
28
|
-
});
|
29
|
-
|
30
|
-
xit('checksum again',function() {
|
31
|
-
var luhn = new Luhn(201773);
|
32
|
-
expect(luhn.checksum).toEqual(21);
|
5
|
+
it('single digit strings can not be valid', function () {
|
6
|
+
const luhn = new Luhn('1');
|
7
|
+
expect(luhn.valid).toEqual(false);
|
33
8
|
});
|
34
9
|
|
35
|
-
xit('invalid
|
36
|
-
|
10
|
+
xit('A single zero is invalid', function () {
|
11
|
+
const luhn = new Luhn('0');
|
37
12
|
expect(luhn.valid).toEqual(false);
|
38
13
|
});
|
39
14
|
|
40
|
-
xit('
|
41
|
-
|
15
|
+
xit('valid Canadian SIN', function () {
|
16
|
+
const luhn = new Luhn('046 454 286');
|
42
17
|
expect(luhn.valid).toEqual(true);
|
43
18
|
});
|
44
19
|
|
45
|
-
xit('
|
46
|
-
|
47
|
-
expect(
|
20
|
+
xit('invalid Canadian SIN', function () {
|
21
|
+
const luhn = new Luhn('046 454 287');
|
22
|
+
expect(luhn.valid).toEqual(false);
|
48
23
|
});
|
49
24
|
|
50
|
-
xit('
|
51
|
-
|
52
|
-
expect(
|
25
|
+
xit('invalid credit card', function () {
|
26
|
+
const luhn = new Luhn('8273 1232 7352 0569');
|
27
|
+
expect(luhn.valid).toEqual(false);
|
53
28
|
});
|
54
29
|
|
55
|
-
xit('
|
56
|
-
|
57
|
-
expect(
|
30
|
+
xit('valid strings with a non-digit added become invalid', function () {
|
31
|
+
const luhn = new Luhn('046a 454 286');
|
32
|
+
expect(luhn.valid).toEqual(false);
|
58
33
|
});
|
59
34
|
|
60
35
|
});
|
data/tracks/ruby/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# xRuby
|
2
2
|
|
3
|
+
[![Build Status](https://travis-ci.org/exercism/xruby.svg?branch=master)](https://travis-ci.org/exercism/xruby)
|
3
4
|
[![Join the chat at https://gitter.im/exercism/xruby](https://badges.gitter.im/exercism/xruby.svg)](https://gitter.im/exercism/xruby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
4
5
|
|
5
6
|
Exercism Exercises in Ruby
|
data/tracks/swift/docs/TESTS.md
CHANGED
@@ -32,21 +32,21 @@ Optionally, Xcode can create a third file for experimentation:
|
|
32
32
|
3. At this point the project's file inspector should look similar to the following image. If the `HelloWorldTests` folder is closed, click on the disclosure triangle to reveal its contents.
|
33
33
|
4. The items Package.swift, Configs, and Products are boilerplate that do not need modification.
|
34
34
|
|
35
|
-
![file inspector](img/file-inspector.png)
|
35
|
+
![file inspector](/docs/img/file-inspector.png)
|
36
36
|
|
37
37
|
### Running Tests with Xcode
|
38
38
|
|
39
39
|
Select the test file from the file inspector. You can trigger tests by clicking on one of the diamonds in the gutter of the Tests Source file. The diamond next to the class definition will run all the tests, whereas the diamond next to each individual test will run only that test.
|
40
40
|
|
41
|
-
![tests](img/tests.png)
|
41
|
+
![tests](/docs/img/tests.png)
|
42
42
|
|
43
43
|
Tests can also be invoked with Command-U, from the Test Inspector (Command-5), or from the sub-menu under the play button in the top bar. Red errors are normal at this stage.
|
44
44
|
|
45
|
-
![failing tests](img/tests-fail.png)
|
45
|
+
![failing tests](/docs/img/tests-fail.png)
|
46
46
|
|
47
47
|
Once all the tests are marked with a green icon, congratulations, you have successfully completed the exercise! Now submit it to the Exercism website for review. If you are impossibly stuck, submit the exercise before it is complete to view how other users solved the exercise.
|
48
48
|
|
49
|
-
![passing tests](img/tests-pass.png)
|
49
|
+
![passing tests](/docs/img/tests-pass.png)
|
50
50
|
|
51
51
|
*The Hello-World exercise is a very simple coding problem, but the complexity of Xcode can make even simple exercises complex. We can ignore most of this complexity, because we only need to edit one file. You can always regenerate the Xcode project if something goes wrong.*
|
52
52
|
|
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.6.
|
4
|
+
version: 2.0.6.17
|
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-01-
|
11
|
+
date: 2017-01-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubyzip
|