trackler 2.2.1.150 → 2.2.1.151
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/java/exercises/bracket-push/src/test/java/BracketCheckerTest.java +14 -14
- data/tracks/java/exercises/difference-of-squares/src/test/java/DifferenceOfSquaresCalculatorTest.java +18 -18
- data/tracks/java/exercises/dominoes/.meta/version +1 -1
- data/tracks/java/exercises/tournament/.meta/version +1 -1
- data/tracks/powershell/exercises/hamming/HammingDifference.tests.ps1 +45 -27
- data/tracks/powershell/exercises/leap/LeapYear.tests.ps1 +7 -19
- data/tracks/rust/config.json +23 -0
- data/tracks/rust/exercises/hamming/example.rs +3 -3
- data/tracks/rust/exercises/hamming/src/lib.rs +3 -3
- data/tracks/rust/exercises/hamming/tests/hamming.rs +7 -7
- data/tracks/rust/exercises/reverse-string/.meta/hints.md +7 -0
- data/tracks/rust/exercises/reverse-string/Cargo.toml +3 -0
- data/tracks/rust/exercises/reverse-string/README.md +7 -0
- data/tracks/rust/exercises/reverse-string/tests/reverse-string.rs +8 -0
- data/tracks/rust/exercises/simple-cipher/.gitignore +3 -0
- data/tracks/rust/exercises/simple-cipher/Cargo.toml +6 -0
- data/tracks/rust/exercises/simple-cipher/README.md +121 -0
- data/tracks/rust/exercises/simple-cipher/example.rs +42 -0
- data/tracks/rust/exercises/simple-cipher/src/lib.rs +11 -0
- data/tracks/rust/exercises/simple-cipher/tests/simple-cipher.rs +171 -0
- data/tracks/rust/exercises/twofer/.gitignore +4 -0
- data/tracks/rust/exercises/twofer/Cargo.toml +5 -0
- data/tracks/rust/exercises/twofer/README.md +47 -0
- data/tracks/rust/exercises/twofer/example.rs +6 -0
- data/tracks/rust/exercises/twofer/src/lib.rs +3 -0
- data/tracks/rust/exercises/twofer/tests/two-fer.rs +19 -0
- data/tracks/swift/exercises/robot-name/Tests/RobotNameTests/RobotNameTests.swift +1 -1
- metadata +14 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 30a30beb6ce13ee8953a3d97725d3438584dac3e
|
4
|
+
data.tar.gz: fb727d81248459be3ac036e199a7b43421123228
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5cddff65e5fb0052b6deb69f7d17051a568ee7afa29a97693d234c55a96b7dc97d1419f11aff58473afe2f1dd2805773d4cc5507d044a1e6308bb69fed4d3a34
|
7
|
+
data.tar.gz: ee0d752600b90ba0019b2d34268fe5a33f2e8878c92d29b6b534868e29960b88dda836248fc4497abe9314706c6c04d5654204512f61a57b0dc231c307e2905f
|
data/lib/trackler/version.rb
CHANGED
@@ -8,98 +8,98 @@ public class BracketCheckerTest {
|
|
8
8
|
|
9
9
|
@Test
|
10
10
|
public void testPairedSquareBrackets() {
|
11
|
-
|
11
|
+
BracketChecker bracketChecker = new BracketChecker("[]");
|
12
12
|
assertTrue(bracketChecker.areBracketsMatchedAndNestedCorrectly());
|
13
13
|
}
|
14
14
|
|
15
15
|
@Ignore("Remove to run test")
|
16
16
|
@Test
|
17
17
|
public void testEmptyString() {
|
18
|
-
|
18
|
+
BracketChecker bracketChecker = new BracketChecker("");
|
19
19
|
assertTrue(bracketChecker.areBracketsMatchedAndNestedCorrectly());
|
20
20
|
}
|
21
21
|
|
22
22
|
@Ignore("Remove to run test")
|
23
23
|
@Test
|
24
24
|
public void testUnpairedBrackets() {
|
25
|
-
|
25
|
+
BracketChecker bracketChecker = new BracketChecker("[[");
|
26
26
|
assertFalse(bracketChecker.areBracketsMatchedAndNestedCorrectly());
|
27
27
|
}
|
28
28
|
|
29
29
|
@Ignore("Remove to run test")
|
30
30
|
@Test
|
31
31
|
public void testIncorrectlyOrderedBrackets() {
|
32
|
-
|
32
|
+
BracketChecker bracketChecker = new BracketChecker("}{");
|
33
33
|
assertFalse(bracketChecker.areBracketsMatchedAndNestedCorrectly());
|
34
34
|
}
|
35
35
|
|
36
36
|
@Ignore("Remove to run test")
|
37
37
|
@Test
|
38
38
|
public void testSingleOpenBracketWithIncorrectClosingBracket() {
|
39
|
-
|
39
|
+
BracketChecker bracketChecker = new BracketChecker("{]");
|
40
40
|
assertFalse(bracketChecker.areBracketsMatchedAndNestedCorrectly());
|
41
41
|
}
|
42
42
|
|
43
43
|
@Ignore("Remove to run test")
|
44
44
|
@Test
|
45
45
|
public void testPairedBracketsWithWhitespace() {
|
46
|
-
|
46
|
+
BracketChecker bracketChecker = new BracketChecker("{ }");
|
47
47
|
assertTrue(bracketChecker.areBracketsMatchedAndNestedCorrectly());
|
48
48
|
}
|
49
49
|
|
50
50
|
@Ignore("Remove to run test")
|
51
51
|
@Test
|
52
52
|
public void testSimpleNestedBrackets() {
|
53
|
-
|
53
|
+
BracketChecker bracketChecker = new BracketChecker("{[]}");
|
54
54
|
assertTrue(bracketChecker.areBracketsMatchedAndNestedCorrectly());
|
55
55
|
}
|
56
56
|
|
57
57
|
@Ignore("Remove to run test")
|
58
58
|
@Test
|
59
59
|
public void testSeveralPairedBrackets() {
|
60
|
-
|
60
|
+
BracketChecker bracketChecker = new BracketChecker("{}[]");
|
61
61
|
assertTrue(bracketChecker.areBracketsMatchedAndNestedCorrectly());
|
62
62
|
}
|
63
63
|
|
64
64
|
@Ignore("Remove to run test")
|
65
65
|
@Test
|
66
66
|
public void testPairedAndNestedBrackets() {
|
67
|
-
|
67
|
+
BracketChecker bracketChecker = new BracketChecker("([{}({}[])])");
|
68
68
|
assertTrue(bracketChecker.areBracketsMatchedAndNestedCorrectly());
|
69
69
|
}
|
70
70
|
|
71
71
|
@Ignore("Remove to run test")
|
72
72
|
@Test
|
73
73
|
public void testUnopenedClosingBracket() {
|
74
|
-
|
74
|
+
BracketChecker bracketChecker = new BracketChecker("{[)][]}");
|
75
75
|
assertFalse(bracketChecker.areBracketsMatchedAndNestedCorrectly());
|
76
76
|
}
|
77
77
|
|
78
78
|
@Ignore("Remove to run test")
|
79
79
|
@Test
|
80
80
|
public void testUnpairedAndNestedBracket() {
|
81
|
-
|
81
|
+
BracketChecker bracketChecker = new BracketChecker("([{])");
|
82
82
|
assertFalse(bracketChecker.areBracketsMatchedAndNestedCorrectly());
|
83
83
|
}
|
84
84
|
|
85
85
|
@Ignore("Remove to run test")
|
86
86
|
@Test
|
87
87
|
public void testPairedAndIncorrectlyNestedBrackets() {
|
88
|
-
|
88
|
+
BracketChecker bracketChecker = new BracketChecker("[({]})");
|
89
89
|
assertFalse(bracketChecker.areBracketsMatchedAndNestedCorrectly());
|
90
90
|
}
|
91
91
|
|
92
92
|
@Ignore("Remove to run test")
|
93
93
|
@Test
|
94
94
|
public void testValidMathExpression() {
|
95
|
-
|
95
|
+
BracketChecker bracketChecker = new BracketChecker("(((185 + 223.85) * 15) - 543)/2");
|
96
96
|
assertTrue(bracketChecker.areBracketsMatchedAndNestedCorrectly());
|
97
97
|
}
|
98
98
|
|
99
99
|
@Ignore("Remove to run test")
|
100
100
|
@Test
|
101
101
|
public void testValidComplexLaTeXExpression() {
|
102
|
-
|
102
|
+
BracketChecker bracketChecker = new BracketChecker(
|
103
103
|
"\\left(\\begin{array}{cc} \\frac{1}{3} & x\\\\ \\mathrm{e}^{x} &... x^2 \\end{array}\\right)");
|
104
104
|
|
105
105
|
assertTrue(bracketChecker.areBracketsMatchedAndNestedCorrectly());
|
@@ -15,72 +15,72 @@ public class DifferenceOfSquaresCalculatorTest {
|
|
15
15
|
|
16
16
|
@Test
|
17
17
|
public void testSquareOfSumUpToOne() {
|
18
|
-
|
19
|
-
|
18
|
+
int expected = 1;
|
19
|
+
int actual = calculator.computeSquareOfSumTo(1);
|
20
20
|
assertEquals(expected, actual);
|
21
21
|
}
|
22
22
|
|
23
23
|
@Ignore("Remove to run test")
|
24
24
|
@Test
|
25
25
|
public void testSquareOfSumUpToFive() {
|
26
|
-
|
27
|
-
|
26
|
+
int expected = 225;
|
27
|
+
int actual = calculator.computeSquareOfSumTo(5);
|
28
28
|
assertEquals(expected, actual);
|
29
29
|
}
|
30
30
|
|
31
31
|
@Ignore("Remove to run test")
|
32
32
|
@Test
|
33
33
|
public void testSquareOfSumUpToHundred() {
|
34
|
-
|
35
|
-
|
34
|
+
int expected = 25502500;
|
35
|
+
int actual = calculator.computeSquareOfSumTo(100);
|
36
36
|
assertEquals(expected, actual);
|
37
37
|
}
|
38
38
|
|
39
39
|
@Ignore("Remove to run test")
|
40
40
|
@Test
|
41
41
|
public void testSumOfSquaresUpToOne() {
|
42
|
-
|
43
|
-
|
42
|
+
int expected = 1;
|
43
|
+
int actual = calculator.computeSumOfSquaresTo(1);
|
44
44
|
assertEquals(expected, actual);
|
45
45
|
}
|
46
46
|
|
47
47
|
@Ignore("Remove to run test")
|
48
48
|
@Test
|
49
49
|
public void testSumOfSquaresUpToFive() {
|
50
|
-
|
51
|
-
|
50
|
+
int expected = 55;
|
51
|
+
int actual = calculator.computeSumOfSquaresTo(5);
|
52
52
|
assertEquals(expected, actual);
|
53
53
|
}
|
54
54
|
|
55
55
|
@Ignore("Remove to run test")
|
56
56
|
@Test
|
57
57
|
public void testSumOfSquaresUpToHundred() {
|
58
|
-
|
59
|
-
|
58
|
+
int expected = 338350;
|
59
|
+
int actual = calculator.computeSumOfSquaresTo(100);
|
60
60
|
assertEquals(expected, actual);
|
61
61
|
}
|
62
62
|
|
63
63
|
@Ignore("Remove to run test")
|
64
64
|
@Test
|
65
65
|
public void testDifferenceOfSquaresUpToOne() {
|
66
|
-
|
67
|
-
|
66
|
+
int expected = 0;
|
67
|
+
int actual = calculator.computeDifferenceOfSquares(1);
|
68
68
|
assertEquals(expected, actual);
|
69
69
|
}
|
70
70
|
|
71
71
|
@Ignore("Remove to run test")
|
72
72
|
@Test
|
73
73
|
public void testDifferenceOfSquaresUpToFive() {
|
74
|
-
|
75
|
-
|
74
|
+
int expected = 170;
|
75
|
+
int actual = calculator.computeDifferenceOfSquares(5);
|
76
76
|
assertEquals(expected, actual);
|
77
77
|
}
|
78
78
|
|
79
79
|
@Ignore("Remove to run test")
|
80
80
|
@Test
|
81
81
|
public void testDifferenceOfSquaresUpToHundred() {
|
82
|
-
|
83
|
-
|
82
|
+
int expected = 25164150;
|
83
|
+
int actual = calculator.computeDifferenceOfSquares(100);
|
84
84
|
assertEquals(expected, actual);
|
85
85
|
}
|
86
86
|
|
@@ -1,2 +1,2 @@
|
|
1
|
-
1.0
|
1
|
+
2.1.0
|
2
2
|
|
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.4.0
|
@@ -1,65 +1,83 @@
|
|
1
|
-
$
|
2
|
-
$
|
3
|
-
. "$here\$sut"
|
1
|
+
$ExercisePath = Split-Path -Parent $MyInvocation.MyCommand.Path
|
2
|
+
$ScriptFile = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.tests\.', '.'
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
$CommandName = "Get-HammingDifference"
|
5
|
+
|
6
|
+
# Remove the function if its already found
|
7
|
+
If (Get-Command $CommandName -ErrorAction SilentlyContinue){
|
8
|
+
Write-Verbose "Removing the existing $CommandName function from memory as it is already loaded"
|
9
|
+
Remove-Item -Path "Function:\$CommandName"
|
10
|
+
}
|
11
|
+
|
12
|
+
# Load the script file
|
13
|
+
If (Test-Path "$ExercisePath\$ScriptFile"){
|
14
|
+
Write-Output ("Loading: {0}" -f "$ExercisePath\$ScriptFile")
|
15
|
+
. ("$ExercisePath\$ScriptFile")
|
16
|
+
}
|
17
|
+
Else {
|
18
|
+
# Display an error and stop the tests
|
19
|
+
Write-Error "The file $ScriptFile was not found. You need to create your answer in a file named $ScriptFile" -ErrorAction Stop
|
20
|
+
}
|
21
|
+
|
22
|
+
Describe "Get-Hamming Test cases" {
|
23
|
+
|
24
|
+
It "Empty strands" {
|
25
|
+
Get-HammingDifference '' '' | Should be 0
|
26
|
+
}
|
27
|
+
|
28
|
+
It "Empty strands" {
|
29
|
+
Get-HammingDifference 'A' 'A' | Should be 0
|
8
30
|
}
|
9
31
|
|
10
|
-
It "
|
32
|
+
It "Long identical strands" {
|
11
33
|
Get-HammingDifference "GGACTGA" "GGACTGA" | Should be 0
|
12
34
|
}
|
13
35
|
|
14
|
-
It "
|
36
|
+
It "Complete distance in single nucleotide strands" {
|
15
37
|
Get-HammingDifference "A" "G" | Should be 1
|
16
38
|
}
|
17
39
|
|
18
|
-
It "
|
40
|
+
It "Complete distance in small strands" {
|
19
41
|
Get-HammingDifference "AG" "CT" | Should be 2
|
20
42
|
}
|
21
43
|
|
22
|
-
It "
|
44
|
+
It "Small distance in small strands" {
|
23
45
|
Get-HammingDifference "AT" "CT" | Should be 1
|
24
46
|
}
|
25
47
|
|
26
|
-
It "
|
48
|
+
It "Small distance" {
|
27
49
|
Get-HammingDifference "GGACG" "GGTCG" | Should be 1
|
28
50
|
}
|
29
51
|
|
30
|
-
It "
|
52
|
+
It "Small distance in long strands" {
|
31
53
|
Get-HammingDifference "ACCAGGG" "ACTATGG" | Should be 2
|
32
54
|
}
|
33
55
|
|
34
|
-
It "
|
35
|
-
Get-HammingDifference "
|
56
|
+
It "Non-unique character in first strand" {
|
57
|
+
Get-HammingDifference "AAG" "AAA" | Should be 1
|
36
58
|
}
|
37
59
|
|
38
|
-
It "
|
39
|
-
Get-HammingDifference "
|
60
|
+
It "Non-unique character in second strand" {
|
61
|
+
Get-HammingDifference "AAA" "AAG" | Should be 1
|
40
62
|
}
|
41
63
|
|
42
|
-
It "
|
64
|
+
It "Same nucleotides in different positions" {
|
43
65
|
Get-HammingDifference "TAG" "GAT" | Should be 2
|
44
66
|
}
|
45
67
|
|
46
|
-
It "
|
68
|
+
It "Large distance" {
|
47
69
|
Get-HammingDifference "GATACA" "GCATAA" | Should be 4
|
48
70
|
}
|
49
71
|
|
50
|
-
It "
|
72
|
+
It "Large distance in off-by-one strand" {
|
51
73
|
Get-HammingDifference "GGACGGATTCTG" "AGGACGGATTCT" | Should be 9
|
52
74
|
}
|
53
75
|
|
54
|
-
It "
|
55
|
-
Get-HammingDifference "" "" | Should be
|
56
|
-
}
|
57
|
-
|
58
|
-
It "tests disallow first strand longer" {
|
59
|
-
{ Get-HammingDifference "AATG" "AAA" } | Should Throw "Mismatching string lengths"
|
76
|
+
It "Disallow first strand longer" {
|
77
|
+
{ Get-HammingDifference "AATG" "AAA" } | Should Throw "Left and right strands must be of equal length."
|
60
78
|
}
|
61
79
|
|
62
|
-
It "
|
63
|
-
{ Get-HammingDifference "ATA" "AGTG" } | Should Throw "
|
80
|
+
It "Disallow second strand longer" {
|
81
|
+
{ Get-HammingDifference "ATA" "AGTG" } | Should Throw "Left and right strands must be of equal length."
|
64
82
|
}
|
65
83
|
}
|
@@ -3,31 +3,19 @@ $sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.tests\.', '.'
|
|
3
3
|
. "$here\$sut"
|
4
4
|
|
5
5
|
Describe "LeapYear Tests" {
|
6
|
-
It "
|
7
|
-
Test-LeapYear(
|
8
|
-
}
|
9
|
-
|
10
|
-
It "tests standard and odd year" {
|
11
|
-
Test-LeapYear(1997) | Should be $false
|
12
|
-
}
|
13
|
-
|
14
|
-
It "tests standard even year" {
|
15
|
-
Test-LeapYear(1998) | Should be $false
|
16
|
-
}
|
17
|
-
|
18
|
-
It "tests standard ninteenth century" {
|
19
|
-
Test-LeapYear(1900) | Should be $false
|
6
|
+
It "Year not divisible by 4: common year" {
|
7
|
+
Test-LeapYear(2015) | Should be $false
|
20
8
|
}
|
21
9
|
|
22
|
-
It "
|
23
|
-
Test-LeapYear(
|
10
|
+
It "Year divisible by 4, not divisible by 100: leap year" {
|
11
|
+
Test-LeapYear(1996) | Should be $true
|
24
12
|
}
|
25
13
|
|
26
|
-
It "
|
27
|
-
Test-LeapYear(
|
14
|
+
It "Year divisible by 100, not divisible by 400: common year" {
|
15
|
+
Test-LeapYear(2100) | Should be $false
|
28
16
|
}
|
29
17
|
|
30
|
-
It "
|
18
|
+
It "Year divisible by 400: leap year" {
|
31
19
|
Test-LeapYear(2000) | Should be $true
|
32
20
|
}
|
33
21
|
}
|
data/tracks/rust/config.json
CHANGED
@@ -18,6 +18,17 @@
|
|
18
18
|
"println"
|
19
19
|
]
|
20
20
|
},
|
21
|
+
{
|
22
|
+
"slug": "twofer",
|
23
|
+
"uuid": "c6631a2c-4632-11e8-842f-0ed5f89f718b",
|
24
|
+
"core": false,
|
25
|
+
"unlocked_by": null,
|
26
|
+
"difficulty": 1,
|
27
|
+
"topics": [
|
28
|
+
"match",
|
29
|
+
"strings"
|
30
|
+
]
|
31
|
+
},
|
21
32
|
{
|
22
33
|
"slug": "gigasecond",
|
23
34
|
"uuid": "f880b1ef-8f66-41f3-bb89-f39a4ed592a2",
|
@@ -431,6 +442,18 @@
|
|
431
442
|
"str_vs_string"
|
432
443
|
]
|
433
444
|
},
|
445
|
+
{
|
446
|
+
"slug": "simple-cipher",
|
447
|
+
"uuid": "f424a350-50bd-11e8-9c2d-fa7ae01bbebc",
|
448
|
+
"core": false,
|
449
|
+
"unlocked_by": null,
|
450
|
+
"difficulty": 4,
|
451
|
+
"topics": [
|
452
|
+
"ascii",
|
453
|
+
"chars",
|
454
|
+
"str_vs_string"
|
455
|
+
]
|
456
|
+
},
|
434
457
|
{
|
435
458
|
"slug": "etl",
|
436
459
|
"uuid": "0c8eeef7-4bab-4cf9-9047-c208b5618312",
|
@@ -1,7 +1,7 @@
|
|
1
|
-
pub fn hamming_distance(a
|
1
|
+
pub fn hamming_distance(a: &str, b: &str) -> Option<usize> {
|
2
2
|
if a.len() != b.len() {
|
3
|
-
return
|
3
|
+
return None;
|
4
4
|
}
|
5
5
|
|
6
|
-
|
6
|
+
Some(a.chars().zip(b.chars()).filter(|&(a, b)| a != b).count())
|
7
7
|
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/// Return the Hamming distance between the strings,
|
2
|
-
/// or
|
3
|
-
pub fn hamming_distance(s1: &str, s2: &str) ->
|
2
|
+
/// or None if the lengths are mismatched.
|
3
|
+
pub fn hamming_distance(s1: &str, s2: &str) -> Option<usize> {
|
4
4
|
unimplemented!("What is the Hamming Distance between {:?} and {:?}",
|
5
5
|
s1, s2);
|
6
|
-
}
|
6
|
+
}
|
@@ -2,41 +2,41 @@ extern crate hamming;
|
|
2
2
|
|
3
3
|
#[test]
|
4
4
|
fn test_no_difference_between_empty_strands() {
|
5
|
-
assert_eq!(hamming::hamming_distance("", ""),
|
5
|
+
assert_eq!(hamming::hamming_distance("", ""), Some(0));
|
6
6
|
}
|
7
7
|
|
8
8
|
#[test]
|
9
9
|
#[ignore]
|
10
10
|
fn test_no_difference_between_identical_strands() {
|
11
|
-
assert_eq!(hamming::hamming_distance("GGACTGA", "GGACTGA"),
|
11
|
+
assert_eq!(hamming::hamming_distance("GGACTGA", "GGACTGA"), Some(0));
|
12
12
|
}
|
13
13
|
|
14
14
|
#[test]
|
15
15
|
#[ignore]
|
16
16
|
fn test_complete_hamming_distance_in_small_strand() {
|
17
|
-
assert_eq!(hamming::hamming_distance("ACT", "GGA"),
|
17
|
+
assert_eq!(hamming::hamming_distance("ACT", "GGA"), Some(3));
|
18
18
|
}
|
19
19
|
|
20
20
|
#[test]
|
21
21
|
#[ignore]
|
22
22
|
fn test_small_hamming_distance_in_the_middle_somewhere() {
|
23
|
-
assert_eq!(hamming::hamming_distance("GGACG", "GGTCG"),
|
23
|
+
assert_eq!(hamming::hamming_distance("GGACG", "GGTCG"), Some(1));
|
24
24
|
}
|
25
25
|
|
26
26
|
#[test]
|
27
27
|
#[ignore]
|
28
28
|
fn test_larger_distance() {
|
29
|
-
assert_eq!(hamming::hamming_distance("ACCAGGG", "ACTATGG"),
|
29
|
+
assert_eq!(hamming::hamming_distance("ACCAGGG", "ACTATGG"), Some(2));
|
30
30
|
}
|
31
31
|
|
32
32
|
#[test]
|
33
33
|
#[ignore]
|
34
34
|
fn test_first_string_is_longer() {
|
35
|
-
|
35
|
+
assert_eq!(hamming::hamming_distance("AAA", "AA"), None);
|
36
36
|
}
|
37
37
|
|
38
38
|
#[test]
|
39
39
|
#[ignore]
|
40
40
|
fn test_second_string_is_longer() {
|
41
|
-
|
41
|
+
assert_eq!(hamming::hamming_distance("A", "AA"), None);
|
42
42
|
}
|
@@ -1,3 +1,10 @@
|
|
1
1
|
## Bonus
|
2
2
|
Test your function on this string: `uüu` and see what happens. Try to write a function that properly
|
3
3
|
reverses this string. Hint: grapheme clusters
|
4
|
+
|
5
|
+
To get the bonus test to run, remove the ignore flag (`#[ignore]`) from the
|
6
|
+
last test, and execute the tests with:
|
7
|
+
|
8
|
+
```bash
|
9
|
+
$ cargo test --features grapheme
|
10
|
+
```
|
@@ -10,6 +10,13 @@ output: "looc"
|
|
10
10
|
Test your function on this string: `uüu` and see what happens. Try to write a function that properly
|
11
11
|
reverses this string. Hint: grapheme clusters
|
12
12
|
|
13
|
+
To get the bonus test to run, remove the ignore flag (`#[ignore]`) from the
|
14
|
+
last test, and execute the tests with:
|
15
|
+
|
16
|
+
```bash
|
17
|
+
$ cargo test --features grapheme
|
18
|
+
```
|
19
|
+
|
13
20
|
|
14
21
|
## Rust Installation
|
15
22
|
|
@@ -62,3 +62,11 @@ fn test_a_palindrome() {
|
|
62
62
|
fn test_wide_characters() {
|
63
63
|
process_reverse_case("子猫", "猫子");
|
64
64
|
}
|
65
|
+
|
66
|
+
#[test]
|
67
|
+
#[ignore]
|
68
|
+
#[cfg(feature="grapheme")]
|
69
|
+
/// grapheme clusters
|
70
|
+
fn test_grapheme_clusters() {
|
71
|
+
process_reverse_case("uüu", "uüu");
|
72
|
+
}
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# Simple Cipher
|
2
|
+
|
3
|
+
Implement a simple shift cipher like Caesar and a more secure substitution cipher.
|
4
|
+
|
5
|
+
## Step 1
|
6
|
+
|
7
|
+
"If he had anything confidential to say, he wrote it in cipher, that is,
|
8
|
+
by so changing the order of the letters of the alphabet, that not a word
|
9
|
+
could be made out. If anyone wishes to decipher these, and get at their
|
10
|
+
meaning, he must substitute the fourth letter of the alphabet, namely D,
|
11
|
+
for A, and so with the others."
|
12
|
+
—Suetonius, Life of Julius Caesar
|
13
|
+
|
14
|
+
Ciphers are very straight-forward algorithms that allow us to render
|
15
|
+
text less readable while still allowing easy deciphering. They are
|
16
|
+
vulnerable to many forms of cryptoanalysis, but we are lucky that
|
17
|
+
generally our little sisters are not cryptoanalysts.
|
18
|
+
|
19
|
+
The Caesar Cipher was used for some messages from Julius Caesar that
|
20
|
+
were sent afield. Now Caesar knew that the cipher wasn't very good, but
|
21
|
+
he had one ally in that respect: almost nobody could read well. So even
|
22
|
+
being a couple letters off was sufficient so that people couldn't
|
23
|
+
recognize the few words that they did know.
|
24
|
+
|
25
|
+
Your task is to create a simple shift cipher like the Caesar Cipher.
|
26
|
+
This image is a great example of the Caesar Cipher:
|
27
|
+
|
28
|
+
![Caesar Cipher][1]
|
29
|
+
|
30
|
+
For example:
|
31
|
+
|
32
|
+
Giving "iamapandabear" as input to the encode function returns the cipher "ldpdsdqgdehdu". Obscure enough to keep our message secret in transit.
|
33
|
+
|
34
|
+
When "ldpdsdqgdehdu" is put into the decode function it would return
|
35
|
+
the original "iamapandabear" letting your friend read your original
|
36
|
+
message.
|
37
|
+
|
38
|
+
## Step 2
|
39
|
+
|
40
|
+
Shift ciphers are no fun though when your kid sister figures it out. Try
|
41
|
+
amending the code to allow us to specify a key and use that for the
|
42
|
+
shift distance. This is called a substitution cipher.
|
43
|
+
|
44
|
+
Here's an example:
|
45
|
+
|
46
|
+
Given the key "aaaaaaaaaaaaaaaaaa", encoding the string "iamapandabear"
|
47
|
+
would return the original "iamapandabear".
|
48
|
+
|
49
|
+
Given the key "ddddddddddddddddd", encoding our string "iamapandabear"
|
50
|
+
would return the obscured "ldpdsdqgdehdu"
|
51
|
+
|
52
|
+
In the example above, we've set a = 0 for the key value. So when the
|
53
|
+
plaintext is added to the key, we end up with the same message coming
|
54
|
+
out. So "aaaa" is not an ideal key. But if we set the key to "dddd", we
|
55
|
+
would get the same thing as the Caesar Cipher.
|
56
|
+
|
57
|
+
## Step 3
|
58
|
+
|
59
|
+
The weakest link in any cipher is the human being. Let's make your
|
60
|
+
substitution cipher a little more fault tolerant by providing a source
|
61
|
+
of randomness and ensuring that the key contains only lowercase letters.
|
62
|
+
|
63
|
+
If someone doesn't submit a key at all, generate a truly random key of
|
64
|
+
at least 100 characters in length.
|
65
|
+
|
66
|
+
If the key submitted is not composed only of lowercase letters, your
|
67
|
+
solution should handle the error in a language-appropriate way.
|
68
|
+
|
69
|
+
## Extensions
|
70
|
+
|
71
|
+
Shift ciphers work by making the text slightly odd, but are vulnerable
|
72
|
+
to frequency analysis. Substitution ciphers help that, but are still
|
73
|
+
very vulnerable when the key is short or if spaces are preserved. Later
|
74
|
+
on you'll see one solution to this problem in the exercise
|
75
|
+
"crypto-square".
|
76
|
+
|
77
|
+
If you want to go farther in this field, the questions begin to be about
|
78
|
+
how we can exchange keys in a secure way. Take a look at [Diffie-Hellman
|
79
|
+
on Wikipedia][dh] for one of the first implementations of this scheme.
|
80
|
+
|
81
|
+
[1]: https://upload.wikimedia.org/wikipedia/commons/thumb/4/4a/Caesar_cipher_left_shift_of_3.svg/320px-Caesar_cipher_left_shift_of_3.svg.png
|
82
|
+
[dh]: http://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange
|
83
|
+
|
84
|
+
## Rust Installation
|
85
|
+
|
86
|
+
Refer to the [exercism help page][help-page] for Rust installation and learning
|
87
|
+
resources.
|
88
|
+
|
89
|
+
## Writing the Code
|
90
|
+
|
91
|
+
Execute the tests with:
|
92
|
+
|
93
|
+
```bash
|
94
|
+
$ cargo test
|
95
|
+
```
|
96
|
+
|
97
|
+
All but the first test have been ignored. After you get the first test to
|
98
|
+
pass, remove the ignore flag (`#[ignore]`) from the next test and get the tests
|
99
|
+
to pass again. The test file is located in the `tests` directory. You can
|
100
|
+
also remove the ignore flag from all the tests to get them to run all at once
|
101
|
+
if you wish.
|
102
|
+
|
103
|
+
Make sure to read the [Modules](https://doc.rust-lang.org/book/second-edition/ch07-00-modules.html) chapter if you
|
104
|
+
haven't already, it will help you with organizing your files.
|
105
|
+
|
106
|
+
## Feedback, Issues, Pull Requests
|
107
|
+
|
108
|
+
The [exercism/rust](https://github.com/exercism/rust) repository on GitHub is the home for all of the Rust exercises. If you have feedback about an exercise, or want to help implement new exercises, head over there and create an issue. Members of the rust track team are happy to help!
|
109
|
+
|
110
|
+
If you want to know more about Exercism, take a look at the [contribution guide](https://github.com/exercism/docs/blob/master/contributing-to-language-tracks/README.md).
|
111
|
+
|
112
|
+
[help-page]: http://exercism.io/languages/rust
|
113
|
+
[modules]: https://doc.rust-lang.org/book/second-edition/ch07-00-modules.html
|
114
|
+
[cargo]: https://doc.rust-lang.org/book/second-edition/ch14-00-more-about-cargo.html
|
115
|
+
|
116
|
+
## Source
|
117
|
+
|
118
|
+
Substitution Cipher at Wikipedia [http://en.wikipedia.org/wiki/Substitution_cipher](http://en.wikipedia.org/wiki/Substitution_cipher)
|
119
|
+
|
120
|
+
## Submitting Incomplete Solutions
|
121
|
+
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
@@ -0,0 +1,42 @@
|
|
1
|
+
extern crate rand;
|
2
|
+
use rand::Rng;
|
3
|
+
|
4
|
+
pub fn encode_random(s: &str) -> (String, String) {
|
5
|
+
let mut r = rand::thread_rng();
|
6
|
+
let mut key = String::new();
|
7
|
+
for _ in 0..100 {
|
8
|
+
key.push(char::from('a' as u8 + r.gen_range(0, 26)));
|
9
|
+
}
|
10
|
+
let encoded = encode(&key, s);
|
11
|
+
(key, encoded.unwrap())
|
12
|
+
}
|
13
|
+
|
14
|
+
pub fn encode(key: &str, s: &str) -> Option<String> {
|
15
|
+
shift(key, s, 1)
|
16
|
+
}
|
17
|
+
|
18
|
+
pub fn decode(key: &str, s: &str) -> Option<String> {
|
19
|
+
shift(key, s, -1)
|
20
|
+
}
|
21
|
+
|
22
|
+
fn shift(key: &str, s: &str, dir: i8) -> Option<String> {
|
23
|
+
if key.is_empty() {
|
24
|
+
return None;
|
25
|
+
}
|
26
|
+
let mut o = String::new();
|
27
|
+
let mut i = 0;
|
28
|
+
let mut key_arr = Vec::new();
|
29
|
+
for c in key.chars() {
|
30
|
+
if !c.is_ascii_lowercase() {
|
31
|
+
return None;
|
32
|
+
}
|
33
|
+
key_arr.push(c);
|
34
|
+
}
|
35
|
+
for c in s.chars() {
|
36
|
+
let shift = key_arr[i % key_arr.len()] as i8 - 'a' as i8;
|
37
|
+
let n = ((c as i8 - 'a' as i8 + dir * shift) % 26 + 26) % 26;
|
38
|
+
o.push(char::from('a' as u8 + n as u8));
|
39
|
+
i += 1;
|
40
|
+
}
|
41
|
+
Some(o)
|
42
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
pub fn encode(key: &str, s: &str) -> Option<String> {
|
2
|
+
unimplemented!("Use {} to encode {} using shift cipher",key,s)
|
3
|
+
}
|
4
|
+
|
5
|
+
pub fn decode(key: &str, s: &str) -> Option<String> {
|
6
|
+
unimplemented!("Use {} to decode {} using shift cipher",key,s)
|
7
|
+
}
|
8
|
+
|
9
|
+
pub fn encode_random(s: &str) -> (String, String) {
|
10
|
+
unimplemented!("Generate random key with only a-z chars and encode {}. Return tuple (key, encoded s)",s)
|
11
|
+
}
|
@@ -0,0 +1,171 @@
|
|
1
|
+
extern crate simple_cipher;
|
2
|
+
use simple_cipher::*;
|
3
|
+
use std::collections::HashSet;
|
4
|
+
|
5
|
+
const PLAIN_TEXT: &str = "thisismysecret";
|
6
|
+
const KEY: &str = "abcdefghij";
|
7
|
+
|
8
|
+
|
9
|
+
#[test]
|
10
|
+
fn cipher_can_encode_with_given_key() {
|
11
|
+
assert_eq!(encode(KEY, "aaaaaaaaaa"), Some(KEY.to_string()));
|
12
|
+
}
|
13
|
+
|
14
|
+
#[test]
|
15
|
+
#[ignore]
|
16
|
+
fn cipher_can_decode_with_given_key() {
|
17
|
+
assert_eq!(decode(KEY, "abcdefghij"), Some("aaaaaaaaaa".to_string()));
|
18
|
+
}
|
19
|
+
|
20
|
+
#[test]
|
21
|
+
#[ignore]
|
22
|
+
fn cipher_is_reversible_given_key() {
|
23
|
+
assert_eq!(
|
24
|
+
decode(KEY, &encode(KEY, PLAIN_TEXT).unwrap()),
|
25
|
+
Some(PLAIN_TEXT.to_string())
|
26
|
+
);
|
27
|
+
}
|
28
|
+
|
29
|
+
#[test]
|
30
|
+
#[ignore]
|
31
|
+
fn cipher_can_double_shift_encode() {
|
32
|
+
let plain_text = "iamapandabear";
|
33
|
+
assert_eq!(
|
34
|
+
encode(plain_text, plain_text),
|
35
|
+
Some("qayaeaagaciai".to_string())
|
36
|
+
);
|
37
|
+
}
|
38
|
+
|
39
|
+
#[test]
|
40
|
+
#[ignore]
|
41
|
+
fn cipher_can_wrap_encode() {
|
42
|
+
assert_eq!(encode(KEY, "zzzzzzzzzz"), Some("zabcdefghi".to_string()));
|
43
|
+
}
|
44
|
+
|
45
|
+
#[test]
|
46
|
+
#[ignore]
|
47
|
+
fn cipher_can_encode_a_message_that_is_shorter_than_the_key() {
|
48
|
+
assert_eq!(encode(KEY, "aaaaa"), Some("abcde".to_string()));
|
49
|
+
}
|
50
|
+
|
51
|
+
#[test]
|
52
|
+
#[ignore]
|
53
|
+
fn cipher_can_decode_a_message_that_is_shorter_than_the_key() {
|
54
|
+
assert_eq!(decode(KEY, "abcde"), Some("aaaaa".to_string()));
|
55
|
+
}
|
56
|
+
|
57
|
+
#[test]
|
58
|
+
#[ignore]
|
59
|
+
fn encode_returns_none_with_an_all_caps_key() {
|
60
|
+
let key = "ABCDEF";
|
61
|
+
assert_eq!(encode(key, PLAIN_TEXT), None);
|
62
|
+
}
|
63
|
+
|
64
|
+
#[test]
|
65
|
+
#[ignore]
|
66
|
+
fn encode_returns_none_with_an_any_caps_key() {
|
67
|
+
let key = "abcdEFg";
|
68
|
+
assert_eq!(encode(key, PLAIN_TEXT), None);
|
69
|
+
}
|
70
|
+
|
71
|
+
#[test]
|
72
|
+
#[ignore]
|
73
|
+
fn encode_returns_none_with_numeric_key() {
|
74
|
+
let key = "12345";
|
75
|
+
assert_eq!(encode(key, PLAIN_TEXT), None);
|
76
|
+
}
|
77
|
+
|
78
|
+
#[test]
|
79
|
+
#[ignore]
|
80
|
+
fn encode_returns_none_with_any_numeric_key() {
|
81
|
+
let key = "abcd345ef";
|
82
|
+
assert_eq!(encode(key, PLAIN_TEXT), None);
|
83
|
+
}
|
84
|
+
|
85
|
+
#[test]
|
86
|
+
#[ignore]
|
87
|
+
fn encode_returns_none_with_empty_key() {
|
88
|
+
let key = "";
|
89
|
+
assert_eq!(encode(key, PLAIN_TEXT), None);
|
90
|
+
}
|
91
|
+
|
92
|
+
#[test]
|
93
|
+
#[ignore]
|
94
|
+
fn decode_returns_none_with_an_all_caps_key() {
|
95
|
+
let key = "ABCDEF";
|
96
|
+
assert_eq!(decode(key, PLAIN_TEXT), None);
|
97
|
+
}
|
98
|
+
|
99
|
+
#[test]
|
100
|
+
#[ignore]
|
101
|
+
fn decode_returns_none_with_an_any_caps_key() {
|
102
|
+
let key = "abcdEFg";
|
103
|
+
assert_eq!(decode(key, PLAIN_TEXT), None);
|
104
|
+
}
|
105
|
+
|
106
|
+
#[test]
|
107
|
+
#[ignore]
|
108
|
+
fn decode_returns_none_with_numeric_key() {
|
109
|
+
let key = "12345";
|
110
|
+
assert_eq!(decode(key, PLAIN_TEXT), None);
|
111
|
+
}
|
112
|
+
|
113
|
+
#[test]
|
114
|
+
#[ignore]
|
115
|
+
fn decode_returns_none_with_any_numeric_key() {
|
116
|
+
let key = "abcd345ef";
|
117
|
+
assert_eq!(decode(key, PLAIN_TEXT), None);
|
118
|
+
}
|
119
|
+
|
120
|
+
#[test]
|
121
|
+
#[ignore]
|
122
|
+
fn decode_returns_none_with_empty_key() {
|
123
|
+
let key = "";
|
124
|
+
assert_eq!(decode(key, PLAIN_TEXT), None);
|
125
|
+
}
|
126
|
+
|
127
|
+
#[test]
|
128
|
+
#[ignore]
|
129
|
+
fn encode_random_uses_key_made_of_letters() {
|
130
|
+
let (k, _) = encode_random(PLAIN_TEXT);
|
131
|
+
assert!(k.chars().all(|c| c.is_ascii_lowercase()));
|
132
|
+
}
|
133
|
+
|
134
|
+
#[test]
|
135
|
+
#[ignore]
|
136
|
+
fn encode_random_uses_key_of_100_characters_or_more() {
|
137
|
+
let (k, _) = encode_random(PLAIN_TEXT);
|
138
|
+
assert!(k.len() >= 100);
|
139
|
+
}
|
140
|
+
|
141
|
+
#[test]
|
142
|
+
#[ignore]
|
143
|
+
fn encode_random_uses_randomly_generated_key() {
|
144
|
+
let mut keys = HashSet::new();
|
145
|
+
let trials = 100;
|
146
|
+
for _ in 0..trials {
|
147
|
+
keys.insert(encode_random(PLAIN_TEXT).0);
|
148
|
+
}
|
149
|
+
assert_eq!(keys.len(), trials);
|
150
|
+
}
|
151
|
+
|
152
|
+
#[test]
|
153
|
+
#[ignore]
|
154
|
+
fn encode_random_can_encode() {
|
155
|
+
let (k, encoded) = encode_random("aaaaaaaaaa");
|
156
|
+
assert_eq!(encoded, k.split_at(10).0);
|
157
|
+
}
|
158
|
+
|
159
|
+
#[test]
|
160
|
+
#[ignore]
|
161
|
+
fn encode_random_can_decode() {
|
162
|
+
let (k, _) = encode_random("aaaaaaaaaa");
|
163
|
+
assert_eq!(decode(&k, k.split_at(10).0), Some("aaaaaaaaaa".to_string()));
|
164
|
+
}
|
165
|
+
|
166
|
+
#[test]
|
167
|
+
#[ignore]
|
168
|
+
fn encode_random_is_reversible() {
|
169
|
+
let (k, encoded) = encode_random(PLAIN_TEXT);
|
170
|
+
assert_eq!(decode(&k, &encoded), Some(PLAIN_TEXT.to_string()));
|
171
|
+
}
|
@@ -0,0 +1,47 @@
|
|
1
|
+
## Two-fer
|
2
|
+
|
3
|
+
`Two-fer` or `2-fer` is short for two for one. One for you and one for me.
|
4
|
+
|
5
|
+
```text
|
6
|
+
"One for X, one for me."
|
7
|
+
```
|
8
|
+
|
9
|
+
When X is a name or "you".
|
10
|
+
|
11
|
+
If the given name is "Alice", the result should be "One for Alice, one for me."
|
12
|
+
If no name is given, the result should be "One for you, one for me."
|
13
|
+
|
14
|
+
## Rust Installation
|
15
|
+
|
16
|
+
Refer to the [exercism help page][help-page] for Rust installation and learning
|
17
|
+
resources.
|
18
|
+
|
19
|
+
## Writing the Code
|
20
|
+
|
21
|
+
Execute the tests with:
|
22
|
+
|
23
|
+
```bash
|
24
|
+
$ cargo test
|
25
|
+
```
|
26
|
+
|
27
|
+
All but the first test have been ignored. After you get the first test to
|
28
|
+
pass, remove the ignore flag (`#[ignore]`) from the next test and get the tests
|
29
|
+
to pass again. The test file is located in the `tests` directory. You can
|
30
|
+
also remove the ignore flag from all the tests to get them to run all at once
|
31
|
+
if you wish.
|
32
|
+
|
33
|
+
Make sure to read the [Modules](https://doc.rust-lang.org/book/second-edition/ch07-00-modules.html) chapter if you
|
34
|
+
haven't already, it will help you with organizing your files.
|
35
|
+
|
36
|
+
## Feedback, Issues, Pull Requests
|
37
|
+
|
38
|
+
The [exercism/rust](https://github.com/exercism/rust) repository on GitHub is the home for all of the Rust exercises. If you have feedback about an exercise, or want to help implement new exercises, head over there and create an issue. Members of the rust track team are happy to help!
|
39
|
+
|
40
|
+
If you want to know more about Exercism, take a look at the [contribution guide](https://github.com/exercism/docs/blob/master/contributing-to-language-tracks/README.md).
|
41
|
+
|
42
|
+
[help-page]: http://exercism.io/languages/rust
|
43
|
+
[modules]: https://doc.rust-lang.org/book/second-edition/ch07-00-modules.html
|
44
|
+
[cargo]: https://doc.rust-lang.org/book/second-edition/ch14-00-more-about-cargo.html
|
45
|
+
|
46
|
+
## Submitting Incomplete Solutions
|
47
|
+
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
@@ -0,0 +1,19 @@
|
|
1
|
+
extern crate twofer;
|
2
|
+
use twofer::twofer;
|
3
|
+
|
4
|
+
#[test]
|
5
|
+
fn empty_string() {
|
6
|
+
assert_eq!(twofer(""), "One for you, one for me.");
|
7
|
+
}
|
8
|
+
|
9
|
+
#[test]
|
10
|
+
#[ignore]
|
11
|
+
fn alice() {
|
12
|
+
assert_eq!(twofer("Alice"), "One for Alice, one for me.");
|
13
|
+
}
|
14
|
+
|
15
|
+
#[test]
|
16
|
+
#[ignore]
|
17
|
+
fn bob() {
|
18
|
+
assert_eq!(twofer("Bob"), "One for Bob, one for me.");
|
19
|
+
}
|
@@ -14,7 +14,7 @@ import Foundation
|
|
14
14
|
|
15
15
|
class RobotNameTests: XCTestCase {
|
16
16
|
func robotNameIsCorrectlyFormatted(_ name: String) -> Bool {
|
17
|
-
let robotNameRegex = try? Regex(pattern: "\\A
|
17
|
+
let robotNameRegex = try? Regex(pattern: "\\A[A-Z]{2}\\d{3}\\z")
|
18
18
|
guard let matches = robotNameRegex?.matches(in: name, options: .withoutAnchoringBounds, range: NSRange(0..<name.utf16.count)) else { return false }
|
19
19
|
|
20
20
|
return matches.count > 0
|
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.2.1.
|
4
|
+
version: 2.2.1.151
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Katrina Owen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-05-
|
11
|
+
date: 2018-05-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubyzip
|
@@ -13389,6 +13389,12 @@ files:
|
|
13389
13389
|
- tracks/rust/exercises/sieve/example.rs
|
13390
13390
|
- tracks/rust/exercises/sieve/src/lib.rs
|
13391
13391
|
- tracks/rust/exercises/sieve/tests/sieve.rs
|
13392
|
+
- tracks/rust/exercises/simple-cipher/.gitignore
|
13393
|
+
- tracks/rust/exercises/simple-cipher/Cargo.toml
|
13394
|
+
- tracks/rust/exercises/simple-cipher/README.md
|
13395
|
+
- tracks/rust/exercises/simple-cipher/example.rs
|
13396
|
+
- tracks/rust/exercises/simple-cipher/src/lib.rs
|
13397
|
+
- tracks/rust/exercises/simple-cipher/tests/simple-cipher.rs
|
13392
13398
|
- tracks/rust/exercises/simple-linked-list/.gitignore
|
13393
13399
|
- tracks/rust/exercises/simple-linked-list/.meta/hints.md
|
13394
13400
|
- tracks/rust/exercises/simple-linked-list/Cargo.toml
|
@@ -13439,6 +13445,12 @@ files:
|
|
13439
13445
|
- tracks/rust/exercises/two-bucket/example.rs
|
13440
13446
|
- tracks/rust/exercises/two-bucket/src/lib.rs
|
13441
13447
|
- tracks/rust/exercises/two-bucket/tests/two-bucket.rs
|
13448
|
+
- tracks/rust/exercises/twofer/.gitignore
|
13449
|
+
- tracks/rust/exercises/twofer/Cargo.toml
|
13450
|
+
- tracks/rust/exercises/twofer/README.md
|
13451
|
+
- tracks/rust/exercises/twofer/example.rs
|
13452
|
+
- tracks/rust/exercises/twofer/src/lib.rs
|
13453
|
+
- tracks/rust/exercises/twofer/tests/two-fer.rs
|
13442
13454
|
- tracks/rust/exercises/variable-length-quantity/.gitignore
|
13443
13455
|
- tracks/rust/exercises/variable-length-quantity/Cargo.toml
|
13444
13456
|
- tracks/rust/exercises/variable-length-quantity/README.md
|