Skip to content

Commit 0eadc8e

Browse files
committed
Merge pull request #21 from bkaestner/issue-20-solutions
Add information on how to handle reference solutions
2 parents 19dfa7b + 706415c commit 0eadc8e

File tree

2 files changed

+40
-8
lines changed

2 files changed

+40
-8
lines changed

rules/0100-Writing-a-kata.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -144,14 +144,14 @@ possible, use the proper type and avoid string, unless it leads to convoluted co
144144

145145
Use the preloaded section only for helpers or constraints
146146
---------------------------------------------------------
147-
While it might seem tempting to put your solution into the preloaded code
148-
section, don't. Some languages provide reflection or similar means to check your
149-
preloaded code, which enables a user to cheat rather easily.
150-
151-
Also, if you're using a dynamic language like Python, JavaScript or Ruby, keep
152-
in mind that the user can change `Math.random` or similar features unless you
153-
use `Object.freeze` or similar. Java, Haskell, C# and potential other statically
154-
typed languages don't share this problem.
147+
The preloaded code is both usable by you and the user. It's the perfect place to
148+
put helpers or data structures that the user should use, or to freeze objects in
149+
dynamic languages.
150+
151+
However, __never__ put your solution into the preloaded code! Some languages
152+
provide reflection or similar means to check your preloaded code, which enables
153+
a user to cheat rather easily. Instead, put your solution into a local scope
154+
(see "Hide your solution").
155155

156156

157157
Provide helpers for tasks that are dull

rules/0120-Tests.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,38 @@ This is usually the hard part of creating random tests. After all, creating
9696
sufficient random input is most often harder than creating the kata itself.
9797
But it is worth every honour.
9898

99+
### Hide your solution
100+
If you use random tests, make sure to hide your solution. In Java or C#, this
101+
includes making your function `private`. Haskell doesn't allow mutual imports,
102+
so the user cannot import the tests either way. However, in dynamic languages,
103+
one can sometimes simply use `solve = solution`.
104+
105+
You can prevent this kind of cheating if you
106+
107+
- add static tests (not only random ones),
108+
- move your solution into a local scope.
109+
110+
The first one is obvious. The second one can be realized if you don't provide
111+
a `solution` with the same interface, but instead a `testAgainstSolution`:
112+
113+
```javascript
114+
// bad!
115+
var solution = function(a, b){
116+
// ...
117+
}
118+
119+
// better
120+
var testFunction = function(a,b){
121+
var solution = function(a, b) {
122+
// ...
123+
}
124+
Test.assertEquals(userFunc(a,b), solution(a,b));
125+
}
126+
```
127+
There are more creative ways to hide/store the function, but that's one way
128+
at least. Note that all dynamic languages on Codewars (Ruby, Python, CS, JS)
129+
support this kind of local scopes.
130+
99131
### Always have some example tests
100132

101133
Unless you're creating a puzzle where the user has to find *the answer*,

0 commit comments

Comments
 (0)