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.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/tracks/java/exercises/bracket-push/src/test/java/BracketCheckerTest.java +14 -14
  4. data/tracks/java/exercises/difference-of-squares/src/test/java/DifferenceOfSquaresCalculatorTest.java +18 -18
  5. data/tracks/java/exercises/dominoes/.meta/version +1 -1
  6. data/tracks/java/exercises/tournament/.meta/version +1 -1
  7. data/tracks/powershell/exercises/hamming/HammingDifference.tests.ps1 +45 -27
  8. data/tracks/powershell/exercises/leap/LeapYear.tests.ps1 +7 -19
  9. data/tracks/rust/config.json +23 -0
  10. data/tracks/rust/exercises/hamming/example.rs +3 -3
  11. data/tracks/rust/exercises/hamming/src/lib.rs +3 -3
  12. data/tracks/rust/exercises/hamming/tests/hamming.rs +7 -7
  13. data/tracks/rust/exercises/reverse-string/.meta/hints.md +7 -0
  14. data/tracks/rust/exercises/reverse-string/Cargo.toml +3 -0
  15. data/tracks/rust/exercises/reverse-string/README.md +7 -0
  16. data/tracks/rust/exercises/reverse-string/tests/reverse-string.rs +8 -0
  17. data/tracks/rust/exercises/simple-cipher/.gitignore +3 -0
  18. data/tracks/rust/exercises/simple-cipher/Cargo.toml +6 -0
  19. data/tracks/rust/exercises/simple-cipher/README.md +121 -0
  20. data/tracks/rust/exercises/simple-cipher/example.rs +42 -0
  21. data/tracks/rust/exercises/simple-cipher/src/lib.rs +11 -0
  22. data/tracks/rust/exercises/simple-cipher/tests/simple-cipher.rs +171 -0
  23. data/tracks/rust/exercises/twofer/.gitignore +4 -0
  24. data/tracks/rust/exercises/twofer/Cargo.toml +5 -0
  25. data/tracks/rust/exercises/twofer/README.md +47 -0
  26. data/tracks/rust/exercises/twofer/example.rs +6 -0
  27. data/tracks/rust/exercises/twofer/src/lib.rs +3 -0
  28. data/tracks/rust/exercises/twofer/tests/two-fer.rs +19 -0
  29. data/tracks/swift/exercises/robot-name/Tests/RobotNameTests/RobotNameTests.swift +1 -1
  30. metadata +14 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fed064cd5da037514165e2542ec5ffd18f0e98f7
4
- data.tar.gz: 594af9b0cc9536b966f3ad65814c53887e84001e
3
+ metadata.gz: 30a30beb6ce13ee8953a3d97725d3438584dac3e
4
+ data.tar.gz: fb727d81248459be3ac036e199a7b43421123228
5
5
  SHA512:
6
- metadata.gz: f16160c281a808804255cd278e5adcf659527c45bc5c326477f40bea126225eb414ae9890cfef6a6fc05720d3524c60952eda679654008419ba26c2fe1718cc6
7
- data.tar.gz: f417b67723e2398c1f10154fea8a4059b4506622285b5365d684f3ee9d785cfed60996e5364c5bbb59be1fe7b7e4e7807b86d9a7d0ea518af8a38fbcfae25fb1
6
+ metadata.gz: 5cddff65e5fb0052b6deb69f7d17051a568ee7afa29a97693d234c55a96b7dc97d1419f11aff58473afe2f1dd2805773d4cc5507d044a1e6308bb69fed4d3a34
7
+ data.tar.gz: ee0d752600b90ba0019b2d34268fe5a33f2e8878c92d29b6b534868e29960b88dda836248fc4497abe9314706c6c04d5654204512f61a57b0dc231c307e2905f
@@ -1,3 +1,3 @@
1
1
  module Trackler
2
- VERSION = "2.2.1.150"
2
+ VERSION = "2.2.1.151"
3
3
  end
@@ -8,98 +8,98 @@ public class BracketCheckerTest {
8
8
 
9
9
  @Test
10
10
  public void testPairedSquareBrackets() {
11
- final BracketChecker bracketChecker = new BracketChecker("[]");
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
- final BracketChecker bracketChecker = new BracketChecker("");
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
- final BracketChecker bracketChecker = new BracketChecker("[[");
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
- final BracketChecker bracketChecker = new BracketChecker("}{");
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
- final BracketChecker bracketChecker = new BracketChecker("{]");
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
- final BracketChecker bracketChecker = new BracketChecker("{ }");
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
- final BracketChecker bracketChecker = new BracketChecker("{[]}");
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
- final BracketChecker bracketChecker = new BracketChecker("{}[]");
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
- final BracketChecker bracketChecker = new BracketChecker("([{}({}[])])");
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
- final BracketChecker bracketChecker = new BracketChecker("{[)][]}");
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
- final BracketChecker bracketChecker = new BracketChecker("([{])");
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
- final BracketChecker bracketChecker = new BracketChecker("[({]})");
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
- final BracketChecker bracketChecker = new BracketChecker("(((185 + 223.85) * 15) - 543)/2");
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
- final BracketChecker bracketChecker = new BracketChecker(
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
- final int expected = 1;
19
- final int actual = calculator.computeSquareOfSumTo(1);
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
- final int expected = 225;
27
- final int actual = calculator.computeSquareOfSumTo(5);
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
- final int expected = 25502500;
35
- final int actual = calculator.computeSquareOfSumTo(100);
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
- final int expected = 1;
43
- final int actual = calculator.computeSumOfSquaresTo(1);
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
- final int expected = 55;
51
- final int actual = calculator.computeSumOfSquaresTo(5);
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
- final int expected = 338350;
59
- final int actual = calculator.computeSumOfSquaresTo(100);
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
- final int expected = 0;
67
- final int actual = calculator.computeDifferenceOfSquares(1);
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
- final int expected = 170;
75
- final int actual = calculator.computeDifferenceOfSquares(5);
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
- final int expected = 25164150;
83
- final int actual = calculator.computeDifferenceOfSquares(100);
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.0
1
+ 2.1.0
2
2
 
@@ -1 +1 @@
1
- 1.3.0
1
+ 1.4.0
@@ -1,65 +1,83 @@
1
- $here = Split-Path -Parent $MyInvocation.MyCommand.Path
2
- $sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.tests\.', '.'
3
- . "$here\$sut"
1
+ $ExercisePath = Split-Path -Parent $MyInvocation.MyCommand.Path
2
+ $ScriptFile = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.tests\.', '.'
4
3
 
5
- Describe "HammingTest" {
6
- It "tests identical strands" {
7
- Get-HammingDifference 'A' 'A' | Should be 0
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 "tests log identical strands" {
32
+ It "Long identical strands" {
11
33
  Get-HammingDifference "GGACTGA" "GGACTGA" | Should be 0
12
34
  }
13
35
 
14
- It "tests complete distance in single nucleotide strands" {
36
+ It "Complete distance in single nucleotide strands" {
15
37
  Get-HammingDifference "A" "G" | Should be 1
16
38
  }
17
39
 
18
- It "tests complete distance in small strands" {
40
+ It "Complete distance in small strands" {
19
41
  Get-HammingDifference "AG" "CT" | Should be 2
20
42
  }
21
43
 
22
- It "tests small distance in small strands" {
44
+ It "Small distance in small strands" {
23
45
  Get-HammingDifference "AT" "CT" | Should be 1
24
46
  }
25
47
 
26
- It "tests small distance" {
48
+ It "Small distance" {
27
49
  Get-HammingDifference "GGACG" "GGTCG" | Should be 1
28
50
  }
29
51
 
30
- It "tests small distance in long strands" {
52
+ It "Small distance in long strands" {
31
53
  Get-HammingDifference "ACCAGGG" "ACTATGG" | Should be 2
32
54
  }
33
55
 
34
- It "tests non unique character in first strand" {
35
- Get-HammingDifference "AGA" "AGG" | Should be 1
56
+ It "Non-unique character in first strand" {
57
+ Get-HammingDifference "AAG" "AAA" | Should be 1
36
58
  }
37
59
 
38
- It "tests non unique character in second strand" {
39
- Get-HammingDifference "AGG" "AGA" | Should be 1
60
+ It "Non-unique character in second strand" {
61
+ Get-HammingDifference "AAA" "AAG" | Should be 1
40
62
  }
41
63
 
42
- It "tests same nucleotides in different position" {
64
+ It "Same nucleotides in different positions" {
43
65
  Get-HammingDifference "TAG" "GAT" | Should be 2
44
66
  }
45
67
 
46
- It "tests large distance" {
68
+ It "Large distance" {
47
69
  Get-HammingDifference "GATACA" "GCATAA" | Should be 4
48
70
  }
49
71
 
50
- It "tests large distance in off by one strand" {
72
+ It "Large distance in off-by-one strand" {
51
73
  Get-HammingDifference "GGACGGATTCTG" "AGGACGGATTCT" | Should be 9
52
74
  }
53
75
 
54
- It "tests empty strands" {
55
- Get-HammingDifference "" "" | Should be 0
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 "tests disallow second strand longer" {
63
- { Get-HammingDifference "ATA" "AGTG" } | Should Throw "Mismatching string lengths"
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 "tests leap year" {
7
- Test-LeapYear(1996) | Should be $true
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 "tests standard eighteenth year" {
23
- Test-LeapYear(1800) | Should be $false
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 "tests leap twenty fourth century" {
27
- Test-LeapYear(2400) | Should be $true
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 "tests leap year 2000" {
18
+ It "Year divisible by 400: leap year" {
31
19
  Test-LeapYear(2000) | Should be $true
32
20
  }
33
21
  }
@@ -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 : &str, b: &str) -> Result<usize, &'static str> {
1
+ pub fn hamming_distance(a: &str, b: &str) -> Option<usize> {
2
2
  if a.len() != b.len() {
3
- return Result::Err("inputs of different length");
3
+ return None;
4
4
  }
5
5
 
6
- Result::Ok(a.chars().zip(b.chars()).filter(|&(a, b)| a != b).count())
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 an error if the lengths are mismatched.
3
- pub fn hamming_distance(s1: &str, s2: &str) -> Result<u64, ()> {
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("", ""), Ok(0));
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"), Ok(0));
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"), Ok(3));
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"), Ok(1));
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"), Ok(2));
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
- assert!(hamming::hamming_distance("AAA", "AA").is_err());
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
- assert!(hamming::hamming_distance("A", "AA").is_err());
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
+ ```
@@ -3,4 +3,7 @@ name = "reverse_string"
3
3
  version = "1.0.0"
4
4
  authors = ["Peter Goodspeed-Niklaus <peter.r.goodspeedniklaus@gmail.com>"]
5
5
 
6
+ [features]
7
+ grapheme = []
8
+
6
9
  [dependencies]
@@ -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,3 @@
1
+ # Ignore Cargo.lock if creating a library
2
+ # More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
3
+ Cargo.lock
@@ -0,0 +1,6 @@
1
+ [package]
2
+ name = "simple-cipher"
3
+ version = "0.0.0"
4
+
5
+ [dependencies]
6
+ rand = "0.4.2"
@@ -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,4 @@
1
+
2
+ /target/
3
+ **/*.rs.bk
4
+ Cargo.lock
@@ -0,0 +1,5 @@
1
+ [package]
2
+ name = "twofer"
3
+ version = "1.2.0"
4
+
5
+ [dependencies]
@@ -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,6 @@
1
+ pub fn twofer(name: &str)-> String {
2
+ match name {
3
+ "" => "One for you, one for me.".to_string(),
4
+ _ => format!("One for {}, one for me.",name),
5
+ }
6
+ }
@@ -0,0 +1,3 @@
1
+ pub fn twofer(name: &str)-> String {
2
+ unimplemented!("One for {}, one for me.", name);
3
+ }
@@ -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\\w{2}\\d{3}\\z", options: Regex.Options.caseInsensitive)
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.150
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-18 00:00:00.000000000 Z
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