trackler 2.2.1.83 → 2.2.1.84

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 (27) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/tracks/bash/config.json +43 -6
  4. data/tracks/bash/exercises/collatz-conjecture/README.md +34 -0
  5. data/tracks/bash/exercises/collatz-conjecture/collatz_test.sh +49 -0
  6. data/tracks/bash/exercises/collatz-conjecture/example.sh +22 -0
  7. data/tracks/bash/exercises/grains/README.md +35 -0
  8. data/tracks/bash/exercises/grains/example.sh +10 -0
  9. data/tracks/bash/exercises/grains/grains_test.sh +81 -0
  10. data/tracks/bash/exercises/luhn/README.md +76 -0
  11. data/tracks/bash/exercises/luhn/example.sh +32 -0
  12. data/tracks/bash/exercises/luhn/luhn_test.sh +105 -0
  13. data/tracks/clojure/config.json +9 -1
  14. data/tracks/clojure/exercises/two-fer/README.md +19 -0
  15. data/tracks/clojure/exercises/two-fer/project.clj +4 -0
  16. data/tracks/clojure/exercises/two-fer/src/example.clj +5 -0
  17. data/tracks/clojure/exercises/two-fer/src/two_fer.clj +5 -0
  18. data/tracks/clojure/exercises/two-fer/test/two_fer_test.clj +12 -0
  19. data/tracks/python/config.json +5 -3
  20. data/tracks/python/exercises/parallel-letter-frequency/README.md +36 -0
  21. data/tracks/python/exercises/parallel-letter-frequency/example.py +56 -0
  22. data/tracks/python/exercises/parallel-letter-frequency/parallel_letter_frequency.py +2 -0
  23. data/tracks/python/exercises/parallel-letter-frequency/parallel_letter_frequency_test.py +61 -0
  24. data/tracks/python/exercises/reverse-string/reverse_string_test.py +5 -5
  25. data/tracks/ruby/README.md +7 -1
  26. data/tracks/ruby/exercises/rotational-cipher/README.md +63 -0
  27. metadata +21 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fd3db94a01e41282f6733f0e8356e7781580009a
4
- data.tar.gz: 25464cb3caef3b9481c20cea3a1e3667d8ffee6b
3
+ metadata.gz: d3ec763db2b39453f204556765096d8b89410636
4
+ data.tar.gz: 0b10a5133a6d4f9fa08142ae215484fd257b8bc7
5
5
  SHA512:
6
- metadata.gz: bb80d176aca640ed2e83cd55815849ff454d6184118095d1af15168bdaedbdb6abeae8dd94e527922e2945e7913f249018ecf38b9d1e3b19de6be8b915cde5c6
7
- data.tar.gz: e54cbb2d9efcac874d7aacba8ed97a916adb53c639e3f01f212e08685fbeaa3fbd5bdbb84e3ec666f2b1df70cc1023af18aaaa8efc545dd24ffbc020c74afd20
6
+ metadata.gz: 136ccecbe72a54b7da0c44b660a02b8dbe4e0304d0e42360f71f53937617221936a011a525b5f6ccd00f98e7ba969b7ddf52f8c16d4725c247a80d078c3731ce
7
+ data.tar.gz: 3d20a2d47b630cc688667dc3ad626e13c603f50c61a969b19a4059cc3a4ed61b74d72a7ef57ac09340cfb84d8d9502f9a637e1b4e88f8f61b15611010d561639
@@ -1,3 +1,3 @@
1
1
  module Trackler
2
- VERSION = "2.2.1.83"
2
+ VERSION = "2.2.1.84"
3
3
  end
@@ -51,6 +51,17 @@
51
51
  ],
52
52
  "uuid": "e24451fd-761d-4d20-81d9-e470486ec44a"
53
53
  },
54
+ {
55
+ "core": true,
56
+ "difficulty": 1,
57
+ "slug": "grains",
58
+ "topics": [
59
+ "control_flow_conditionals",
60
+ "input_validation",
61
+ "mathematics"
62
+ ],
63
+ "uuid": "c9d36155-10e8-4a75-a732-3c43a68910eb"
64
+ },
54
65
  {
55
66
  "core": false,
56
67
  "difficulty": 1,
@@ -182,6 +193,19 @@
182
193
  "unlocked_by": "pangram",
183
194
  "uuid": "51bd6542-408b-4a73-8343-1c4d50db5315"
184
195
  },
196
+ {
197
+ "core": false,
198
+ "difficulty": 2,
199
+ "slug": "triangle",
200
+ "topics": [
201
+ "boolean_logic",
202
+ "input_validation",
203
+ "number_comparison",
204
+ "mathematics"
205
+ ],
206
+ "unlocked_by": "leap",
207
+ "uuid": "0f79f9ab-4a51-468c-88ca-84f0bf7cfc38"
208
+ },
185
209
  {
186
210
  "core": false,
187
211
  "difficulty": 2,
@@ -195,16 +219,29 @@
195
219
  },
196
220
  {
197
221
  "core": false,
198
- "difficulty": 2,
199
- "slug": "triangle",
222
+ "difficulty": 3,
223
+ "slug": "luhn",
200
224
  "topics": [
201
- "boolean_logic",
225
+ "algorithms",
226
+ "control_flow_conditionals",
227
+ "integers",
228
+ "mathematics"
229
+ ],
230
+ "unlocked_by": "difference-of-squares",
231
+ "uuid": "a3b16d02-2963-445d-9339-7e3002375a71"
232
+ },
233
+ {
234
+ "core": false,
235
+ "difficulty": 3,
236
+ "slug": "collatz-conjecture",
237
+ "topics": [
238
+ "control_flow_conditionals",
202
239
  "input_validation",
203
- "number_comparison",
240
+ "integers",
204
241
  "mathematics"
205
242
  ],
206
- "unlocked_by": "leap",
207
- "uuid": "bd8fd05e-3f8d-4a1f-a9d8-e6223dcc6f93"
243
+ "unlocked_by": "armstrong-numbers",
244
+ "uuid": "b4793e6d-f443-41ea-8289-95e18a5dbef4"
208
245
  },
209
246
  {
210
247
  "core": false,
@@ -0,0 +1,34 @@
1
+ # Collatz Conjecture
2
+
3
+ The Collatz Conjecture or 3x+1 problem can be summarized as follows:
4
+
5
+ Take any positive integer n. If n is even, divide n by 2 to get n / 2. If n is
6
+ odd, multiply n by 3 and add 1 to get 3n + 1. Repeat the process indefinitely.
7
+ The conjecture states that no matter which number you start with, you will
8
+ always reach 1 eventually.
9
+
10
+ Given a number n, return the number of steps required to reach 1.
11
+
12
+ ## Examples
13
+
14
+ Starting with n = 12, the steps would be as follows:
15
+
16
+ 0. 12
17
+ 1. 6
18
+ 2. 3
19
+ 3. 10
20
+ 4. 5
21
+ 5. 16
22
+ 6. 8
23
+ 7. 4
24
+ 8. 2
25
+ 9. 1
26
+
27
+ Resulting in 9 steps. So for input n = 12, the return value would be 9.
28
+
29
+ ## Source
30
+
31
+ An unsolved problem in mathematics named after mathematician Lothar Collatz [Wikipedia](https://en.wikipedia.org/wiki/3x_%2B_1_problem)
32
+
33
+ ## Submitting Incomplete Solutions
34
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env bats
2
+
3
+ @test "zero steps for one" {
4
+ #skip
5
+ run bash collatz.sh 1
6
+
7
+ [ "$status" -eq 0 ]
8
+ [ "$output" -eq 0 ]
9
+ }
10
+
11
+ @test "divide if even" {
12
+ skip
13
+ run bash collatz.sh 16
14
+
15
+ [ "$status" -eq 0 ]
16
+ [ "$output" -eq 4 ]
17
+ }
18
+
19
+ @test "even and odd steps" {
20
+ skip
21
+ run bash collatz.sh 12
22
+
23
+ [ "$status" -eq 0 ]
24
+ [ "$output" -eq 9 ]
25
+ }
26
+
27
+ @test "large number of even and odd steps" {
28
+ skip
29
+ run bash collatz.sh 1000000
30
+
31
+ [ "$status" -eq 0 ]
32
+ [ "$output" -eq 152 ]
33
+ }
34
+
35
+ @test "zero is an error" {
36
+ skip
37
+ run bash collatz.sh 0
38
+
39
+ [ "$status" -eq 1 ]
40
+ [ "$output" == "Error: Only positive numbers are allowed" ]
41
+ }
42
+
43
+ @test "negative value is an error" {
44
+ skip
45
+ run bash collatz.sh -15
46
+
47
+ [ "$status" -eq 1 ]
48
+ [ "$output" == "Error: Only positive numbers are allowed" ]
49
+ }
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env bash
2
+
3
+ if [ "$1" -gt 0 ]; then
4
+ N=$1
5
+ else
6
+ echo "Error: Only positive numbers are allowed"
7
+ exit 1
8
+ fi
9
+
10
+ STEP=0
11
+
12
+ while [ "$N" -ne "1" ]
13
+ do
14
+ if [ "$(($N % 2))" -eq "0" ]; then
15
+ N=$(($N / 2))
16
+ else
17
+ N=$((($N * 3) + 1))
18
+ fi
19
+ STEP=$(($STEP + 1))
20
+ done
21
+
22
+ echo $STEP
@@ -0,0 +1,35 @@
1
+ # Grains
2
+
3
+ Calculate the number of grains of wheat on a chessboard given that the number
4
+ on each square doubles.
5
+
6
+ There once was a wise servant who saved the life of a prince. The king
7
+ promised to pay whatever the servant could dream up. Knowing that the
8
+ king loved chess, the servant told the king he would like to have grains
9
+ of wheat. One grain on the first square of a chess board. Two grains on
10
+ the next. Four on the third, and so on.
11
+
12
+ There are 64 squares on a chessboard.
13
+
14
+ Write code that shows:
15
+ - how many grains were on each square, and
16
+ - the total number of grains
17
+
18
+ ## For bonus points
19
+
20
+ Did you get the tests passing and the code clean? If you want to, these
21
+ are some additional things you could try:
22
+
23
+ - Optimize for speed.
24
+ - Optimize for readability.
25
+
26
+ Then please share your thoughts in a comment on the submission. Did this
27
+ experiment make the code better? Worse? Did you learn anything from it?
28
+
29
+ ## Source
30
+
31
+ Calculate the number of grains of wheat on a chessboard given that the number on each square doubles. [JavaRanch Cattle Drive, exercise 6](http://www.javaranch.com/grains.jsp)
32
+
33
+ ## Submitting Incomplete Solutions
34
+
35
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,10 @@
1
+ #!/bin/bash
2
+
3
+ if [[ "$1" -lt 1 || "$1" -gt 64 ]];
4
+ then
5
+ echo "Error: invalid input"
6
+ exit 1;
7
+ else
8
+ index=$(($1-1))
9
+ echo "2^$index" | bc;
10
+ fi;
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env bats
2
+
3
+ @test "Square 1" {
4
+ #skip
5
+ run bash grains.sh 1
6
+
7
+ [ "$status" -eq 0 ]
8
+ [ "$output" = "1" ]
9
+ }
10
+
11
+ @test "Square 2" {
12
+ #skip
13
+ run bash grains.sh 2
14
+
15
+ [ "$status" -eq 0 ]
16
+ [ "$output" = "2" ]
17
+ }
18
+
19
+ @test "Square 3" {
20
+ #skip
21
+ run bash grains.sh 3
22
+
23
+ [ "$status" -eq 0 ]
24
+ [ "$output" = "4" ]
25
+ }
26
+
27
+ @test "Square 4" {
28
+ #skip
29
+ run bash grains.sh 4
30
+
31
+ [ "$status" -eq 0 ]
32
+ [ "$output" = "8" ]
33
+ }
34
+
35
+ @test "Square 16" {
36
+ #skip
37
+ run bash grains.sh 16
38
+
39
+ [ "$status" -eq 0 ]
40
+ [ "$output" = "32768" ]
41
+ }
42
+
43
+ @test "Square 32" {
44
+ #skip
45
+ run bash grains.sh 32
46
+
47
+ [ "$status" -eq 0 ]
48
+ [ "$output" = "2147483648" ]
49
+ }
50
+
51
+ @test "Square 64" {
52
+ #skip
53
+ run bash grains.sh 64
54
+
55
+ [ "$status" -eq 0 ]
56
+ [ "$output" = "9223372036854775808" ]
57
+ }
58
+
59
+ @test "Square 0 causes error" {
60
+ #skip
61
+ run bash grains.sh 0
62
+
63
+ [ "$status" -eq 1 ]
64
+ [ "$output" = "Error: invalid input" ]
65
+ }
66
+
67
+ @test "Square -1 causes error" {
68
+ #skip
69
+ run bash grains.sh -1
70
+
71
+ [ "$status" -eq 1 ]
72
+ [ "$output" = "Error: invalid input" ]
73
+ }
74
+
75
+ @test "Square 65 causes error" {
76
+ #skip
77
+ run bash grains.sh 65
78
+
79
+ [ "$status" -eq 1 ]
80
+ [ "$output" = "Error: invalid input" ]
81
+ }
@@ -0,0 +1,76 @@
1
+ # Luhn
2
+
3
+ Given a number determine whether or not it is valid per the Luhn formula.
4
+
5
+ The [Luhn algorithm](https://en.wikipedia.org/wiki/Luhn_algorithm) is
6
+ a simple checksum formula used to validate a variety of identification
7
+ numbers, such as credit card numbers and Canadian Social Insurance
8
+ Numbers.
9
+
10
+ The task is to check if a given string is valid.
11
+
12
+ Validating a Number
13
+ ------
14
+
15
+ Strings of length 1 or less are not valid. Spaces are allowed in the input,
16
+ but they should be stripped before checking. All other non-digit characters
17
+ are disallowed.
18
+
19
+ ## Example 1: valid credit card number
20
+
21
+ ```text
22
+ 4539 1488 0343 6467
23
+ ```
24
+
25
+ The first step of the Luhn algorithm is to double every second digit,
26
+ starting from the right. We will be doubling
27
+
28
+ ```text
29
+ 4_3_ 1_8_ 0_4_ 6_6_
30
+ ```
31
+
32
+ If doubling the number results in a number greater than 9 then subtract 9
33
+ from the product. The results of our doubling:
34
+
35
+ ```text
36
+ 8569 2478 0383 3437
37
+ ```
38
+
39
+ Then sum all of the digits:
40
+
41
+ ```text
42
+ 8+5+6+9+2+4+7+8+0+3+8+3+3+4+3+7 = 80
43
+ ```
44
+
45
+ If the sum is evenly divisible by 10, then the number is valid. This number is valid!
46
+
47
+ ## Example 2: invalid credit card number
48
+
49
+ ```text
50
+ 8273 1232 7352 0569
51
+ ```
52
+
53
+ Double the second digits, starting from the right
54
+
55
+ ```text
56
+ 7253 2262 5312 0539
57
+ ```
58
+
59
+ Sum the digits
60
+
61
+ ```text
62
+ 7+2+5+3+2+2+6+2+5+3+1+2+0+5+3+9 = 57
63
+ ```
64
+
65
+ 57 is not evenly divisible by 10, so this number is not valid.
66
+
67
+ Run the tests with:
68
+
69
+ bats whatever_test.sh
70
+
71
+ ## Source
72
+
73
+ The Luhn Algorithm on Wikipedia [Wikipedia](http://en.wikipedia.org/wiki/Luhn_algorithm)
74
+
75
+ ## Submitting Incomplete Solutions
76
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,32 @@
1
+ #!/bin/bash
2
+
3
+ num=$(echo "$1" | sed 's/[\ ]//g')
4
+
5
+ if ! [[ 10#$num -ge 0 ]] 2>/dev/null || ! [[ ${#num} -gt 1 ]] ; then
6
+ echo "false"
7
+ else
8
+ shift 1
9
+
10
+ len=${#num}
11
+ is_odd=1
12
+ sum=0
13
+
14
+ for((t = len - 1; t >= 0; --t)) {
15
+ digit=${num:$t:1}
16
+
17
+ if [[ $is_odd -eq 1 ]]; then
18
+ sum=$(( sum + $digit ))
19
+ else
20
+ sum=$(( $sum + ( $digit != 9 ? ( ( 2 * $digit ) % 9 ) : 9 ) ))
21
+ fi
22
+
23
+ is_odd=$(( ! $is_odd ))
24
+ }
25
+
26
+ if [[ 0 -eq $(( 0 != ( $sum % 10 ) )) ]] ; then
27
+ echo "true"
28
+ else
29
+ echo "false"
30
+ fi
31
+
32
+ fi
@@ -0,0 +1,105 @@
1
+ #!/usr/bin/env bats
2
+
3
+ @test "single digit strings cannot be valid" {
4
+ #skip
5
+ run bash luhn.sh "1"
6
+
7
+ [ "$status" -eq 0 ]
8
+ [ "$output" == "false" ]
9
+ }
10
+
11
+ @test "a single zero is invalid" {
12
+ #skip
13
+ run bash luhn.sh "0"
14
+
15
+ [ "$status" -eq 0 ]
16
+ [ "$output" == "false" ]
17
+ }
18
+
19
+ @test "a simple valid SIN that remains valid if reversed" {
20
+ #skip
21
+ run bash luhn.sh "059"
22
+
23
+ [ "$status" -eq 0 ]
24
+ [ "$output" == "true" ]
25
+ }
26
+
27
+ @test "a simple valid SIN that becomes invalid if reversed" {
28
+ #skip
29
+ run bash luhn.sh "59"
30
+
31
+ [ "$status" -eq 0 ]
32
+ [ "$output" == "true" ]
33
+ }
34
+
35
+ @test "a valid Canadian SIN" {
36
+ #skip
37
+ run bash luhn.sh "055 444 285"
38
+
39
+ [ "$status" -eq 0 ]
40
+ [ "$output" == "true" ]
41
+ }
42
+
43
+ @test "invalid Canadian SID" {
44
+ #skip
45
+ run bash luhn.sh "055 444 286"
46
+
47
+ [ "$status" -eq 0 ]
48
+ [ "$output" == "false" ]
49
+ }
50
+
51
+ @test "invalid credit card" {
52
+ #skip
53
+ run bash luhn.sh "8273 1232 7352 0569"
54
+
55
+ [ "$status" -eq 0 ]
56
+ [ "$output" == "false" ]
57
+ }
58
+
59
+ @test "valid strings with a non-digit included become invalid" {
60
+ #skip
61
+ run bash luhn.sh "055a 444 285"
62
+
63
+ [ "$status" -eq 0 ]
64
+ [ "$output" == "false" ]
65
+ }
66
+
67
+ @test "valid strings with punctuation included become invalid" {
68
+ #skip
69
+ run bash luhn.sh "055-444-285"
70
+
71
+ [ "$status" -eq 0 ]
72
+ [ "$output" == "false" ]
73
+ }
74
+
75
+ @test "valid strings with symbols included become invalid" {
76
+ #skip
77
+ run bash luhn.sh "055£ 444$ 285"
78
+
79
+ [ "$status" -eq 0 ]
80
+ [ "$output" == "false" ]
81
+ }
82
+
83
+ @test "single zero with space is invalid" {
84
+ #skip
85
+ run bash luhn.sh " 0"
86
+
87
+ [ "$status" -eq 0 ]
88
+ [ "$output" == "false" ]
89
+ }
90
+
91
+ @test "more than a single zero is valid" {
92
+ #skip
93
+ run bash luhn.sh "0000 0"
94
+
95
+ [ "$status" -eq 0 ]
96
+ [ "$output" == "true" ]
97
+ }
98
+
99
+ @test "input digit 9 is correctly converted to output digit 9" {
100
+ #skip
101
+ run bash luhn.sh "091"
102
+
103
+ [ "$status" -eq 0 ]
104
+ [ "$output" == "true" ]
105
+ }
@@ -17,6 +17,14 @@
17
17
  "unlocked_by": null,
18
18
  "uuid": "a4bdbdfd-1db1-425c-a243-dd032dc7b93a"
19
19
  },
20
+ {
21
+ "core": false,
22
+ "difficulty": 1,
23
+ "slug": "two-fer",
24
+ "topics": null,
25
+ "unlocked_by": null,
26
+ "uuid": "91a1f32c-0dac-4c65-8a13-49da90d21520"
27
+ },
20
28
  {
21
29
  "core": false,
22
30
  "difficulty": 1,
@@ -585,4 +593,4 @@
585
593
  ],
586
594
  "foregone": [],
587
595
  "language": "Clojure"
588
- }
596
+ }
@@ -0,0 +1,19 @@
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
+ ## Source
15
+
16
+ This is an exercise to introduce users to basic programming constructs, just after hello World. [http://en.wikipedia.org/wiki/Two-fer](http://en.wikipedia.org/wiki/Two-fer)
17
+
18
+ ## Submitting Incomplete Solutions
19
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,4 @@
1
+ (defproject two-fer "0.1.0-SNAPSHOT"
2
+ :description "two-fer exercise."
3
+ :url "https://github.com/exercism/clojure/tree/master/exercises/two-fer"
4
+ :dependencies [[org.clojure/clojure "1.8.0"]])
@@ -0,0 +1,5 @@
1
+ (ns two-fer)
2
+
3
+ (defn two-fer
4
+ ([] (str "One for you, one for me."))
5
+ ([name] (str "One for " name ", one for me.")))
@@ -0,0 +1,5 @@
1
+ (ns two-fer)
2
+
3
+ (defn two-fer [] ;; <- arglist goes here
4
+ ;; your code goes here
5
+ )
@@ -0,0 +1,12 @@
1
+ (ns two-fer-test
2
+ (:require [clojure.test :refer [deftest is]]
3
+ two-fer))
4
+
5
+ (deftest two-fer-test
6
+ (is (= "One for you, one for me." (two-fer/two-fer))))
7
+
8
+ (deftest name-alice-test
9
+ (is (= "One for Alice, one for me." (two-fer/two-fer "Alice"))))
10
+
11
+ (deftest name-bob-test
12
+ (is (= "One for Bob, one for me." (two-fer/two-fer "Bob"))))
@@ -1298,9 +1298,11 @@
1298
1298
  "uuid": "6b7f7b1f-c388-4f4c-b924-84535cc5e1a0",
1299
1299
  "slug": "hexadecimal",
1300
1300
  "deprecated": true
1301
+ },
1302
+ {
1303
+ "uuid": "da03fca4-4606-48d8-9137-6e40396f7759",
1304
+ "slug": "parallel-letter-frequency",
1305
+ "deprecated": true
1301
1306
  }
1302
- ],
1303
- "foregone": [
1304
- "parallel-letter-frequency"
1305
1307
  ]
1306
1308
  }
@@ -0,0 +1,36 @@
1
+ # Parallel Letter Frequency
2
+
3
+ Count the frequency of letters in texts using parallel computation.
4
+
5
+ Parallelism is about doing things in parallel that can also be done
6
+ sequentially. A common example is counting the frequency of letters.
7
+ Create a function that returns the total frequency of each letter in a
8
+ list of texts and that employs parallelism.
9
+
10
+ ## Exception messages
11
+
12
+ Sometimes it is necessary to raise an exception. When you do this, you should include a meaningful error message to
13
+ indicate what the source of the error is. This makes your code more readable and helps significantly with debugging. Not
14
+ every exercise will require you to raise an exception, but for those that do, the tests will only pass if you include
15
+ a message.
16
+
17
+ To raise a message with an exception, just write it as an argument to the exception type. For example, instead of
18
+ `raise Exception`, you shold write:
19
+
20
+ ```python
21
+ raise Exception("Meaningful message indicating the source of the error")
22
+ ```
23
+
24
+
25
+ ## Submitting Exercises
26
+
27
+ Note that, when trying to submit an exercise, make sure the solution is in the `exercism/python/<exerciseName>` directory.
28
+
29
+ For example, if you're submitting `bob.py` for the Bob exercise, the submit command would be something like `exercism submit <path_to_exercism_dir>/python/bob/bob.py`.
30
+
31
+ For more detailed information about running tests, code style and linting,
32
+ please see the [help page](http://exercism.io/languages/python).
33
+
34
+
35
+ ## Submitting Incomplete Solutions
36
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,56 @@
1
+ # -*- coding: utf-8 -*-
2
+ from collections import Counter
3
+ from threading import Lock, Thread
4
+ from time import sleep
5
+ import sys
6
+ if sys.version[0] == '2':
7
+ from Queue import Queue
8
+ else:
9
+ from queue import Queue
10
+
11
+ total_workers = 3 # Maximum number of threads chosen arbitrarily
12
+
13
+
14
+ class LetterCounter(object):
15
+
16
+ def __init__(self):
17
+ self.lock = Lock()
18
+ self.value = Counter()
19
+
20
+ def add_counter(self, counter_to_add):
21
+ self.lock.acquire()
22
+ try:
23
+ self.value = self.value + counter_to_add
24
+ finally:
25
+ self.lock.release()
26
+
27
+
28
+ def count_letters(queue_of_texts, letter_to_frequency, worker_id):
29
+ while not queue_of_texts.empty():
30
+ sleep(worker_id + 1)
31
+ line_input = queue_of_texts.get()
32
+ if line_input is not None:
33
+ letters_in_line = Counter([x for x in line_input.lower() if
34
+ x.isalpha()])
35
+ letter_to_frequency.add_counter(letters_in_line)
36
+ queue_of_texts.task_done()
37
+ if line_input is None:
38
+ break
39
+
40
+
41
+ def calculate(list_of_texts):
42
+ queue_of_texts = Queue()
43
+ [queue_of_texts.put(line) for line in list_of_texts]
44
+ letter_to_frequency = LetterCounter()
45
+ threads = []
46
+ for i in range(total_workers):
47
+ worker = Thread(target=count_letters, args=(queue_of_texts,
48
+ letter_to_frequency, i))
49
+ worker.start()
50
+ threads.append(worker)
51
+ queue_of_texts.join()
52
+ for i in range(total_workers):
53
+ queue_of_texts.put(None)
54
+ for t in threads:
55
+ t.join()
56
+ return letter_to_frequency.value
@@ -0,0 +1,2 @@
1
+ def calculate(text_input):
2
+ pass
@@ -0,0 +1,61 @@
1
+ # -*- coding: utf-8 -*-
2
+ from collections import Counter
3
+ import unittest
4
+
5
+ from parallel_letter_frequency import calculate
6
+
7
+
8
+ class ParallelLetterFrequencyTest(unittest.TestCase):
9
+ def test_one_letter(self):
10
+ actual = calculate(['a'])
11
+ expected = {'a': 1}
12
+ self.assertDictEqual(actual, expected)
13
+
14
+ def test_case_insensitivity(self):
15
+ actual = calculate(['aA'])
16
+ expected = {'a': 2}
17
+ self.assertDictEqual(actual, expected)
18
+
19
+ def test_numbers(self):
20
+ actual = calculate(['012', '345', '6789'])
21
+ expected = {}
22
+ self.assertDictEqual(actual, expected)
23
+
24
+ def test_punctuations(self):
25
+ actual = calculate(['[]\;,', './{}|', ':"<>?'])
26
+ expected = {}
27
+ self.assertDictEqual(actual, expected)
28
+
29
+ def test_whitespaces(self):
30
+ actual = calculate([' ', '\t ', '\n\n'])
31
+ expected = {}
32
+ self.assertDictEqual(actual, expected)
33
+
34
+ def test_repeated_string_with_known_frequencies(self):
35
+ letter_frequency = 3
36
+ text_input = 'abc\n' * letter_frequency
37
+ actual = calculate(text_input.split('\n'))
38
+ expected = {'a': letter_frequency, 'b': letter_frequency,
39
+ 'c': letter_frequency}
40
+ self.assertDictEqual(actual, expected)
41
+
42
+ def test_multiline_text(self):
43
+ text_input = "3 Quotes from Excerism Homepage:\n" + \
44
+ "\tOne moment you feel like you're\n" + \
45
+ "getting it. The next moment you're\n" + \
46
+ "stuck.\n" + \
47
+ "\tYou know what it’s like to be fluent.\n" + \
48
+ "Suddenly you’re feeling incompetent\n" + \
49
+ "and clumsy.\n" + \
50
+ "\tHaphazard, convoluted code is\n" + \
51
+ "infuriating, not to mention costly. That\n" + \
52
+ "slapdash explosion of complexity is an\n" + \
53
+ "expensive yak shave waiting to\n" + \
54
+ "happen."
55
+ actual = calculate(text_input.split('\n'))
56
+ expected = Counter([x for x in text_input.lower() if x.isalpha()])
57
+ self.assertDictEqual(actual, expected)
58
+
59
+
60
+ if __name__ == '__main__':
61
+ unittest.main()
@@ -6,19 +6,19 @@ from reverse_string import reverse
6
6
  # Tests adapted from `problem-specifications//canonical-data.json` @ v1.0.1
7
7
 
8
8
  class ReverseStringTests(unittest.TestCase):
9
- def empty_string(self):
9
+ def test_empty_string(self):
10
10
  self.assertEqual(reverse(''), '')
11
11
 
12
- def a_word(self):
12
+ def test_a_word(self):
13
13
  self.assertEqual(reverse('robot'), 'tobor')
14
14
 
15
- def a_capitalized_word(self):
15
+ def test_a_capitalized_word(self):
16
16
  self.assertEqual(reverse('Ramen'), 'nemaR')
17
17
 
18
- def a_sentence_with_punctuation(self):
18
+ def test_a_sentence_with_punctuation(self):
19
19
  self.assertEqual(reverse('I\'m hungry!'), '!yrgnuh m\'I')
20
20
 
21
- def a_palindrome(self):
21
+ def test_a_palindrome(self):
22
22
  self.assertEqual(reverse('racecar'), 'racecar')
23
23
 
24
24
 
@@ -315,9 +315,15 @@ string indices to integer indices.
315
315
 
316
316
  ## READMEs
317
317
 
318
- Do not add a README or README.md file to the exercise's directory. The READMEs
318
+ All exercises must have a README.md file, but should not be created manually. The READMEs
319
319
  are constructed using shared metadata, which lives in the [problem-specifications][] repo.
320
320
 
321
+ Use the `configlet` tool to generate a README from shared metadata:
322
+
323
+ 1. Clone the [problem-specifications][] repo into an adjacent directory.
324
+ 2. Fetch the configlet appropriate for your system: `bin/fetch-configlet`
325
+ 3. Generate the readme for a particular exercise: `bin/configlet generate . --only rotational-cipher`
326
+
321
327
  ## Contributing Guide
322
328
 
323
329
  For an in-depth discussion of how exercism language tracks and exercises work, please see the
@@ -0,0 +1,63 @@
1
+ # Rotational Cipher
2
+
3
+ Create an implementation of the rotational cipher, also sometimes called the Caesar cipher.
4
+
5
+ The Caesar cipher is a simple shift cipher that relies on
6
+ transposing all the letters in the alphabet using an integer key
7
+ between `0` and `26`. Using a key of `0` or `26` will always yield
8
+ the same output due to modular arithmetic. The letter is shifted
9
+ for as many values as the value of the key.
10
+
11
+ The general notation for rotational ciphers is `ROT + <key>`.
12
+ The most commonly used rotational cipher is `ROT13`.
13
+
14
+ A `ROT13` on the Latin alphabet would be as follows:
15
+
16
+ ```text
17
+ Plain: abcdefghijklmnopqrstuvwxyz
18
+ Cipher: nopqrstuvwxyzabcdefghijklm
19
+ ```
20
+
21
+ It is stronger than the Atbash cipher because it has 27 possible keys, and 25 usable keys.
22
+
23
+ Ciphertext is written out in the same formatting as the input including spaces and punctuation.
24
+
25
+ ## Examples
26
+
27
+ - ROT5 `omg` gives `trl`
28
+ - ROT0 `c` gives `c`
29
+ - ROT26 `Cool` gives `Cool`
30
+ - ROT13 `The quick brown fox jumps over the lazy dog.` gives `Gur dhvpx oebja sbk whzcf bire gur ynml qbt.`
31
+ - ROT13 `Gur dhvpx oebja sbk whzcf bire gur ynml qbt.` gives `The quick brown fox jumps over the lazy dog.`
32
+
33
+ * * * *
34
+
35
+ For installation and learning resources, refer to the
36
+ [exercism help page](http://exercism.io/languages/ruby).
37
+
38
+ For running the tests provided, you will need the Minitest gem. Open a
39
+ terminal window and run the following command to install minitest:
40
+
41
+ gem install minitest
42
+
43
+ If you would like color output, you can `require 'minitest/pride'` in
44
+ the test file, or note the alternative instruction, below, for running
45
+ the test file.
46
+
47
+ In order to run the test, you can run the test file from the exercise
48
+ directory. For example, if the test suite is called
49
+ `hello_world_test.rb`, you can run the following command:
50
+
51
+ ruby hello_world_test.rb
52
+
53
+ To include color from the command line:
54
+
55
+ ruby -r minitest/pride hello_world_test.rb
56
+
57
+
58
+ ## Source
59
+
60
+ Wikipedia [https://en.wikipedia.org/wiki/Caesar_cipher](https://en.wikipedia.org/wiki/Caesar_cipher)
61
+
62
+ ## Submitting Incomplete Solutions
63
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
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.83
4
+ version: 2.2.1.84
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-01-02 00:00:00.000000000 Z
11
+ date: 2018-01-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubyzip
@@ -621,6 +621,9 @@ files:
621
621
  - tracks/bash/exercises/bob/README.md
622
622
  - tracks/bash/exercises/bob/bob_test.sh
623
623
  - tracks/bash/exercises/bob/example.sh
624
+ - tracks/bash/exercises/collatz-conjecture/README.md
625
+ - tracks/bash/exercises/collatz-conjecture/collatz_test.sh
626
+ - tracks/bash/exercises/collatz-conjecture/example.sh
624
627
  - tracks/bash/exercises/difference-of-squares/README.md
625
628
  - tracks/bash/exercises/difference-of-squares/difference_of_squares_test.sh
626
629
  - tracks/bash/exercises/difference-of-squares/example.sh
@@ -631,6 +634,9 @@ files:
631
634
  - tracks/bash/exercises/gigasecond/README.md
632
635
  - tracks/bash/exercises/gigasecond/example.sh
633
636
  - tracks/bash/exercises/gigasecond/gigasecond_test.sh
637
+ - tracks/bash/exercises/grains/README.md
638
+ - tracks/bash/exercises/grains/example.sh
639
+ - tracks/bash/exercises/grains/grains_test.sh
634
640
  - tracks/bash/exercises/hamming/README.md
635
641
  - tracks/bash/exercises/hamming/example.sh
636
642
  - tracks/bash/exercises/hamming/hamming_test.sh
@@ -641,6 +647,9 @@ files:
641
647
  - tracks/bash/exercises/leap/README.md
642
648
  - tracks/bash/exercises/leap/example.sh
643
649
  - tracks/bash/exercises/leap/leap_test.sh
650
+ - tracks/bash/exercises/luhn/README.md
651
+ - tracks/bash/exercises/luhn/example.sh
652
+ - tracks/bash/exercises/luhn/luhn_test.sh
644
653
  - tracks/bash/exercises/nucleotide-count/README.md
645
654
  - tracks/bash/exercises/nucleotide-count/example.sh
646
655
  - tracks/bash/exercises/nucleotide-count/nucleotide_count_test.sh
@@ -1715,6 +1724,11 @@ files:
1715
1724
  - tracks/clojure/exercises/trinary/project.clj
1716
1725
  - tracks/clojure/exercises/trinary/src/example.clj
1717
1726
  - tracks/clojure/exercises/trinary/test/trinary_test.clj
1727
+ - tracks/clojure/exercises/two-fer/README.md
1728
+ - tracks/clojure/exercises/two-fer/project.clj
1729
+ - tracks/clojure/exercises/two-fer/src/example.clj
1730
+ - tracks/clojure/exercises/two-fer/src/two_fer.clj
1731
+ - tracks/clojure/exercises/two-fer/test/two_fer_test.clj
1718
1732
  - tracks/clojure/exercises/word-count/README.md
1719
1733
  - tracks/clojure/exercises/word-count/project.clj
1720
1734
  - tracks/clojure/exercises/word-count/src/example.clj
@@ -11085,6 +11099,10 @@ files:
11085
11099
  - tracks/python/exercises/pangram/example.py
11086
11100
  - tracks/python/exercises/pangram/pangram.py
11087
11101
  - tracks/python/exercises/pangram/pangram_test.py
11102
+ - tracks/python/exercises/parallel-letter-frequency/README.md
11103
+ - tracks/python/exercises/parallel-letter-frequency/example.py
11104
+ - tracks/python/exercises/parallel-letter-frequency/parallel_letter_frequency.py
11105
+ - tracks/python/exercises/parallel-letter-frequency/parallel_letter_frequency_test.py
11088
11106
  - tracks/python/exercises/pascals-triangle/README.md
11089
11107
  - tracks/python/exercises/pascals-triangle/example.py
11090
11108
  - tracks/python/exercises/pascals-triangle/pascals_triangle.py
@@ -11882,6 +11900,7 @@ files:
11882
11900
  - tracks/ruby/exercises/rotational-cipher/.meta/.version
11883
11901
  - tracks/ruby/exercises/rotational-cipher/.meta/generator/rotational_cipher_case.rb
11884
11902
  - tracks/ruby/exercises/rotational-cipher/.meta/solutions/rotational_cipher.rb
11903
+ - tracks/ruby/exercises/rotational-cipher/README.md
11885
11904
  - tracks/ruby/exercises/rotational-cipher/rotational_cipher_test.rb
11886
11905
  - tracks/ruby/exercises/run-length-encoding/.meta/.version
11887
11906
  - tracks/ruby/exercises/run-length-encoding/.meta/generator/run_length_encoding_case.rb