trackler 2.0.8.20 → 2.0.8.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/tracks/csharp/.travis.yml +1 -4
  4. data/tracks/csharp/exercises/accumulate/HINTS.md +3 -0
  5. data/tracks/csharp/exercises/allergies/HINTS.md +3 -0
  6. data/tracks/csharp/exercises/alphametics/HINTS.md +5 -0
  7. data/tracks/csharp/exercises/bank-account/HINTS.md +3 -0
  8. data/tracks/csharp/exercises/beer-song/HINTS.md +2 -0
  9. data/tracks/csharp/exercises/clock/HINTS.md +4 -0
  10. data/tracks/csharp/exercises/custom-set/HINTS.md +4 -0
  11. data/tracks/csharp/exercises/difference-of-squares/HINTS.md +4 -0
  12. data/tracks/csharp/exercises/diffie-hellman/HINTS.md +3 -0
  13. data/tracks/csharp/exercises/food-chain/HINTS.md +2 -0
  14. data/tracks/csharp/exercises/forth/HINTS.md +2 -0
  15. data/tracks/csharp/exercises/hangman/HINTS.md +3 -0
  16. data/tracks/csharp/exercises/leap/Example.cs +2 -2
  17. data/tracks/csharp/exercises/leap/Leap.cs +2 -2
  18. data/tracks/csharp/exercises/leap/LeapTest.cs +4 -4
  19. data/tracks/csharp/exercises/sgf-parsing/HINTS.md +2 -0
  20. data/tracks/csharp/exercises/simple-linked-list/HINTS.md +3 -0
  21. data/tracks/csharp/exercises/sublist/HINTS.md +3 -0
  22. data/tracks/csharp/exercises/twelve-days/HINTS.md +2 -0
  23. data/tracks/csharp/exercises/variable-length-quantity/HINTS.md +3 -0
  24. data/tracks/csharp/exercises/wordy/HINTS.md +2 -0
  25. data/tracks/csharp/generators/BooleanTestMethod.cs +36 -0
  26. data/tracks/csharp/generators/Exercises/Exercise.cs +13 -2
  27. data/tracks/csharp/generators/Exercises/LeapExercise.cs +3 -26
  28. data/tracks/csharp/generators/Program.cs +7 -8
  29. data/tracks/csharp/generators/TestClassNameTransformer.cs +9 -0
  30. data/tracks/csharp/generators/TestClassRenderer.cs +1 -1
  31. data/tracks/csharp/generators/TestedClassNameTransformer.cs +11 -0
  32. data/tracks/csharp/generators/TestedMethodNameTransformer.cs +9 -0
  33. data/tracks/csharp/generators/To.cs +3 -0
  34. data/tracks/elixir/config.json +8 -0
  35. data/tracks/elixir/exercises/ocr-numbers/example.exs +47 -0
  36. data/tracks/elixir/exercises/ocr-numbers/ocr_numbers.exs +10 -0
  37. data/tracks/elixir/exercises/ocr-numbers/ocr_numbers_test.exs +254 -0
  38. data/tracks/go/exercises/say/example.go +2 -0
  39. data/tracks/go/exercises/say/say_test.go +8 -0
  40. data/tracks/go/exercises/scrabble-score/scrabble_score_test.go +6 -4
  41. data/tracks/go/exercises/secret-handshake/secret_handshake_test.go +4 -1
  42. data/tracks/go/exercises/sieve/example.go +2 -0
  43. data/tracks/go/exercises/sieve/sieve_test.go +8 -0
  44. data/tracks/go/exercises/simple-cipher/example.go +3 -1
  45. data/tracks/go/exercises/simple-cipher/simple_cipher_test.go +8 -0
  46. data/tracks/go/exercises/sum-of-multiples/example.go +2 -0
  47. data/tracks/go/exercises/sum-of-multiples/sum_of_multiples_test.go +8 -0
  48. data/tracks/go/exercises/tournament/tournament_test.go +3 -1
  49. data/tracks/go/exercises/transpose/example.go +2 -0
  50. data/tracks/go/exercises/transpose/transpose_test.go +8 -0
  51. data/tracks/go/exercises/tree-building/tree_test.go +6 -6
  52. data/tracks/go/exercises/triangle/triangle_test.go +6 -6
  53. data/tracks/haskell/exercises/atbash-cipher/src/Atbash.hs +2 -2
  54. data/tracks/haskell/exercises/largest-series-product/src/Series.hs +1 -1
  55. data/tracks/haskell/exercises/linked-list/src/Deque.hs +4 -4
  56. data/tracks/haskell/exercises/list-ops/src/ListOps.hs +7 -7
  57. data/tracks/haskell/exercises/luhn/src/Luhn.hs +10 -5
  58. data/tracks/haskell/exercises/matrix/src/Matrix.hs +10 -10
  59. data/tracks/haskell/exercises/minesweeper/src/Minesweeper.hs +1 -1
  60. data/tracks/haskell/exercises/nth-prime/src/Prime.hs +2 -1
  61. data/tracks/haskell/exercises/nucleotide-count/src/DNA.hs +1 -1
  62. data/tracks/haskell/exercises/ocr-numbers/src/OCR.hs +1 -1
  63. data/tracks/haskell/exercises/pascals-triangle/src/Triangle.hs +1 -1
  64. data/tracks/haskell/exercises/phone-number/src/Phone.hs +1 -1
  65. data/tracks/haskell/exercises/pig-latin/src/PigLatin.hs +1 -1
  66. data/tracks/haskell/exercises/prime-factors/src/PrimeFactors.hs +1 -1
  67. data/tracks/kotlin/exercises/_template/build.gradle +1 -1
  68. data/tracks/kotlin/exercises/accumulate/build.gradle +1 -1
  69. data/tracks/kotlin/exercises/acronym/build.gradle +1 -1
  70. data/tracks/kotlin/exercises/allergies/build.gradle +1 -1
  71. data/tracks/kotlin/exercises/anagram/build.gradle +1 -1
  72. data/tracks/kotlin/exercises/atbash-cipher/build.gradle +1 -1
  73. data/tracks/kotlin/exercises/beer-song/build.gradle +1 -1
  74. data/tracks/kotlin/exercises/binary/build.gradle +1 -1
  75. data/tracks/kotlin/exercises/binary-search/build.gradle +1 -1
  76. data/tracks/kotlin/exercises/bob/build.gradle +1 -1
  77. data/tracks/kotlin/exercises/bracket-push/build.gradle +1 -1
  78. data/tracks/kotlin/exercises/change/build.gradle +1 -1
  79. data/tracks/kotlin/exercises/difference-of-squares/build.gradle +1 -1
  80. data/tracks/kotlin/exercises/etl/build.gradle +1 -1
  81. data/tracks/kotlin/exercises/flatten-array/build.gradle +1 -1
  82. data/tracks/kotlin/exercises/gigasecond/build.gradle +1 -1
  83. data/tracks/kotlin/exercises/grade-school/build.gradle +1 -1
  84. data/tracks/kotlin/exercises/hamming/build.gradle +1 -1
  85. data/tracks/kotlin/exercises/hello-world/build.gradle +1 -1
  86. data/tracks/kotlin/exercises/hexadecimal/build.gradle +1 -1
  87. data/tracks/kotlin/exercises/isogram/build.gradle +1 -1
  88. data/tracks/kotlin/exercises/largest-series-product/build.gradle +1 -1
  89. data/tracks/kotlin/exercises/leap/build.gradle +1 -1
  90. data/tracks/kotlin/exercises/linked-list/build.gradle +1 -1
  91. data/tracks/kotlin/exercises/luhn/build.gradle +1 -1
  92. data/tracks/kotlin/exercises/nth-prime/build.gradle +1 -1
  93. data/tracks/kotlin/exercises/nucleotide-count/build.gradle +1 -1
  94. data/tracks/kotlin/exercises/pangram/build.gradle +1 -1
  95. data/tracks/kotlin/exercises/pascals-triangle/build.gradle +1 -1
  96. data/tracks/kotlin/exercises/perfect-numbers/build.gradle +1 -1
  97. data/tracks/kotlin/exercises/phone-number/build.gradle +1 -1
  98. data/tracks/kotlin/exercises/pig-latin/build.gradle +1 -1
  99. data/tracks/kotlin/exercises/raindrops/build.gradle +1 -1
  100. data/tracks/kotlin/exercises/react/build.gradle +1 -1
  101. data/tracks/kotlin/exercises/react/src/test/kotlin/ReactTest.kt +9 -9
  102. data/tracks/kotlin/exercises/rna-transcription/build.gradle +1 -1
  103. data/tracks/kotlin/exercises/robot-name/build.gradle +1 -1
  104. data/tracks/kotlin/exercises/roman-numerals/build.gradle +1 -1
  105. data/tracks/kotlin/exercises/scrabble-score/build.gradle +1 -1
  106. data/tracks/kotlin/exercises/series/build.gradle +1 -1
  107. data/tracks/kotlin/exercises/sieve/build.gradle +1 -1
  108. data/tracks/kotlin/exercises/simple-cipher/build.gradle +1 -1
  109. data/tracks/kotlin/exercises/space-age/build.gradle +1 -1
  110. data/tracks/kotlin/exercises/strain/build.gradle +1 -1
  111. data/tracks/kotlin/exercises/triangle/build.gradle +1 -1
  112. data/tracks/kotlin/exercises/word-count/build.gradle +1 -1
  113. data/tracks/perl6/.gitmodules +3 -0
  114. data/tracks/perl6/.travis.yml +1 -0
  115. data/tracks/perl6/config.json +8 -11
  116. data/tracks/perl6/exercises/accumulate/Accumulate.pm6 +1 -0
  117. data/tracks/perl6/exercises/accumulate/Example.pm +8 -8
  118. data/tracks/perl6/exercises/accumulate/accumulate.t +27 -12
  119. data/tracks/perl6/exercises/all-your-base/AllYourBase.pm6 +1 -0
  120. data/tracks/perl6/exercises/all-your-base/Example.pm +46 -0
  121. data/tracks/perl6/exercises/all-your-base/all-your-base.t +163 -0
  122. data/tracks/perl6/exercises/bob/Bob.pm6 +13 -0
  123. data/tracks/perl6/exercises/bob/Example.pm +9 -9
  124. data/tracks/perl6/exercises/bob/bob.t +201 -34
  125. data/tracks/perl6/exercises/grade-school/Example.pm +13 -12
  126. data/tracks/perl6/exercises/grade-school/GradeSchool.pm6 +4 -0
  127. data/tracks/perl6/exercises/grade-school/grade-school.t +38 -19
  128. data/tracks/perl6/exercises/hello-world/Example.pm +3 -3
  129. data/tracks/perl6/exercises/hello-world/HelloWorld.pm6 +2 -2
  130. data/tracks/perl6/exercises/hello-world/hello-world.t +41 -10
  131. data/tracks/perl6/exercises/linked-list/Example.pm6 +33 -34
  132. data/tracks/perl6/exercises/linked-list/LinkedList.pm6 +1 -0
  133. data/tracks/perl6/exercises/linked-list/linked-list.t +32 -22
  134. data/tracks/perl6/exercises/robot-name/Example.pm +8 -15
  135. data/tracks/perl6/exercises/robot-name/Robot.pm6 +1 -0
  136. data/tracks/perl6/exercises/robot-name/robot-name.t +39 -14
  137. data/tracks/php/config.json +5 -0
  138. data/tracks/php/exercises/luhn/example.php +26 -0
  139. data/tracks/php/exercises/luhn/luhn_test.php +95 -0
  140. data/tracks/purescript/README.md +67 -4
  141. data/tracks/python/docs/LEARNING.md +1 -0
  142. data/tracks/python/exercises/acronym/acronym_test.py +5 -1
  143. data/tracks/python/exercises/atbash-cipher/atbash_cipher_test.py +8 -0
  144. data/tracks/python/exercises/hello-world/hello_world_test.py +4 -38
  145. data/tracks/python/exercises/run-length-encoding/run_length_encoding_test.py +30 -15
  146. metadata +38 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: eb72b896068a0db09871303423eb36d77ae12e79
4
- data.tar.gz: b4f173c7a80ecc1a8dad8b60f163a92085a97a82
3
+ metadata.gz: 2491ccce5df1a33884d83cdd96ff6c4f2c05112d
4
+ data.tar.gz: e4b9594ea3bf42070f042029ac4da76db12148c9
5
5
  SHA512:
6
- metadata.gz: 36f010e19529f3ff4f39e0a8b3aa16ecbba03834b7fbc36a644e1abef9dc9e1d05e3bb17a81c3ffdecc2daeb9ed0d3c08d68387b1559cd8b3154bad7cf52a2bf
7
- data.tar.gz: 9ebce40e4a533258b9920f11ae1354e29aeb926704bf074eb05733d13364335be3e93a993e6f8b3fd7422c131286c3a4d9d38c244ebbe5e0b4b8e8198d0838dc
6
+ metadata.gz: 890a55c3d39142507ca80cf77e361d6562b1b78791847c5f1eb7fee02870083cb8756259dd66841ab169e929870198512e406eeb416b9f3b2b229b13fd4f6067
7
+ data.tar.gz: ee04f7b93f395b455fca240796a3cceeabd0224b882f45bd00d72edf54d2f852e66ae6d9524d0b97ee47975a49082aef26b1a1482326f647dcb4f611596407a9
@@ -1,3 +1,3 @@
1
1
  module Trackler
2
- VERSION = "2.0.8.20"
2
+ VERSION = "2.0.8.21"
3
3
  end
@@ -1,10 +1,7 @@
1
1
  language: csharp
2
- sudo: required
3
2
  dist: trusty
4
3
  dotnet: 1.0.1
5
4
  mono: none
6
- os:
7
- - linux
8
5
  env:
9
6
  global:
10
7
  - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
@@ -12,4 +9,4 @@ env:
12
9
  script:
13
10
  - ./bin/fetch-configlet
14
11
  - ./bin/configlet .
15
- - ./build.sh
12
+ - ./build.sh
@@ -0,0 +1,3 @@
1
+ ## Hints
2
+ This exercise requires you to write an extension method. For more information, see [this page]
3
+ (https://msdn.microsoft.com/en-us//library/bb383977.aspx).
@@ -0,0 +1,3 @@
1
+ ## Hints
2
+ This exercise requires you to use bitwise operations. For more information, see [this page]
3
+ (https://msdn.microsoft.com/en-us/library/6a71f45d.aspx).
@@ -0,0 +1,5 @@
1
+ ## Hints
2
+ - To parse the text, you could try to use the [Sprache](https://github.com/sprache/Sprache/blob/develop/README.md) library. You can also find a good tutorial [here](https://www.thomaslevesque.com/2017/02/23/easy-text-parsing-in-c-with-sprache/).
3
+ - You can solve this exercise with a brute force algorithm, but this will possibly have a poor runtime performance.
4
+ Try to find a more sophisticated solution.
5
+ - Hint: You could try the column-wise addition algorithm that is usually taught in school.
@@ -0,0 +1,3 @@
1
+ ## Hints
2
+ This exercise requires you to handle data related to currency and money. A normal approuch is to use the [Decimal](https://msdn.microsoft.com/en-US/library/system.decimal.aspx) struct to store currency values.
3
+ Note though that you then only store the numeric value of a currency.
@@ -0,0 +1,2 @@
1
+ ## Hints
2
+ - Try to capture the structure of the song in your code, where you build up the song by composing its parts.
@@ -0,0 +1,4 @@
1
+ ## Hints
2
+ This exercise requires you to implements a type-specific method for determining equality of instances.
3
+ For more information, see [this page]
4
+ (https://docs.microsoft.com/en-us/dotnet/core/api/System.IEquatable-1) .
@@ -0,0 +1,4 @@
1
+ ## Hints
2
+ This exercise requires you to implements a type-specific method for determining equality of instances.
3
+ For more information, see [this page]
4
+ (https://docs.microsoft.com/en-us/dotnet/core/api/System.IEquatable-1) .
@@ -0,0 +1,4 @@
1
+ ## Hints
2
+ This exercise requires you to process a collection of data. You can simplify your code by using LINQ (Language Integrated Query).
3
+ For more information, see [this page]
4
+ (https://docs.microsoft.com/en-us/dotnet/articles/standard/using-linq).
@@ -0,0 +1,3 @@
1
+ ## Hints
2
+ This exercise requires you to perform calculations on large numbers. To correctly represent large numbers, the
3
+ [BigInteger](https://msdn.microsoft.com/en-us/library/system.numerics.biginteger(v=vs.110).aspx) struct is used.
@@ -0,0 +1,2 @@
1
+ ## Hints
2
+ - Try to capture the structure of the song in your code, where you build up the song by composing its parts.
@@ -0,0 +1,2 @@
1
+ ## Hints
2
+ - To parse the text, you could try to use the [Sprache](https://github.com/sprache/Sprache/blob/develop/README.md) library. You can also find a good tutorial [here](https://www.thomaslevesque.com/2017/02/23/easy-text-parsing-in-c-with-sprache/).
@@ -0,0 +1,3 @@
1
+ ## Hints
2
+ This exercise requires you to work with events. For more information, see [this page]
3
+ (https://docs.microsoft.com/en-us/dotnet/articles/csharp/programming-guide/events/) .
@@ -1,6 +1,6 @@
1
- public class Year
1
+ public static class Leap
2
2
  {
3
- public static bool IsLeap(int year)
3
+ public static bool IsLeapYear(int year)
4
4
  {
5
5
  if (year % 100 == 0)
6
6
  return year % 400 == 0;
@@ -1,8 +1,8 @@
1
1
  using System;
2
2
 
3
- public static class Year
3
+ public static class Leap
4
4
  {
5
- public static bool IsLeap(int year)
5
+ public static bool IsLeapYear(int year)
6
6
  {
7
7
  throw new NotImplementedException("You need to implement this function.");
8
8
  }
@@ -5,24 +5,24 @@ public class LeapTest
5
5
  [Fact]
6
6
  public void Year_not_divisible_by_4_is_common_year()
7
7
  {
8
- Assert.False(Year.IsLeap(2015));
8
+ Assert.False(Leap.IsLeapYear(2015));
9
9
  }
10
10
 
11
11
  [Fact(Skip = "Remove to run test")]
12
12
  public void Year_divisible_by_4_not_divisible_by_100_is_leap_year()
13
13
  {
14
- Assert.True(Year.IsLeap(2016));
14
+ Assert.True(Leap.IsLeapYear(2016));
15
15
  }
16
16
 
17
17
  [Fact(Skip = "Remove to run test")]
18
18
  public void Year_divisible_by_100_not_divisible_by_400_is_common_year()
19
19
  {
20
- Assert.False(Year.IsLeap(2100));
20
+ Assert.False(Leap.IsLeapYear(2100));
21
21
  }
22
22
 
23
23
  [Fact(Skip = "Remove to run test")]
24
24
  public void Year_divisible_by_400_is_leap_year()
25
25
  {
26
- Assert.True(Year.IsLeap(2000));
26
+ Assert.True(Leap.IsLeapYear(2000));
27
27
  }
28
28
  }
@@ -0,0 +1,2 @@
1
+ ## Hints
2
+ - To parse the text, you could try to use the [Sprache](https://github.com/sprache/Sprache/blob/develop/README.md) library. You can also find a good tutorial [here](https://www.thomaslevesque.com/2017/02/23/easy-text-parsing-in-c-with-sprache/).
@@ -0,0 +1,3 @@
1
+ ## Hints
2
+ This exercise requires you to create a linked list data structure which can be iterated. This requires you to implement the IEnumerable\<T> interface.
3
+ For more information, see [this page](https://msdn.microsoft.com/en-us/library/9eekhta0(v=vs.110).aspx).
@@ -0,0 +1,3 @@
1
+ ## Hints
2
+ To be able to compare data, the IComparable interface is used.
3
+ For more information, see [this page](https://msdn.microsoft.com/en-us/library/system.icomparable(v=vs.110).aspx).
@@ -0,0 +1,2 @@
1
+ ## Hints
2
+ - Try to capture the structure of the song in your code, where you build up the song by composing its parts.
@@ -0,0 +1,3 @@
1
+ ## Hints
2
+ This exercise requires you to use bitwise operations. For more information, see [this page]
3
+ (https://msdn.microsoft.com/en-us/library/6a71f45d.aspx).
@@ -0,0 +1,2 @@
1
+ ## Hints
2
+ - To parse the text, you could try to use the [Sprache](https://github.com/sprache/Sprache/blob/develop/README.md) library. You can also find a good tutorial [here](https://www.thomaslevesque.com/2017/02/23/easy-text-parsing-in-c-with-sprache/).
@@ -0,0 +1,36 @@
1
+ using System;
2
+ using Humanizer;
3
+
4
+ namespace Generators
5
+ {
6
+ public class BooleanTestMethod : TestMethod
7
+ {
8
+ public BooleanTestMethod(CanonicalData canonicalData, CanonicalDataCase canonicalDataCase, int index)
9
+ {
10
+ Index = index;
11
+ MethodName = GetMethodName(canonicalDataCase);
12
+ Body = GetBody(canonicalData, canonicalDataCase);
13
+ }
14
+
15
+ private static string GetMethodName(CanonicalDataCase canonicalDataCase)
16
+ => canonicalDataCase.Description.Replace(":", " is").Transform(To.TestMethodName);
17
+
18
+ private static string GetBody(CanonicalData canonicalData, CanonicalDataCase canonicalDataCase)
19
+ {
20
+ var isTrue = Convert.ToBoolean(canonicalDataCase.Expected);
21
+ var testedClassName = GetTestedClassName(canonicalData);
22
+ var testedMethod = GetTestedMethod(canonicalDataCase);
23
+
24
+ return $"Assert.{isTrue}({testedClassName}.{testedMethod}({canonicalDataCase.Input}));";
25
+ }
26
+
27
+ private static string GetTestedClassName(CanonicalData canonicalData)
28
+ => canonicalData.Exercise.Transform(To.TestedClassName);
29
+
30
+ private static string GetTestedMethod(CanonicalDataCase canonicalDataCase)
31
+ {
32
+ var testedMethod = canonicalDataCase.Property.Transform(To.TestedMethodName);
33
+ return testedMethod.StartsWith("Is") ? testedMethod : "Is" + testedMethod;
34
+ }
35
+ }
36
+ }
@@ -1,4 +1,7 @@
1
- namespace Generators.Exercises
1
+ using System.Linq;
2
+ using Humanizer;
3
+
4
+ namespace Generators.Exercises
2
5
  {
3
6
  public abstract class Exercise
4
7
  {
@@ -9,6 +12,14 @@
9
12
 
10
13
  public string Name { get; }
11
14
 
12
- public abstract TestClass CreateTestClass(CanonicalData canonicalData);
15
+ public TestClass CreateTestClass(CanonicalData canonicalData)
16
+ {
17
+ return new TestClass
18
+ {
19
+ ClassName = Name.Transform(To.TestClassName),
20
+ TestMethods = canonicalData.Cases.Select((canonicalDataCase, index) => CreateTestMethod(canonicalData, canonicalDataCase, index)).ToArray()
21
+ };
22
+ }
23
+ protected abstract TestMethod CreateTestMethod(CanonicalData canonicalData, CanonicalDataCase canonicalDataCase, int index);
13
24
  }
14
25
  }
@@ -1,8 +1,4 @@
1
- using System;
2
- using System.Linq;
3
- using Humanizer;
4
-
5
- namespace Generators.Exercises
1
+ namespace Generators.Exercises
6
2
  {
7
3
  public class LeapExercise : Exercise
8
4
  {
@@ -10,26 +6,7 @@ namespace Generators.Exercises
10
6
  {
11
7
  }
12
8
 
13
- public override TestClass CreateTestClass(CanonicalData canonicalData)
14
- {
15
- return new TestClass
16
- {
17
- ClassName = "Leap",
18
- TestMethods = canonicalData.Cases.Select(CreateTestMethod).ToArray()
19
- };
20
- }
21
-
22
- private static TestMethod CreateTestMethod(CanonicalDataCase canonicalDataCase, int index)
23
- {
24
- var year = Convert.ToInt32(canonicalDataCase.Input);
25
- var isTrue = Convert.ToBoolean(canonicalDataCase.Expected);
26
-
27
- return new TestMethod
28
- {
29
- Index = index,
30
- MethodName = canonicalDataCase.Description.Replace(":", " is").Transform(To.TestMethodName),
31
- Body = $"Assert.{isTrue}(Year.IsLeap({year}));"
32
- };
33
- }
9
+ protected override TestMethod CreateTestMethod(CanonicalData canonicalData, CanonicalDataCase canonicalDataCase, int index)
10
+ => new BooleanTestMethod(canonicalData, canonicalDataCase, index);
34
11
  }
35
12
  }
@@ -1,6 +1,5 @@
1
1
  using Generators.Exercises;
2
2
  using System.IO;
3
- using Humanizer;
4
3
  using Serilog;
5
4
 
6
5
  namespace Generators
@@ -35,25 +34,25 @@ namespace Generators
35
34
  {
36
35
  public static void Generate(Exercise exercise)
37
36
  {
38
- var testClassContents = GenerateTestClassContents(exercise);
39
- var testClassFilePath = TestFilePath(exercise);
37
+ var testClass = CreateTestClass(exercise);
38
+ var testClassContents = TestClassRenderer.Render(testClass);
39
+ var testClassFilePath = TestFilePath(exercise, testClass);
40
40
 
41
41
  SaveTestClassContentsToFile(testClassFilePath, testClassContents);
42
42
  Log.Information("Generated tests for {Exercise} exercise in {TestFile}.", exercise.Name, testClassFilePath);
43
43
  }
44
44
 
45
- private static string GenerateTestClassContents(Exercise exercise)
45
+ private static TestClass CreateTestClass(Exercise exercise)
46
46
  {
47
47
  var canonicalData = CanonicalDataParser.Parse(exercise.Name);
48
- var testClass = exercise.CreateTestClass(canonicalData);
49
- return TestClassRenderer.Render(testClass);
48
+ return exercise.CreateTestClass(canonicalData);
50
49
  }
51
50
 
52
51
  private static void SaveTestClassContentsToFile(string testClassFilePath, string testClassContents) =>
53
52
  File.WriteAllText(testClassFilePath, testClassContents);
54
53
 
55
- private static string TestFilePath(Exercise exercise) => Path.Combine("..", "exercises", exercise.Name, TestFileName(exercise));
54
+ private static string TestFilePath(Exercise exercise, TestClass testClass) => Path.Combine("..", "exercises", exercise.Name, TestFileName(testClass));
56
55
 
57
- private static string TestFileName(Exercise exercise) => $"{exercise.Name.Transform(Humanizer.To.TitleCase)}Test.cs";
56
+ private static string TestFileName(TestClass testClass) => $"{testClass.ClassName}.cs";
58
57
  }
59
58
  }
@@ -0,0 +1,9 @@
1
+ using Humanizer;
2
+
3
+ namespace Generators
4
+ {
5
+ public class TestClassNameTransformer : IStringTransformer
6
+ {
7
+ public string Transform(string input) => $"{input.Dehumanize()}Test";
8
+ }
9
+ }
@@ -8,7 +8,7 @@ namespace Generators
8
8
  private const string TestClassTemplate =
9
9
  @"{UsingNamespaces}
10
10
 
11
- public class {ClassName}Test
11
+ public class {ClassName}
12
12
  {
13
13
  {Body}
14
14
  }";
@@ -0,0 +1,11 @@
1
+ using System.Text.RegularExpressions;
2
+ using Humanizer;
3
+
4
+ namespace Generators
5
+ {
6
+ public class TestedClassNameTransformer : IStringTransformer
7
+ {
8
+ public string Transform(string input)
9
+ => Regex.Replace(input, @"[^\w]+", "", RegexOptions.Compiled).Underscore().Transform(Humanizer.To.TitleCase);
10
+ }
11
+ }
@@ -0,0 +1,9 @@
1
+ using Humanizer;
2
+
3
+ namespace Generators
4
+ {
5
+ public class TestedMethodNameTransformer : IStringTransformer
6
+ {
7
+ public string Transform(string input) => input.Dehumanize();
8
+ }
9
+ }
@@ -2,6 +2,9 @@
2
2
  {
3
3
  public static class To
4
4
  {
5
+ public static readonly TestedClassNameTransformer TestedClassName = new TestedClassNameTransformer();
6
+ public static readonly TestClassNameTransformer TestClassName = new TestClassNameTransformer();
7
+ public static readonly TestedMethodNameTransformer TestedMethodName = new TestedMethodNameTransformer();
5
8
  public static readonly TestMethodNameTransformer TestMethodName = new TestMethodNameTransformer();
6
9
  }
7
10
  }
@@ -464,6 +464,14 @@
464
464
  "topics": [
465
465
  "Pattern Matching"
466
466
  ]
467
+ },
468
+ {
469
+ "slug": "ocr-numbers",
470
+ "difficulty": 6,
471
+ "topics": [
472
+ "Strings",
473
+ "Enumerations"
474
+ ]
467
475
  }
468
476
  ],
469
477
  "deprecated": [
@@ -0,0 +1,47 @@
1
+ defmodule OCRNumbers do
2
+
3
+ @doc """
4
+ Given a 3 x 4 grid of pipes, underscores, and spaces, determine which number is represented, or
5
+ whether it is garbled.
6
+ """
7
+ @spec convert([String.t]) :: String.t
8
+ def convert(input) do
9
+ Enum.chunk(input, 4)
10
+ |> Enum.map(fn row_set -> _convert(row_set, "") end)
11
+ |> format_output()
12
+ end
13
+
14
+ def format_output([]), do: {:error, 'invalid line count'}
15
+ def format_output(rows), do: _format_output(Enum.any?(rows, &_error?/1), rows)
16
+ def _format_output(true, rows), do: Enum.find(rows, &_error?/1)
17
+ def _format_output(false, output), do: {:ok, Enum.join(output, ",")}
18
+ def _error?({:error, _}), do: true
19
+ def _error?(_), do: false
20
+
21
+ def _convert(_, {:error, _} = error), do: error
22
+ def _convert(input, _) when length(input) != 4, do: {:error, 'invalid line count'}
23
+ def _convert(["", "", "", ""], output), do: output
24
+ def _convert(input, output) do
25
+ split_strings = Enum.map(input, fn a -> String.split_at(a, 3) end)
26
+ this_character = Enum.map(split_strings, fn ({a, _}) -> a end)
27
+ other_characters = Enum.map(split_strings, fn {_, a} -> a end)
28
+ lengths = Enum.map(this_character, fn a -> String.length(a) end)
29
+
30
+ _convert(other_characters, update_output(lengths, this_character, output))
31
+ end
32
+
33
+ def update_output([3, 3, 3, 3], chars, output), do: output <> recognize_character(chars)
34
+ def update_output(_, _, _), do: {:error, 'invalid column count'}
35
+
36
+ def recognize_character([" _ ", "| |", "|_|", " "]), do: "0"
37
+ def recognize_character([" ", " |", " |", " "]), do: "1"
38
+ def recognize_character([" _ ", " _|", "|_ ", " "]), do: "2"
39
+ def recognize_character([" _ ", " _|", " _|", " "]), do: "3"
40
+ def recognize_character([" ", "|_|", " |", " "]), do: "4"
41
+ def recognize_character([" _ ", "|_ ", " _|", " "]), do: "5"
42
+ def recognize_character([" _ ", "|_ ", "|_|", " "]), do: "6"
43
+ def recognize_character([" _ ", " |", " |", " "]), do: "7"
44
+ def recognize_character([" _ ", "|_|", "|_|", " "]), do: "8"
45
+ def recognize_character([" _ ", "|_|", " _|", " "]), do: "9"
46
+ def recognize_character(_), do: "?"
47
+ end
@@ -0,0 +1,10 @@
1
+ defmodule OCRNumbers do
2
+
3
+ @doc """
4
+ Given a 3 x 4 grid of pipes, underscores, and spaces, determine which number is represented, or
5
+ whether it is garbled.
6
+ """
7
+ @spec convert([String.t]) :: String.t
8
+ def convert(input) do
9
+ end
10
+ end