trackler 2.0.8.36 → 2.0.8.37

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +3 -0
  3. data/lib/trackler/version.rb +1 -1
  4. data/tracks/c/config.json +7 -0
  5. data/tracks/c/exercises/perfect-numbers/makefile +16 -0
  6. data/tracks/c/exercises/perfect-numbers/src/example.c +28 -0
  7. data/tracks/c/exercises/perfect-numbers/src/example.h +13 -0
  8. data/tracks/c/exercises/perfect-numbers/src/perfect_numbers.h +11 -0
  9. data/tracks/c/exercises/perfect-numbers/test/test_perfect_numbers.c +87 -0
  10. data/tracks/c/exercises/perfect-numbers/test/vendor/unity.c +1300 -0
  11. data/tracks/c/exercises/perfect-numbers/test/vendor/unity.h +274 -0
  12. data/tracks/c/exercises/perfect-numbers/test/vendor/unity_internals.h +701 -0
  13. data/tracks/ceylon/README.md +1 -1
  14. data/tracks/ceylon/docs/RESOURCES.md +5 -0
  15. data/tracks/ceylon/exercises/anagram/source/anagram/module.ceylon +1 -1
  16. data/tracks/ceylon/exercises/bracket-push/example/module.ceylon +2 -2
  17. data/tracks/ceylon/exercises/bracket-push/source/bracketpush/module.ceylon +1 -1
  18. data/tracks/ceylon/exercises/hamming/source/hamming/module.ceylon +1 -1
  19. data/tracks/ceylon/exercises/largest-series-product/source/largestseriesproduct/module.ceylon +1 -1
  20. data/tracks/ceylon/exercises/leap/source/leap/module.ceylon +1 -1
  21. data/tracks/ceylon/exercises/react/example/module.ceylon +2 -2
  22. data/tracks/ceylon/exercises/react/source/react/module.ceylon +1 -1
  23. data/tracks/ceylon/exercises/sieve/example/module.ceylon +2 -2
  24. data/tracks/ceylon/exercises/sieve/source/sieve/module.ceylon +1 -1
  25. data/tracks/clojurescript/.github/ISSUE_TEMPLATE.md +9 -0
  26. data/tracks/clojurescript/.gitignore +4 -0
  27. data/tracks/clojurescript/.travis.yml +5 -0
  28. data/tracks/clojurescript/LICENSE +21 -0
  29. data/tracks/clojurescript/README.md +72 -0
  30. data/tracks/clojurescript/bin/fetch-configlet +32 -0
  31. data/tracks/clojurescript/config.json +21 -0
  32. data/tracks/clojurescript/docs/ABOUT.md +0 -0
  33. data/tracks/clojurescript/docs/INSTALLATION.md +0 -0
  34. data/tracks/clojurescript/docs/LEARNING.md +0 -0
  35. data/tracks/clojurescript/docs/RESOURCES.md +0 -0
  36. data/tracks/clojurescript/docs/TESTS.md +0 -0
  37. data/tracks/clojurescript/exercises/TRACK_HINTS.md +0 -0
  38. data/tracks/clojurescript/img/.keep +0 -0
  39. data/tracks/csharp/exercises/grade-school/Example.cs +13 -1
  40. data/tracks/csharp/exercises/grade-school/GradeSchool.cs +1 -1
  41. data/tracks/csharp/exercises/grade-school/GradeSchoolTest.cs +42 -18
  42. data/tracks/go/README.md +8 -0
  43. data/tracks/go/exercises/twelve-days/HINTS.md +2 -0
  44. data/tracks/haskell/config.json +0 -1
  45. data/tracks/objective-c/config.json +9 -0
  46. data/tracks/objective-c/exercises/crypto-square/CryptoSquareExample.h +14 -0
  47. data/tracks/objective-c/exercises/crypto-square/CryptoSquareExample.m +96 -0
  48. data/tracks/objective-c/exercises/crypto-square/CryptoSquareTest.m +94 -0
  49. data/tracks/objective-c/xcodeProject/ObjectiveC.xcodeproj/project.pbxproj +18 -0
  50. data/tracks/purescript/.gitignore +2 -2
  51. data/tracks/purescript/bin/test-one.sh +58 -0
  52. data/tracks/purescript/bin/test.sh +13 -44
  53. data/tracks/purescript/config.json +7 -0
  54. data/tracks/purescript/exercises/bracket-push/bower.json +17 -0
  55. data/tracks/purescript/exercises/bracket-push/examples/src/BracketPush.purs +43 -0
  56. data/tracks/purescript/exercises/bracket-push/src/BracketPush.purs +3 -0
  57. data/tracks/purescript/exercises/bracket-push/test/Main.purs +64 -0
  58. data/tracks/scala/exercises/hello-world/HINTS.md +0 -4
  59. data/tracks/scala/exercises/hello-world/example.scala +1 -2
  60. data/tracks/scala/exercises/hello-world/src/test/scala/HelloWorldTest.scala +4 -11
  61. data/tracks/scala/testgen/build.sbt +9 -0
  62. data/tracks/scala/testgen/project/build.properties +2 -0
  63. data/tracks/scala/testgen/project/plugins.sbt +2 -0
  64. data/tracks/scala/testgen/src/main/scala/BeerSongTestGenerator.scala +15 -0
  65. data/tracks/scala/testgen/src/main/scala/BowlingTestGenerator.scala +23 -44
  66. data/tracks/scala/testgen/src/main/scala/FoodChainTestGenerator.scala +31 -0
  67. data/tracks/scala/testgen/src/main/scala/HelloWorldTestGenerator.scala +14 -0
  68. data/tracks/scala/testgen/src/main/scala/NucleotideCountTestGenerator.scala +15 -0
  69. data/tracks/scala/testgen/src/main/scala/PangramsTestGenerator.scala +20 -38
  70. data/tracks/scala/testgen/src/main/scala/SumOfMultiplesTestGenerator.scala +14 -0
  71. data/tracks/scala/testgen/src/main/scala/testgen/CanonicalDataParser.scala +105 -0
  72. data/tracks/scala/testgen/src/main/scala/testgen/TestSuiteBuilder.scala +111 -0
  73. data/tracks/scala/testgen/src/main/twirl/funSuiteTemplate.scala.txt +12 -0
  74. metadata +44 -4
  75. data/tracks/haskell/common/stack.yaml +0 -1
  76. data/tracks/haskell/exercises/pov/.dummylink +0 -1
@@ -141,7 +141,7 @@ As mentioned above, we used parameterized tests since this avoids test code dupl
141
141
 
142
142
  Unfortunately, since by default all cases are enabled, this runs counter to the usual Exercism style in which only a *single test case* is enabled, and the student enables one more test case after making the previous one pass, taking an iterative process.
143
143
 
144
- The [ignore annotation](https://modules.ceylon-lang.org/repo/1/ceylon/test/1.3.1/module-doc/api/index.html#ignore) does not seem like it can be applied to individual cases of a parameterized test.
144
+ The [ignore annotation](https://modules.ceylon-lang.org/repo/1/ceylon/test/1.3.2/module-doc/api/index.html#ignore) does not seem like it can be applied to individual cases of a parameterized test.
145
145
 
146
146
  One possible solution to this would be to comment out all cases except the first.
147
147
  If this solution were taken, students would need to be aware of this, and be informed that they need to uncomment the cases.
@@ -0,0 +1,5 @@
1
+ * [Language specification](https://www.ceylon-lang.org/documentation/1.3/spec/)
2
+ * [Reference](https://www.ceylon-lang.org/documentation/1.3/reference/)
3
+ * [API documentation for the `language` module](https://modules.ceylon-lang.org/repo/1/ceylon/language/1.3.2/module-doc/api/index.html)
4
+ * [Examples](https://www.ceylon-lang.org/documentation/1.3/examples/)
5
+ * [Community page](https://www.ceylon-lang.org/community/)
@@ -1,3 +1,3 @@
1
1
  module anagram "1.0" {
2
- import "ceylon.test" "1.3.1";
2
+ import "ceylon.test" "1.3.2";
3
3
  }
@@ -1,4 +1,4 @@
1
1
  module bracketpush "1.0" {
2
- import "ceylon.collection" "1.3.1";
3
- import "ceylon.test" "1.3.1";
2
+ import "ceylon.collection" "1.3.2";
3
+ import "ceylon.test" "1.3.2";
4
4
  }
@@ -1,3 +1,3 @@
1
1
  module bracketpush "1.0" {
2
- import "ceylon.test" "1.3.1";
2
+ import "ceylon.test" "1.3.2";
3
3
  }
@@ -1,3 +1,3 @@
1
1
  module hamming "1.0" {
2
- import "ceylon.test" "1.3.1";
2
+ import "ceylon.test" "1.3.2";
3
3
  }
@@ -1,3 +1,3 @@
1
1
  module largestseriesproduct "1.0" {
2
- import "ceylon.test" "1.3.1";
2
+ import "ceylon.test" "1.3.2";
3
3
  }
@@ -1,3 +1,3 @@
1
1
  module leap "1.0" {
2
- import "ceylon.test" "1.3.1";
2
+ import "ceylon.test" "1.3.2";
3
3
  }
@@ -1,4 +1,4 @@
1
1
  module react "1.0" {
2
- import "ceylon.collection" "1.3.1";
3
- import "ceylon.test" "1.3.1";
2
+ import "ceylon.collection" "1.3.2";
3
+ import "ceylon.test" "1.3.2";
4
4
  }
@@ -1,3 +1,3 @@
1
1
  module react "1.0" {
2
- import "ceylon.test" "1.3.1";
2
+ import "ceylon.test" "1.3.2";
3
3
  }
@@ -1,4 +1,4 @@
1
1
  module sieve "1.0" {
2
- import "ceylon.numeric" "1.3.1";
3
- import "ceylon.test" "1.3.1";
2
+ import "ceylon.numeric" "1.3.2";
3
+ import "ceylon.test" "1.3.2";
4
4
  }
@@ -1,3 +1,3 @@
1
1
  module sieve "1.0" {
2
- import "ceylon.test" "1.3.1";
2
+ import "ceylon.test" "1.3.2";
3
3
  }
@@ -0,0 +1,9 @@
1
+ **What programming language should we add?**
2
+
3
+ **What is the official website for the language?**
4
+
5
+ **Is this a language that comes in many variants? If so, which variant should we support?**
6
+
7
+ **Is there a testing framework available for the language?**
8
+
9
+ **Who will be leading the effort to launch the track?**
@@ -0,0 +1,4 @@
1
+ *.swp
2
+ .DS_Store
3
+ bin/configlet
4
+ bin/configlet.exe
@@ -0,0 +1,5 @@
1
+ language: bash
2
+
3
+ script:
4
+ - bin/fetch-configlet
5
+ - bin/configlet .
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017 Exercism, Inc
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,72 @@
1
+ # Exercism ClojureScript Track
2
+
3
+ ![build status](https://travis-ci.org/exercism/xslug.svg?branch=master)
4
+
5
+ Exercism exercises in ClojureScript.
6
+
7
+ ## Setup
8
+
9
+ The simplest way to install ClojureScript is ...
10
+
11
+ ## Contributing
12
+
13
+ Thank you so much for contributing! :tada:
14
+
15
+ Please start by reading how to [get involved in a track](https://github.com/exercism/exercism.io/blob/master/docs/getting-involved-in-a-track.md). Comprehensive details on contributing can be found [here](https://github.com/exercism/x-common/blob/master/CONTRIBUTING.md). Be sure to read the Exercism [Code of Conduct](https://github.com/exercism/exercism.io/blob/master/CODE_OF_CONDUCT.md).
16
+
17
+ We welcome pull requests of all kinds. No contribution is too small.
18
+
19
+ We encourage contributions that provide fixes and improvements to existing exercises. Please note that this track's exercises must conform to the standards determined in the [exercism/x-common](https://github.com/exercism/x-common) repo. Changes to the tests or documentation of a common exercise will often warrant a PR in that repo before it can be incorporated into this track's exercises. If you're unsure, then go ahead and open a GitHub issue, and we'll discuss the change.
20
+
21
+ ## Exercise Tests ##
22
+
23
+ At the most basic level, Exercism is all about the tests. They drive the user's implementation forward and tell them when the exercise is complete.
24
+
25
+ The utmost care and attention should be used when adding or making changes to the tests for an exercise. When implementing an exercise test suite, we want to provide a good user experience for the people writing a solution to the exercise. People should not be confused or overwhelmed.
26
+
27
+ We simulate Test-Driven Development (TDD) by implementing the tests in order of increasing complexity. We try to ensure that each test either
28
+
29
+ - helps triangulate a solution to be more generic, or
30
+ - requires new functionality incrementally.
31
+
32
+ Test files should use the following format:
33
+
34
+ ```
35
+ # include the body of an example test
36
+ ```
37
+
38
+ ## Submitting a Pull Request ##
39
+
40
+ Please keep the following in mind:
41
+
42
+ - Pull requests should be focused on a single exercise, issue, or change.
43
+
44
+ - We welcome changes to code style, and wording. Please open a separate PR for these changes if possible.
45
+
46
+ - Please open an issue before creating a PR that makes significant (breaking) changes to an existing exercise or makes changes across many exercises. It is best to discuss these changes before doing the work. Discussions related to exercises that are not track specific can be found in [exercism/discussions](https://github.com/exercism/discussions/issues).
47
+
48
+ - Follow the coding standards for ClojureScript. (If there is a formatter for the track's language, add instructions for using it here.)
49
+
50
+ - Watch out for trailing spaces, extra blank lines, and spaces in blank lines.
51
+
52
+ - All the tests for ClojureScript exercises can be run from the top level of the repo with ... Please run this command before submitting your PR.
53
+
54
+ ## Contributing a New Exercise ##
55
+
56
+ - All Exercism exercises must be defined in [x-common](https://github.com/exercism/x-common/tree/master/exercises) before they are implemented for a specific track. Please submit a PR there if your exercise is new to Exercism.
57
+
58
+ - Please make sure the new exercise conforms to specifications in the [exercism/x-common](https://github.com/exercism/x-common) repo.
59
+
60
+ - Each exercise must stand on its own. Do not reference files outside the exercise directory. They will not be included when the user fetches the exercise.
61
+
62
+ - Exercises should use only the ClojureScript core libraries.
63
+
64
+ - Please do not add a README or README.md file to the exercise directory. The READMEs are constructed using shared metadata, which lives in the
65
+ [exercism/x-common](https://github.com/exercism/x-common) repository. Further explanation can be found in [fixing-exercise-readmes](https://github.com/exercism/exercism.io/blob/master/docs/fixing-exercise-readmes.md)
66
+
67
+ - Each exercise should have a test suite, an example solution, a template file for the real implementation and ... (anything else that needs to go with each exercise for this track). The CI build expects files to be named using the following convention: (describe the ClojureScript convention for naming the various files that make up an exercise).
68
+
69
+ - Please do not commit any configuration files or directories inside the exercise other than ...
70
+
71
+ - Be sure to add it to the appropriate place in the `config.json` file. Also, please run `bin/fetch-configlet && bin/configlet` to ensure the exercise is configured correctly.
72
+
@@ -0,0 +1,32 @@
1
+ #!/bin/bash
2
+
3
+ LATEST=https://github.com/exercism/configlet/releases/latest
4
+
5
+ OS=$(
6
+ case $(uname) in
7
+ (Darwin*)
8
+ echo "mac";;
9
+ (Linux*)
10
+ echo "linux";;
11
+ (Windows*)
12
+ echo "windows";;
13
+ (*)
14
+ echo "linux";;
15
+ esac)
16
+
17
+ ARCH=$(
18
+ case $(uname -m) in
19
+ (*64*)
20
+ echo 64bit;;
21
+ (*686*)
22
+ echo 32bit;;
23
+ (*386*)
24
+ echo 32bit;;
25
+ (*)
26
+ echo 64bit;;
27
+ esac)
28
+
29
+ VERSION="$(curl --head --silent $LATEST | awk -v FS=/ '/Location:/{print $NF}' | tr -d '\r')"
30
+ URL=https://github.com/exercism/configlet/releases/download/$VERSION/configlet-$OS-${ARCH}.tgz
31
+
32
+ curl -s --location $URL | tar xz -C bin/
@@ -0,0 +1,21 @@
1
+ {
2
+ "slug": "clojurescript",
3
+ "language": "ClojureScript",
4
+ "repository": "https://github.com/exercism/xclojurescript",
5
+ "active": false,
6
+ "test_pattern": "TODO",
7
+ "exercises": [
8
+
9
+ ],
10
+ "deprecated": [
11
+
12
+ ],
13
+ "ignored": [
14
+ "bin",
15
+ "img",
16
+ "docs"
17
+ ],
18
+ "foregone": [
19
+
20
+ ]
21
+ }
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -13,7 +13,19 @@ public void Add(string student, int grade)
13
13
  roster.Add(grade, new SortedList<string> { student });
14
14
  }
15
15
 
16
- public IEnumerable<string> Roster(int grade) => roster[grade];
16
+ public IEnumerable<string> Roster()
17
+ {
18
+ var students = new List<string>();
19
+
20
+ foreach (var item in roster)
21
+ {
22
+ foreach (var student in item.Value)
23
+ {
24
+ students.Add(student);
25
+ }
26
+ }
27
+ return students;
28
+ }
17
29
 
18
30
  public IEnumerable<string> Grade(int grade)
19
31
  {
@@ -8,7 +8,7 @@ public void Add(string student, int grade)
8
8
  throw new NotImplementedException("You need to implement this function.");
9
9
  }
10
10
 
11
- public IEnumerable<string> Roster(int grade)
11
+ public IEnumerable<string> Roster()
12
12
  {
13
13
  throw new NotImplementedException("You need to implement this function.");
14
14
  }
@@ -2,60 +2,84 @@
2
2
 
3
3
  public class GradeSchoolTest
4
4
  {
5
- private readonly School school = new School();
6
-
7
5
  [Fact]
8
- public void Adding_a_student_adds_them_to_the_roster_for_the_given_grade()
6
+ public void Adding_a_student_adds_them_to_the_sorted_roster()
9
7
  {
8
+ var school = new School();
10
9
  school.Add("Aimee", 2);
11
- var expected = new [] { "Aimee" };
12
- Assert.Equal(expected, school.Roster(2));
10
+
11
+ var actual = school.Roster();
12
+
13
+ var expected = new[] { "Aimee" };
14
+ Assert.Equal(expected, actual);
13
15
  }
14
16
 
15
17
  [Fact(Skip = "Remove to run test")]
16
- public void Adding_more_students_to_the_same_grade_adds_them_to_the_roster()
18
+ public void Adding_more_students_adds_them_to_the_sorted_roster()
17
19
  {
20
+ var school = new School();
18
21
  school.Add("Blair", 2);
19
22
  school.Add("James", 2);
20
23
  school.Add("Paul", 2);
21
- var expected = new [] { "Blair", "James", "Paul" };
22
- Assert.Equal(expected, school.Roster(2));
24
+
25
+ var actual = school.Roster();
26
+
27
+ var expected = new[] { "Blair", "James", "Paul" };
28
+ Assert.Equal(expected, actual );
23
29
  }
24
30
 
25
31
  [Fact(Skip = "Remove to run test")]
26
- public void Adding_students_to_different_grades_adds_them_to_the_roster()
32
+ public void Adding_students_to_different_grades_adds_them_to_the_same_sorted_roster()
27
33
  {
34
+ var school = new School();
28
35
  school.Add("Chelsea", 3);
29
36
  school.Add("Logan", 7);
30
- Assert.Equal(new [] { "Chelsea" }, school.Roster(3));
31
- Assert.Equal(new [] { "Logan" }, school.Roster(7));
37
+
38
+ var actual = school.Roster();
39
+
40
+ var expected = new[] { "Chelsea", "Logan"};
41
+ Assert.Equal(expected, actual);
32
42
  }
33
43
 
34
44
  [Fact(Skip = "Remove to run test")]
35
45
  public void Grade_returns_the_students_in_that_grade_in_alphabetical_order()
36
46
  {
47
+ var school = new School();
37
48
  school.Add("Franklin", 5);
38
49
  school.Add("Bradley", 5);
39
50
  school.Add("Jeff", 1);
40
- var expected = new [] { "Bradley", "Franklin" };
41
- Assert.Equal(expected, school.Grade(5));
51
+
52
+ var actual = school.Grade(5);
53
+
54
+ var expected = new[] { "Bradley", "Franklin" };
55
+ Assert.Equal(expected, actual);
42
56
  }
43
57
 
44
58
  [Fact(Skip = "Remove to run test")]
45
59
  public void Grade_returns_an_empty_list_if_there_are_no_students_in_that_grade()
46
60
  {
47
- Assert.Empty(school.Grade(1));
61
+ var school = new School();
62
+
63
+ var actual = school.Grade(1);
64
+
65
+ Assert.Empty(actual);
48
66
  }
49
67
 
50
68
  [Fact(Skip = "Remove to run test")]
51
- public void Student_names_in_each_grade_in_roster_are_sorted()
69
+ public void Student_names_with_grades_are_displayed_in_the_same_sorted_roster()
52
70
  {
71
+ var school = new School();
53
72
  school.Add("Jennifer", 4);
54
73
  school.Add("Kareem", 6);
55
74
  school.Add("Christopher", 4);
56
75
  school.Add("Kyle", 3);
57
- Assert.Equal(new [] { "Kyle" }, school.Roster(3));
58
- Assert.Equal(new [] { "Christopher", "Jennifer" }, school.Roster(4));
59
- Assert.Equal(new [] { "Kareem" }, school.Roster(6));
76
+
77
+ var actual = school.Roster();
78
+
79
+
80
+ var expected = new[] { "Christopher", "Jennifer", "Kareem", "Kyle" };
81
+ Assert.Equal(expected, actual);
82
+
83
+
60
84
  }
61
85
  }
@@ -130,6 +130,14 @@ By convention, the stub file for an exercise with slug `exercise-slug`
130
130
  must be named `exercise_slug.go`. This is because CI needs to delete stub files
131
131
  to avoid conflicting definitions.
132
132
 
133
+ The track exercises may or may not provide stub files. The first few exercises
134
+ provide stubs as a helpful starting point. The initial exercise users will encounter
135
+ without a stub is [twelve-days](exercises/twelve-days/). At this point users will
136
+ have some experience in creating solutions for the exercises and can begin to
137
+ create their own solutions from scratch. Some of the later exercises may have stub
138
+ files if the author thinks there may be implementation confusion, a particularly
139
+ difficult concept, or boilerplate code needed.
140
+
133
141
  ### Problem Versioning
134
142
 
135
143
  Each problem defines a `const targetTestVersion` in the test file, and validates
@@ -0,0 +1,2 @@
1
+ ## No Stub
2
+ This is the first Go track exercise you encounter without a stub: a pre-existing "twelve-days.go" file for your solution. You may not see stubs in the future and should begin to get comfortable with creating your own Go files for your solutions.
@@ -510,7 +510,6 @@
510
510
  "trinary"
511
511
  ],
512
512
  "ignored": [
513
- "common",
514
513
  "docs",
515
514
  "img"
516
515
  ],
@@ -280,6 +280,15 @@
280
280
  "Searching"
281
281
  ]
282
282
  },
283
+ {
284
+ "difficulty": 4,
285
+ "slug": "crypto-square",
286
+ "topics": [
287
+ "Looping",
288
+ "Transforming",
289
+ "Strings"
290
+ ]
291
+ },
283
292
  {
284
293
  "difficulty": 5,
285
294
  "slug": "bracket-push",