trackler 2.0.8.6 → 2.0.8.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/verify-metadata +7 -11
- data/lib/trackler/version.rb +1 -1
- data/tracks/clojure/config.json +5 -0
- data/tracks/clojure/exercises/luhn/luhn.mustache +9 -0
- data/tracks/clojure/exercises/luhn/src/example.clj +11 -9
- data/tracks/clojure/exercises/luhn/test/luhn_test.clj +29 -29
- data/tracks/clojure/exercises/nth-prime/project.clj +4 -0
- data/tracks/clojure/exercises/nth-prime/src/example.clj +33 -0
- data/tracks/clojure/exercises/nth-prime/test/nth_prime_test.clj +23 -0
- data/tracks/go/exercises/TRACK_HINTS.md +3 -0
- data/tracks/go/exercises/ocr-numbers/example.go +2 -0
- data/tracks/go/exercises/ocr-numbers/ocr_numbers_test.go +8 -0
- data/tracks/go/exercises/octal/octal_test.go +6 -6
- data/tracks/go/exercises/paasio/paasio_test.go +5 -3
- data/tracks/go/exercises/palindrome-products/palindrome_products_test.go +6 -6
- data/tracks/go/exercises/strain/strain_test.go +37 -39
- data/tracks/julia/config.json +19 -0
- data/tracks/julia/exercises/etl/etl.jl +4 -0
- data/tracks/julia/exercises/etl/example.jl +11 -0
- data/tracks/julia/exercises/etl/runtests.jl +36 -0
- data/tracks/julia/exercises/pascals-triangle/example.jl +1 -0
- data/tracks/julia/exercises/pascals-triangle/pascals-triangle.jl +3 -0
- data/tracks/julia/exercises/pascals-triangle/runtests.jl +14 -0
- data/tracks/rust/config.json +22 -1
- data/tracks/rust/exercises/luhn-from/.gitignore +7 -0
- data/tracks/rust/exercises/luhn-from/Cargo.toml +3 -0
- data/tracks/rust/exercises/luhn-from/description.md +9 -0
- data/tracks/rust/exercises/luhn-from/example.rs +62 -0
- data/tracks/rust/exercises/luhn-from/metadata.yml +3 -0
- data/tracks/rust/exercises/luhn-from/tests/luhn-from.rs +101 -0
- data/tracks/rust/exercises/luhn-trait/.gitignore +7 -0
- data/tracks/rust/exercises/luhn-trait/Cargo.toml +3 -0
- data/tracks/rust/exercises/luhn-trait/description.md +17 -0
- data/tracks/rust/exercises/luhn-trait/example.rs +55 -0
- data/tracks/rust/exercises/luhn-trait/metadata.yml +3 -0
- data/tracks/rust/exercises/luhn-trait/tests/luhn-trait.rs +59 -0
- data/tracks/rust/exercises/nucleotide-codons/tests/codons.rs +24 -5
- data/tracks/rust/exercises/protein-translation/Cargo.lock +4 -0
- data/tracks/rust/exercises/protein-translation/Cargo.toml +4 -0
- data/tracks/rust/exercises/protein-translation/example.rs +40 -0
- data/tracks/rust/exercises/protein-translation/tests/proteins.rs +116 -0
- metadata +28 -2
data/tracks/julia/config.json
CHANGED
@@ -34,6 +34,16 @@
|
|
34
34
|
"generators"
|
35
35
|
]
|
36
36
|
},
|
37
|
+
{
|
38
|
+
"slug": "pascals-triangle",
|
39
|
+
"difficulty": 1,
|
40
|
+
"topics": [
|
41
|
+
"control-flow (conditionals)",
|
42
|
+
"integers",
|
43
|
+
"mathematics",
|
44
|
+
"exceptions"
|
45
|
+
]
|
46
|
+
},
|
37
47
|
{
|
38
48
|
"slug": "nucleotide-count",
|
39
49
|
"difficulty": 1,
|
@@ -147,6 +157,15 @@
|
|
147
157
|
"filtering"
|
148
158
|
]
|
149
159
|
},
|
160
|
+
{
|
161
|
+
"slug": "etl",
|
162
|
+
"difficulty": 2,
|
163
|
+
"topics": [
|
164
|
+
"arrays",
|
165
|
+
"strings",
|
166
|
+
"sorting"
|
167
|
+
]
|
168
|
+
},
|
150
169
|
{
|
151
170
|
"slug": "bob",
|
152
171
|
"difficulty": 2,
|
@@ -0,0 +1,36 @@
|
|
1
|
+
using Base.Test
|
2
|
+
|
3
|
+
include("etl.jl")
|
4
|
+
|
5
|
+
@testset "a single letter" begin
|
6
|
+
input = Dict(1=>['A'])
|
7
|
+
output = Dict('a'=>1)
|
8
|
+
@test transform(input) == output
|
9
|
+
end
|
10
|
+
|
11
|
+
@testset "single score with multiple letters" begin
|
12
|
+
input = Dict(1=>['A', 'E', 'I', 'O', 'U'])
|
13
|
+
output = Dict('a'=>1, 'e'=>1, 'i'=>1, 'o'=>1, 'u'=>1)
|
14
|
+
@test transform(input) == output
|
15
|
+
end
|
16
|
+
|
17
|
+
@testset "multiple scores with multiple letters" begin
|
18
|
+
input = Dict(1=>['A', 'E'], 2=>['D', 'G'])
|
19
|
+
output = Dict('g'=>2, 'e'=>1, 'a'=>1, 'd'=>2)
|
20
|
+
@test transform(input) == output
|
21
|
+
end
|
22
|
+
|
23
|
+
@testset "multiple scores with differing numbers of letters" begin
|
24
|
+
input = Dict(1=>[ 'A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T' ],
|
25
|
+
2=>[ 'D', 'G' ], 3=>[ 'B', 'C', 'M', 'P' ],
|
26
|
+
4=>[ 'F', 'H', 'V', 'W', 'Y' ], 5=>[ 'K' ],
|
27
|
+
8=>[ 'J', 'X' ], 10=>[ 'Q', 'Z' ])
|
28
|
+
output = Dict('a'=>1, 'b'=>3, 'c'=>3, 'd'=>2, 'e'=>1,
|
29
|
+
'f'=>4, 'g'=>2, 'h'=>4, 'i'=>1, 'j'=>8,
|
30
|
+
'k'=>5, 'l'=>1, 'm'=>3, 'n'=>1, 'o'=>1,
|
31
|
+
'p'=>3, 'q'=>10, 'r'=>1, 's'=>1, 't'=>1,
|
32
|
+
'u'=>1, 'v'=>4, 'w'=>4, 'x'=>8, 'y'=>4,
|
33
|
+
'z'=>10)
|
34
|
+
@test transform(input) == output
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
triangle(n::Int) = n >= 0 ? [[binomial(i, j) for j in 0:i] for i in 0:n-1] : throw(DomainError())
|
@@ -0,0 +1,14 @@
|
|
1
|
+
using Base.Test
|
2
|
+
|
3
|
+
include("pascals-triangle.jl")
|
4
|
+
|
5
|
+
rows = [[1], [1, 1], [1, 2, 1], [1, 3, 3, 1]]
|
6
|
+
|
7
|
+
@testset "$i row(s)" for i in 1:4
|
8
|
+
@test triangle(i) == rows[1:i]
|
9
|
+
end
|
10
|
+
|
11
|
+
@testset "special cases" begin
|
12
|
+
@test_throws DomainError triangle(-1)
|
13
|
+
@test isempty(triangle(0))
|
14
|
+
end
|
data/tracks/rust/config.json
CHANGED
@@ -263,6 +263,16 @@
|
|
263
263
|
"stack or recursion"
|
264
264
|
]
|
265
265
|
},
|
266
|
+
{
|
267
|
+
"slug": "luhn-from",
|
268
|
+
"difficulty": 4,
|
269
|
+
"topics": [
|
270
|
+
"from trait",
|
271
|
+
"str to digits",
|
272
|
+
"iterators",
|
273
|
+
"higher-order functions"
|
274
|
+
]
|
275
|
+
},
|
266
276
|
{
|
267
277
|
"slug": "queen-attack",
|
268
278
|
"difficulty": 4,
|
@@ -298,6 +308,16 @@
|
|
298
308
|
"Default Trait implementation"
|
299
309
|
]
|
300
310
|
},
|
311
|
+
{
|
312
|
+
"slug": "luhn-trait",
|
313
|
+
"difficulty": 4,
|
314
|
+
"topics": [
|
315
|
+
"Custom Trait",
|
316
|
+
"str to digits",
|
317
|
+
"iterators",
|
318
|
+
"higher-order functions"
|
319
|
+
]
|
320
|
+
},
|
301
321
|
{
|
302
322
|
"slug": "allergies",
|
303
323
|
"difficulty": 4,
|
@@ -381,7 +401,7 @@
|
|
381
401
|
]
|
382
402
|
},
|
383
403
|
{
|
384
|
-
"slug": "
|
404
|
+
"slug": "protein-translation",
|
385
405
|
"difficulty": 7,
|
386
406
|
"topics": [
|
387
407
|
"struct",
|
@@ -468,6 +488,7 @@
|
|
468
488
|
}
|
469
489
|
],
|
470
490
|
"deprecated": [
|
491
|
+
"nucleotide-codons",
|
471
492
|
"hexadecimal"
|
472
493
|
],
|
473
494
|
"ignored": [
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# Luhn: Using the From Trait
|
2
|
+
|
3
|
+
Before doing this exercise you should probably do the original Luhn exercise. If you have not completed Luhn, you can get it by running the command:
|
4
|
+
|
5
|
+
> `exercism fetch rust luhn`
|
6
|
+
|
7
|
+
In the original Luhn exercise you only validated strings, but the Luhn algorithm can be applied to integers as well.
|
8
|
+
|
9
|
+
In this exercise you'll implement the [From trait](https://doc.rust-lang.org/std/convert/trait.From.html) to convert strings, strs and unsigned integers into a Struct that performs the validation.
|
@@ -0,0 +1,62 @@
|
|
1
|
+
pub struct Luhn {
|
2
|
+
digits: Vec<char>,
|
3
|
+
}
|
4
|
+
|
5
|
+
impl Luhn {
|
6
|
+
pub fn is_valid(&self) -> bool {
|
7
|
+
if self.digits.iter().any(|c| c.is_alphabetic()) || self.digits.iter().count() == 1 {
|
8
|
+
return false;
|
9
|
+
}
|
10
|
+
|
11
|
+
self.digits
|
12
|
+
.iter()
|
13
|
+
.filter_map(|c| c.to_digit(10))
|
14
|
+
.rev()
|
15
|
+
.enumerate()
|
16
|
+
.map(|(index, digit)| if index % 2 == 0 { digit } else { digit * 2 })
|
17
|
+
.map(|digit| if digit > 9 { digit - 9 } else { digit })
|
18
|
+
.sum::<u32>() % 10 == 0
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
22
|
+
impl From<String> for Luhn {
|
23
|
+
fn from(s: String) -> Self {
|
24
|
+
Luhn { digits: s.chars().collect() }
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
impl<'a> From<&'a str> for Luhn {
|
29
|
+
fn from(s: &'a str) -> Self {
|
30
|
+
Luhn::from(String::from(s))
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
impl From<u8> for Luhn {
|
35
|
+
fn from(s: u8) -> Self {
|
36
|
+
Luhn::from(s.to_string())
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
impl From<u16> for Luhn {
|
41
|
+
fn from(s: u16) -> Self {
|
42
|
+
Luhn::from(s.to_string())
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
impl From<u32> for Luhn {
|
47
|
+
fn from(s: u32) -> Self {
|
48
|
+
Luhn::from(s.to_string())
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
impl From<u64> for Luhn {
|
53
|
+
fn from(s: u64) -> Self {
|
54
|
+
Luhn::from(s.to_string())
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
impl From<usize> for Luhn {
|
59
|
+
fn from(s: usize) -> Self {
|
60
|
+
Luhn::from(s.to_string())
|
61
|
+
}
|
62
|
+
}
|
@@ -0,0 +1,101 @@
|
|
1
|
+
extern crate luhn_from;
|
2
|
+
|
3
|
+
use luhn_from::*;
|
4
|
+
|
5
|
+
#[test]
|
6
|
+
fn you_can_validate_from_a_str() {
|
7
|
+
let valid = Luhn::from("046 454 286");
|
8
|
+
let invalid = Luhn::from("046 454 287");
|
9
|
+
assert!(valid.is_valid());
|
10
|
+
assert!(!invalid.is_valid());
|
11
|
+
}
|
12
|
+
|
13
|
+
#[test]
|
14
|
+
#[ignore]
|
15
|
+
fn you_can_validate_from_a_string() {
|
16
|
+
let valid = Luhn::from(String::from("046 454 286"));
|
17
|
+
let invalid = Luhn::from(String::from("046 454 287"));
|
18
|
+
assert!(valid.is_valid());
|
19
|
+
assert!(!invalid.is_valid());
|
20
|
+
}
|
21
|
+
|
22
|
+
#[test]
|
23
|
+
#[ignore]
|
24
|
+
fn you_can_validate_from_a_u8() {
|
25
|
+
let valid = Luhn::from(240u8);
|
26
|
+
let invalid = Luhn::from(241u8);
|
27
|
+
assert!(valid.is_valid());
|
28
|
+
assert!(!invalid.is_valid());
|
29
|
+
}
|
30
|
+
|
31
|
+
#[test]
|
32
|
+
#[ignore]
|
33
|
+
fn you_can_validate_from_a_u16() {
|
34
|
+
let valid = Luhn::from(64_436u16);
|
35
|
+
let invalid = Luhn::from(64_437u16);
|
36
|
+
assert!(valid.is_valid());
|
37
|
+
assert!(!invalid.is_valid());
|
38
|
+
}
|
39
|
+
|
40
|
+
#[test]
|
41
|
+
#[ignore]
|
42
|
+
fn you_can_validate_from_a_u32() {
|
43
|
+
let valid = Luhn::from(46_454_286u32);
|
44
|
+
let invalid = Luhn::from(46_454_287u32);
|
45
|
+
assert!(valid.is_valid());
|
46
|
+
assert!(!invalid.is_valid());
|
47
|
+
}
|
48
|
+
|
49
|
+
#[test]
|
50
|
+
#[ignore]
|
51
|
+
fn you_can_validate_from_a_u64() {
|
52
|
+
let valid = Luhn::from(8273_1232_7352_0562u64);
|
53
|
+
let invalid = Luhn::from(8273_1232_7352_0569u64);
|
54
|
+
assert!(valid.is_valid());
|
55
|
+
assert!(!invalid.is_valid());
|
56
|
+
}
|
57
|
+
|
58
|
+
#[test]
|
59
|
+
#[ignore]
|
60
|
+
fn you_can_validate_from_a_usize() {
|
61
|
+
let valid = Luhn::from(8273_1232_7352_0562usize);
|
62
|
+
let invalid = Luhn::from(8273_1232_7352_0569usize);
|
63
|
+
assert!(valid.is_valid());
|
64
|
+
assert!(!invalid.is_valid());
|
65
|
+
}
|
66
|
+
|
67
|
+
#[test]
|
68
|
+
#[ignore]
|
69
|
+
fn single_digit_string_is_invalid() {
|
70
|
+
assert!(!Luhn::from("1").is_valid());
|
71
|
+
}
|
72
|
+
|
73
|
+
#[test]
|
74
|
+
#[ignore]
|
75
|
+
fn single_zero_string_is_invalid() {
|
76
|
+
assert!(!Luhn::from("0").is_valid());
|
77
|
+
}
|
78
|
+
|
79
|
+
#[test]
|
80
|
+
#[ignore]
|
81
|
+
fn valid_canadian_sin_is_valid() {
|
82
|
+
assert!(Luhn::from("046 454 286").is_valid());
|
83
|
+
}
|
84
|
+
|
85
|
+
#[test]
|
86
|
+
#[ignore]
|
87
|
+
fn invalid_canadian_sin_is_invalid() {
|
88
|
+
assert!(!Luhn::from("046 454 287").is_valid());
|
89
|
+
}
|
90
|
+
|
91
|
+
#[test]
|
92
|
+
#[ignore]
|
93
|
+
fn invalid_credit_card_is_invalid() {
|
94
|
+
assert!(!Luhn::from("8273 1232 7352 0569").is_valid());
|
95
|
+
}
|
96
|
+
|
97
|
+
#[test]
|
98
|
+
#[ignore]
|
99
|
+
fn strings_that_contain_non_digits_are_invalid() {
|
100
|
+
assert!(!Luhn::from("046a 454 286").is_valid());
|
101
|
+
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Luhn: Using a Custom Trait
|
2
|
+
|
3
|
+
Before doing this exercise you should probably do the original Luhn exercise and its successor, "Luhn: Using the From Trait"
|
4
|
+
|
5
|
+
To get the original Luhn exercise, run `exercism fetch rust luhn`
|
6
|
+
|
7
|
+
To get the "Luhn: Using the From Trait" exercise, run `exercism fetch rust luhn-from`
|
8
|
+
|
9
|
+
In the original Luhn exercise you only validated strings, but the Luhn algorithm can be applied to integers as well.
|
10
|
+
|
11
|
+
In "Luhn: Using the From Trait" you implemented a From trait, which also required you to create a Luhn struct.
|
12
|
+
|
13
|
+
Instead of creating a Struct just to perform the validation, what if you you validated the primitives (i.e, String, u8, etc.) themselves?
|
14
|
+
|
15
|
+
In this exercise you'll create and implement a custom [trait](https://doc.rust-lang.org/book/traits.html) that performs the validation.
|
16
|
+
|
17
|
+
Note: It is [not idiomatic Rust to implement traits on on primitives](https://doc.rust-lang.org/book/traits.html#rules-for-implementing-traits). In this exercise we're showing something that you _can_ do, not something you _should_ do. If you find yourself implementing traits on primitives, perhaps you have a case of [Primitive Obsession](http://wiki.c2.com/?PrimitiveObsession).
|
@@ -0,0 +1,55 @@
|
|
1
|
+
pub trait Luhn {
|
2
|
+
fn valid_luhn(&self) -> bool;
|
3
|
+
}
|
4
|
+
|
5
|
+
impl Luhn for String {
|
6
|
+
fn valid_luhn(&self) -> bool {
|
7
|
+
if self.chars().any(|c| c.is_alphabetic()) || self.chars().count() == 1 {
|
8
|
+
return false;
|
9
|
+
}
|
10
|
+
|
11
|
+
self.chars()
|
12
|
+
.filter_map(|c| c.to_digit(10))
|
13
|
+
.rev()
|
14
|
+
.enumerate()
|
15
|
+
.map(|(index, digit)| if index % 2 == 0 { digit } else { digit * 2 })
|
16
|
+
.map(|digit| if digit > 9 { digit - 9 } else { digit })
|
17
|
+
.sum::<u32>() % 10 == 0
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
impl<'a> Luhn for &'a str {
|
22
|
+
fn valid_luhn(&self) -> bool {
|
23
|
+
String::from(*self).valid_luhn()
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
impl Luhn for u8 {
|
28
|
+
fn valid_luhn(&self) -> bool {
|
29
|
+
self.to_string().valid_luhn()
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
impl Luhn for u16 {
|
34
|
+
fn valid_luhn(&self) -> bool {
|
35
|
+
self.to_string().valid_luhn()
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
impl Luhn for u32 {
|
40
|
+
fn valid_luhn(&self) -> bool {
|
41
|
+
self.to_string().valid_luhn()
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
impl Luhn for u64 {
|
46
|
+
fn valid_luhn(&self) -> bool {
|
47
|
+
self.to_string().valid_luhn()
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
impl Luhn for usize {
|
52
|
+
fn valid_luhn(&self) -> bool {
|
53
|
+
self.to_string().valid_luhn()
|
54
|
+
}
|
55
|
+
}
|