trackler 2.0.0.8 → 2.0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/common/exercises/bob/canonical-data.json +1 -20
- data/common/exercises/raindrops/canonical-data.json +18 -0
- data/common/exercises/sublist/canonical-data.json +5 -0
- data/lib/trackler/version.rb +1 -1
- data/tracks/clojure/config.json +5 -0
- data/tracks/clojure/exercises/pig-latin/project.clj +4 -0
- data/tracks/clojure/exercises/pig-latin/src/example.clj +49 -0
- data/tracks/clojure/exercises/pig-latin/test/pig_latin_test.clj +92 -0
- data/tracks/clojure/exercises/robot-name/src/example.clj +8 -11
- data/tracks/clojure/exercises/robot-name/test/robot_name_test.clj +23 -18
- data/tracks/crystal/config.json +6 -0
- data/tracks/crystal/exercises/acronym/spec/acronym_spec.cr +7 -7
- data/tracks/crystal/exercises/forth/spec/forth_spec.cr +198 -0
- data/tracks/crystal/exercises/forth/src/example.cr +187 -0
- data/tracks/crystal/exercises/hello-world/spec/hello_world_spec.cr +3 -3
- data/tracks/crystal/src/generator/exercises/acronym.cr +1 -1
- data/tracks/crystal/src/generator/exercises/exercise_generator.cr +3 -2
- data/tracks/crystal/src/generator/exercises/forth.cr +56 -0
- data/tracks/crystal/src/generator/exercises/templates/example.tt +2 -2
- data/tracks/crystal/src/generator/spec/exercise_generator_spec.cr +5 -3
- data/tracks/csharp/exercises/wordy/WordyTest.cs +2 -2
- data/tracks/elixir/config.json +83 -70
- data/tracks/fsharp/exercises/wordy/WordyTest.fs +1 -1
- data/tracks/go/config.json +28 -3
- data/tracks/go/exercises/all-your-base/all_your_base_test.go +185 -0
- data/tracks/go/exercises/all-your-base/example.go +60 -0
- data/tracks/go/exercises/isogram/example.go +15 -0
- data/tracks/go/exercises/isogram/isogram_test.go +50 -0
- data/tracks/go/exercises/ledger/ledger.go +2 -2
- data/tracks/go/exercises/pangram/example.go +32 -0
- data/tracks/go/exercises/pangram/pangram_test.go +43 -0
- data/tracks/go/exercises/protein-translation/example.go +59 -0
- data/tracks/go/exercises/protein-translation/protein_translation_test.go +69 -0
- data/tracks/go/exercises/tree-building/tree_building.go +1 -1
- data/tracks/go/exercises/twelve-days/example.go +57 -0
- data/tracks/go/exercises/twelve-days/twelve_days_test.go +79 -0
- data/tracks/haskell/.travis.yml +13 -8
- data/tracks/haskell/config.json +6 -0
- data/tracks/haskell/exercises/accumulate/stack.yaml +1 -1
- data/tracks/haskell/exercises/all-your-base/stack.yaml +1 -1
- data/tracks/haskell/exercises/allergies/stack.yaml +1 -1
- data/tracks/haskell/exercises/alphametics/stack.yaml +1 -1
- data/tracks/haskell/exercises/anagram/stack.yaml +1 -1
- data/tracks/haskell/exercises/atbash-cipher/stack.yaml +1 -1
- data/tracks/haskell/exercises/bank-account/stack.yaml +1 -1
- data/tracks/haskell/exercises/beer-song/stack.yaml +1 -1
- data/tracks/haskell/exercises/binary/stack.yaml +1 -1
- data/tracks/haskell/exercises/binary-search-tree/stack.yaml +1 -1
- data/tracks/haskell/exercises/bob/stack.yaml +1 -1
- data/tracks/haskell/exercises/bowling/HINTS.md +19 -0
- data/tracks/haskell/exercises/bowling/examples/success-standard/package.yaml +16 -0
- data/tracks/haskell/exercises/bowling/examples/success-standard/src/Bowling.hs +84 -0
- data/tracks/haskell/exercises/bowling/package.yaml +19 -0
- data/tracks/haskell/exercises/bowling/src/Bowling.hs +9 -0
- data/tracks/haskell/exercises/bowling/stack.yaml +1 -0
- data/tracks/haskell/exercises/bowling/test/Tests.hs +143 -0
- data/tracks/haskell/exercises/change/stack.yaml +1 -1
- data/tracks/haskell/exercises/clock/stack.yaml +1 -1
- data/tracks/haskell/exercises/connect/stack.yaml +1 -1
- data/tracks/haskell/exercises/crypto-square/stack.yaml +1 -1
- data/tracks/haskell/exercises/custom-set/stack.yaml +1 -1
- data/tracks/haskell/exercises/difference-of-squares/stack.yaml +1 -1
- data/tracks/haskell/exercises/dominoes/stack.yaml +1 -1
- data/tracks/haskell/exercises/etl/stack.yaml +1 -1
- data/tracks/haskell/exercises/food-chain/stack.yaml +1 -1
- data/tracks/haskell/exercises/forth/stack.yaml +1 -1
- data/tracks/haskell/exercises/gigasecond/stack.yaml +1 -1
- data/tracks/haskell/exercises/go-counting/stack.yaml +1 -1
- data/tracks/haskell/exercises/grade-school/stack.yaml +1 -1
- data/tracks/haskell/exercises/grains/stack.yaml +1 -1
- data/tracks/haskell/exercises/hamming/stack.yaml +1 -1
- data/tracks/haskell/exercises/hexadecimal/stack.yaml +1 -1
- data/tracks/haskell/exercises/house/stack.yaml +1 -1
- data/tracks/haskell/exercises/kindergarten-garden/stack.yaml +1 -1
- data/tracks/haskell/exercises/largest-series-product/stack.yaml +1 -1
- data/tracks/haskell/exercises/leap/stack.yaml +1 -1
- data/tracks/haskell/exercises/lens-person/stack.yaml +1 -1
- data/tracks/haskell/exercises/linked-list/stack.yaml +1 -1
- data/tracks/haskell/exercises/list-ops/stack.yaml +1 -1
- data/tracks/haskell/exercises/luhn/stack.yaml +1 -1
- data/tracks/haskell/exercises/matrix/stack.yaml +1 -1
- data/tracks/haskell/exercises/meetup/stack.yaml +1 -1
- data/tracks/haskell/exercises/minesweeper/stack.yaml +1 -1
- data/tracks/haskell/exercises/nth-prime/stack.yaml +1 -1
- data/tracks/haskell/exercises/nucleotide-count/stack.yaml +1 -1
- data/tracks/haskell/exercises/ocr-numbers/stack.yaml +1 -1
- data/tracks/haskell/exercises/octal/stack.yaml +1 -1
- data/tracks/haskell/exercises/palindrome-products/stack.yaml +1 -1
- data/tracks/haskell/exercises/parallel-letter-frequency/stack.yaml +1 -1
- data/tracks/haskell/exercises/pascals-triangle/stack.yaml +1 -1
- data/tracks/haskell/exercises/phone-number/stack.yaml +1 -1
- data/tracks/haskell/exercises/pig-latin/stack.yaml +1 -1
- data/tracks/haskell/exercises/pov/stack.yaml +1 -1
- data/tracks/haskell/exercises/prime-factors/stack.yaml +1 -1
- data/tracks/haskell/exercises/pythagorean-triplet/stack.yaml +1 -1
- data/tracks/haskell/exercises/queen-attack/stack.yaml +1 -1
- data/tracks/haskell/exercises/raindrops/stack.yaml +1 -1
- data/tracks/haskell/exercises/rna-transcription/stack.yaml +1 -1
- data/tracks/haskell/exercises/robot-name/stack.yaml +1 -1
- data/tracks/haskell/exercises/robot-simulator/stack.yaml +1 -1
- data/tracks/haskell/exercises/roman-numerals/stack.yaml +1 -1
- data/tracks/haskell/exercises/saddle-points/stack.yaml +1 -1
- data/tracks/haskell/exercises/say/stack.yaml +1 -1
- data/tracks/haskell/exercises/scrabble-score/stack.yaml +1 -1
- data/tracks/haskell/exercises/secret-handshake/stack.yaml +1 -1
- data/tracks/haskell/exercises/series/stack.yaml +1 -1
- data/tracks/haskell/exercises/sgf-parsing/stack.yaml +1 -1
- data/tracks/haskell/exercises/sieve/stack.yaml +1 -1
- data/tracks/haskell/exercises/simple-cipher/stack.yaml +1 -1
- data/tracks/haskell/exercises/simple-linked-list/stack.yaml +1 -1
- data/tracks/haskell/exercises/space-age/stack.yaml +1 -1
- data/tracks/haskell/exercises/strain/stack.yaml +1 -1
- data/tracks/haskell/exercises/sublist/stack.yaml +1 -1
- data/tracks/haskell/exercises/sum-of-multiples/stack.yaml +1 -1
- data/tracks/haskell/exercises/triangle/stack.yaml +1 -1
- data/tracks/haskell/exercises/trinary/stack.yaml +1 -1
- data/tracks/haskell/exercises/word-count/stack.yaml +1 -1
- data/tracks/haskell/exercises/wordy/stack.yaml +1 -1
- data/tracks/haskell/exercises/zebra-puzzle/stack.yaml +1 -1
- data/tracks/haskell/exercises/zipper/stack.yaml +1 -1
- data/tracks/java/config.json +13 -1
- data/tracks/java/exercises/etl/src/main/java/Etl.java +3 -3
- data/tracks/java/exercises/hello-world/GETTING_STARTED.md +1 -1
- data/tracks/java/exercises/hello-world/src/main/java/HelloWorld.java +3 -3
- data/tracks/java/exercises/minesweeper/build.gradle +17 -0
- data/tracks/java/exercises/minesweeper/src/example/java/MinesweeperBoard.java +111 -0
- data/tracks/java/exercises/minesweeper/src/main/java/MinesweeperBoard.java +5 -0
- data/tracks/java/exercises/minesweeper/src/test/java/MinesweeperBoardTest.java +295 -0
- data/tracks/java/exercises/nucleotide-count/src/test/java/NucleotideTest.java +67 -67
- data/tracks/java/exercises/series/build.gradle +18 -0
- data/tracks/java/exercises/series/src/example/java/Series.java +39 -0
- data/tracks/java/exercises/series/src/main/java/.keep +0 -0
- data/tracks/java/exercises/series/src/main/java/Series.java +3 -0
- data/tracks/java/exercises/series/src/test/java/.keep +0 -0
- data/tracks/java/exercises/series/src/test/java/SeriesTest.java +154 -0
- data/tracks/java/exercises/settings.gradle +2 -0
- data/tracks/javascript/exercises/custom-set/custom-set.spec.js +130 -84
- data/tracks/javascript/exercises/custom-set/example-gen.js +200 -0
- data/tracks/ocaml/Makefile +5 -1
- data/tracks/ocaml/config.json +2 -1
- data/tracks/ocaml/exercises/anagram/test.ml +35 -24
- data/tracks/ocaml/exercises/bob/example.ml +1 -1
- data/tracks/ocaml/exercises/bob/test.ml +53 -40
- data/tracks/ocaml/exercises/hamming/test.ml +41 -31
- data/tracks/ocaml/exercises/raindrops/test.ml +38 -39
- data/tracks/ocaml/tools/test-generator/.merlin +5 -0
- data/tracks/ocaml/tools/test-generator/Makefile +15 -0
- data/tracks/ocaml/tools/test-generator/_tags +0 -0
- data/tracks/ocaml/tools/test-generator/src/codegen.ml +17 -0
- data/tracks/ocaml/tools/test-generator/src/codegen.mli +7 -0
- data/tracks/ocaml/tools/test-generator/src/leap.json +39 -0
- data/tracks/ocaml/tools/test-generator/src/model.ml +31 -0
- data/tracks/ocaml/tools/test-generator/src/parser.ml +61 -0
- data/tracks/ocaml/tools/test-generator/src/parser.mli +9 -0
- data/tracks/ocaml/tools/test-generator/src/special_cases.ml +12 -0
- data/tracks/ocaml/tools/test-generator/src/special_cases.mli +7 -0
- data/tracks/ocaml/tools/test-generator/src/test_gen.ml +25 -0
- data/tracks/ocaml/tools/test-generator/src/test_generator.ml +62 -0
- data/tracks/ocaml/tools/test-generator/src/test_generator.mli +6 -0
- data/tracks/ocaml/tools/test-generator/src/utils.ml +32 -0
- data/tracks/ocaml/tools/test-generator/src/utils.mli +18 -0
- data/tracks/ocaml/tools/test-generator/templates/anagram/template.ml +17 -0
- data/tracks/ocaml/tools/test-generator/templates/bob/template.ml +15 -0
- data/tracks/ocaml/tools/test-generator/templates/hamming/template.ml +30 -0
- data/tracks/ocaml/tools/test-generator/templates/leap/template.ml +15 -0
- data/tracks/ocaml/tools/test-generator/templates/raindrops/template.ml +15 -0
- data/tracks/ocaml/tools/test-generator/templates/word-count/template.ml +19 -0
- data/tracks/ocaml/tools/test-generator/test/all_tests.ml +11 -0
- data/tracks/ocaml/tools/test-generator/test/codegen_test.ml +20 -0
- data/tracks/ocaml/tools/test-generator/test/model_test.ml +27 -0
- data/tracks/ocaml/tools/test-generator/test/parser_test.ml +73 -0
- data/tracks/ocaml/tools/test-generator/test/special_cases_test.ml +22 -0
- data/tracks/ocaml/tools/test-generator/test/test_generator_test.ml +11 -0
- data/tracks/ocaml/tools/test-generator/test/utils_test.ml +21 -0
- data/tracks/perl5/config.json +1 -1
- data/tracks/perl6/accumulate/accumulate.t +8 -2
- data/tracks/perl6/anagram/Example.pm +1 -1
- data/tracks/perl6/anagram/anagram.t +7 -8
- data/tracks/perl6/binary/Example.pm +1 -1
- data/tracks/perl6/binary/binary.t +7 -8
- data/tracks/perl6/bob/bob.t +1 -3
- data/tracks/perl6/config.json +1 -0
- data/tracks/perl6/grains/grains.t +7 -2
- data/tracks/perl6/leap/leap.t +3 -1
- data/tracks/perl6/raindrops/raindrops.t +8 -2
- data/tracks/perl6/rna-transcription/rna_transcription.t +8 -9
- data/tracks/perl6/robot-name/robot.t +8 -9
- data/tracks/perl6/scrabble-score/Example.pm +1 -1
- data/tracks/perl6/scrabble-score/scrabble_score.t +8 -2
- data/tracks/perl6/word-count/word_count.t +8 -2
- data/tracks/php/config.json +5 -0
- data/tracks/php/exercises/markdown/example.php +85 -0
- data/tracks/php/exercises/markdown/markdown.php +82 -0
- data/tracks/php/exercises/markdown/markdown_test.php +57 -0
- data/tracks/python/exercises/hamming/example.py +3 -0
- data/tracks/python/exercises/hamming/hamming_test.py +40 -14
- data/tracks/python/exercises/rna-transcription/example.py +6 -1
- data/tracks/python/exercises/rna-transcription/rna_transcription_test.py +9 -0
- data/tracks/ruby/config.json +6 -0
- data/tracks/ruby/exercises/dominoes/.version +1 -0
- data/tracks/ruby/exercises/dominoes/dominoes_test.rb +149 -0
- data/tracks/ruby/exercises/dominoes/example.rb +37 -0
- data/tracks/ruby/exercises/dominoes/example.tt +57 -0
- data/tracks/ruby/exercises/pangram/.version +1 -1
- data/tracks/ruby/exercises/pangram/example.rb +2 -2
- data/tracks/ruby/exercises/pangram/example.tt +5 -7
- data/tracks/ruby/exercises/pangram/pangram_test.rb +30 -25
- data/tracks/ruby/exercises/queen-attack/.version +1 -0
- data/tracks/ruby/exercises/queen-attack/example.rb +5 -30
- data/tracks/ruby/exercises/queen-attack/example.tt +22 -0
- data/tracks/ruby/exercises/queen-attack/queen_attack_test.rb +46 -95
- data/tracks/ruby/exercises/triangle/.version +1 -0
- data/tracks/ruby/exercises/triangle/example.rb +15 -22
- data/tracks/ruby/exercises/triangle/example.tt +20 -0
- data/tracks/ruby/exercises/triangle/triangle_test.rb +80 -40
- data/tracks/ruby/lib/dominoes_cases.rb +23 -0
- data/tracks/ruby/lib/pangram_cases.rb +19 -4
- data/tracks/ruby/lib/queen_attack_cases.rb +54 -0
- data/tracks/ruby/lib/triangle_cases.rb +51 -0
- data/tracks/scala/config.json +6 -0
- data/tracks/scala/exercises/dominoes/Example.scala +41 -0
- data/tracks/scala/exercises/dominoes/build.sbt +3 -0
- data/tracks/scala/exercises/dominoes/src/main/scala/Dominoes.scala +4 -0
- data/tracks/scala/exercises/dominoes/src/test/scala/DominoesSuite.scala +91 -0
- metadata +83 -2
@@ -0,0 +1,85 @@
|
|
1
|
+
<?php
|
2
|
+
|
3
|
+
function parseMarkdown($markdown)
|
4
|
+
{
|
5
|
+
$lines = explode("\n", $markdown);
|
6
|
+
|
7
|
+
$isInList = false;
|
8
|
+
|
9
|
+
foreach ($lines as &$line) {
|
10
|
+
if (preg_match('/^######(.*)/', $line, $matches)) {
|
11
|
+
$line = "<h6>" . trim($matches[1]) . "</h6>";
|
12
|
+
} elseif (preg_match('/^##(.*)/', $line, $matches)) {
|
13
|
+
$line = "<h2>" . trim($matches[1]) . "</h2>";
|
14
|
+
} elseif (preg_match('/^#(.*)/', $line, $matches)) {
|
15
|
+
$line = "<h1>" . trim($matches[1]) . "</h1>";
|
16
|
+
}
|
17
|
+
|
18
|
+
if (preg_match('/\*(.*)/', $line, $matches)) {
|
19
|
+
if (!$isInList) {
|
20
|
+
$isInList = true;
|
21
|
+
$isBold = false;
|
22
|
+
$isItalic = false;
|
23
|
+
if (preg_match('/(.*)__(.*)__(.*)/', $matches[1], $matches2)) {
|
24
|
+
$matches[1] = $matches2[1] . '<em>' . $matches2[2] . '</em>' . $matches2[3];
|
25
|
+
$isBold = true;
|
26
|
+
}
|
27
|
+
|
28
|
+
if (preg_match('/(.*)_(.*)_(.*)/', $matches[1], $matches3)) {
|
29
|
+
$matches[1] = $matches3[1] . '<i>' . $matches3[2] . '</i>' . $matches3[3];
|
30
|
+
$isItalic = true;
|
31
|
+
}
|
32
|
+
|
33
|
+
if ($isItalic || $isBold) {
|
34
|
+
$line = "<ul><li>" . trim($matches[1]) . "</li>";
|
35
|
+
} else {
|
36
|
+
$line = "<ul><li><p>" . trim($matches[1]) . "</p></li>";
|
37
|
+
}
|
38
|
+
|
39
|
+
} else {
|
40
|
+
$isBold = false;
|
41
|
+
$isItalic = false;
|
42
|
+
if (preg_match('/(.*)__(.*)__(.*)/', $matches[1], $matches2)) {
|
43
|
+
$matches[1] = $matches2[1] . '<em>' . $matches2[2] . '</em>' . $matches2[3];
|
44
|
+
$isBold = true;
|
45
|
+
}
|
46
|
+
|
47
|
+
if (preg_match('/(.*)_(.*)_(.*)/', $matches[1], $matches3)) {
|
48
|
+
$matches[1] = $matches3[1] . '<i>' . $matches3[2] . '</i>' . $matches3[3];
|
49
|
+
$isItalic = true;
|
50
|
+
}
|
51
|
+
|
52
|
+
if ($isItalic || $isBold) {
|
53
|
+
$line = "<li>" . trim($matches[1]) . "</li>";
|
54
|
+
} else {
|
55
|
+
$line = "<li><p>" . trim($matches[1]) . "</p></li>";
|
56
|
+
}
|
57
|
+
}
|
58
|
+
} else {
|
59
|
+
if ($isInList) {
|
60
|
+
$line = "</ul>" . $line;
|
61
|
+
$isInList = false;
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
if (!preg_match('/<h|<ul|<p|<li/', $line)) {
|
66
|
+
$line = "<p>$line</p>";
|
67
|
+
}
|
68
|
+
|
69
|
+
if (preg_match('/(.*)__(.*)__(.*)/', $line, $matches)) {
|
70
|
+
$line = $matches[1] . '<em>' . $matches[2] . '</em>' . $matches[3];
|
71
|
+
}
|
72
|
+
|
73
|
+
if (preg_match('/(.*)_(.*)_(.*)/', $line, $matches)) {
|
74
|
+
$line = $matches[1] . '<i>' . $matches[2] . '</i>' . $matches[3];
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
$html = join($lines);
|
79
|
+
|
80
|
+
if ($isInList) {
|
81
|
+
$html .= '</ul>';
|
82
|
+
}
|
83
|
+
|
84
|
+
return $html;
|
85
|
+
}
|
@@ -0,0 +1,82 @@
|
|
1
|
+
<?php
|
2
|
+
|
3
|
+
function parseMarkdown($markdown)
|
4
|
+
{
|
5
|
+
$lines = explode("\n", $markdown);
|
6
|
+
|
7
|
+
$isInList = false;
|
8
|
+
|
9
|
+
foreach ($lines as &$line) {
|
10
|
+
if (preg_match('/^######(.*)/', $line, $matches)) {
|
11
|
+
$line = "<h6>" . trim($matches[1]) . "</h6>";
|
12
|
+
} elseif (preg_match('/^##(.*)/', $line, $matches)) {
|
13
|
+
$line = "<h2>" . trim($matches[1]) . "</h2>";
|
14
|
+
} elseif (preg_match('/^#(.*)/', $line, $matches)) {
|
15
|
+
$line = "<h1>" . trim($matches[1]) . "</h1>";
|
16
|
+
}
|
17
|
+
|
18
|
+
if (preg_match('/\*(.*)/', $line, $matches)) {
|
19
|
+
if (!$isInList) {
|
20
|
+
$isInList = true;
|
21
|
+
$isBold = false;
|
22
|
+
$isItalic = false;
|
23
|
+
if (preg_match('/(.*)__(.*)__(.*)/', $matches[1], $matches2)) {
|
24
|
+
$matches[1] = $matches2[1] . '<em>' . $matches2[2] . '</em>' . $matches2[3];
|
25
|
+
$isBold = true;
|
26
|
+
}
|
27
|
+
|
28
|
+
if (preg_match('/(.*)_(.*)_(.*)/', $matches[1], $matches3)) {
|
29
|
+
$matches[1] = $matches3[1] . '<i>' . $matches3[2] . '</i>' . $matches3[3];
|
30
|
+
$isItalic = true;
|
31
|
+
}
|
32
|
+
|
33
|
+
if ($isItalic || $isBold) {
|
34
|
+
$line = "<ul><li>" . trim($matches[1]) . "</li>";
|
35
|
+
} else {
|
36
|
+
$line = "<ul><li><p>" . trim($matches[1]) . "</p></li>";
|
37
|
+
}
|
38
|
+
|
39
|
+
} else {
|
40
|
+
$isBold = false;
|
41
|
+
$isItalic = false;
|
42
|
+
if (preg_match('/(.*)__(.*)__(.*)/', $matches[1], $matches2)) {
|
43
|
+
$matches[1] = $matches2[1] . '<em>' . $matches2[2] . '</em>' . $matches2[3];
|
44
|
+
$isBold = true;
|
45
|
+
}
|
46
|
+
|
47
|
+
if (preg_match('/(.*)_(.*)_(.*)/', $matches[1], $matches3)) {
|
48
|
+
$matches[1] = $matches3[1] . '<i>' . $matches3[2] . '</i>' . $matches3[3];
|
49
|
+
$isItalic = true;
|
50
|
+
}
|
51
|
+
|
52
|
+
if ($isItalic || $isBold) {
|
53
|
+
$line = "<li>" . trim($matches[1]) . "</li>";
|
54
|
+
} else {
|
55
|
+
$line = "<li><p>" . trim($matches[1]) . "</p></li>";
|
56
|
+
}
|
57
|
+
}
|
58
|
+
} else {
|
59
|
+
if ($isInList) {
|
60
|
+
$line = "</ul>" . $line;
|
61
|
+
$isInList = false;
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
if (!preg_match('/<h|<ul|<p|<li/', $line)) {
|
66
|
+
$line = "<p>$line</p>";
|
67
|
+
}
|
68
|
+
|
69
|
+
if (preg_match('/(.*)__(.*)__(.*)/', $line, $matches)) {
|
70
|
+
$line = $matches[1] . '<em>' . $matches[2] . '</em>' . $matches[3];
|
71
|
+
}
|
72
|
+
|
73
|
+
if (preg_match('/(.*)_(.*)_(.*)/', $line, $matches)) {
|
74
|
+
$line = $matches[1] . '<i>' . $matches[2] . '</i>' . $matches[3];
|
75
|
+
}
|
76
|
+
}
|
77
|
+
$html = join($lines);
|
78
|
+
if ($isInList) {
|
79
|
+
$html .= '</ul>';
|
80
|
+
}
|
81
|
+
return $html;
|
82
|
+
}
|
@@ -0,0 +1,57 @@
|
|
1
|
+
<?php
|
2
|
+
|
3
|
+
require 'markdown.php';
|
4
|
+
|
5
|
+
class MarkdownTest extends \PHPUnit_Framework_TestCase
|
6
|
+
{
|
7
|
+
public function testParsingParagraph()
|
8
|
+
{
|
9
|
+
$this->assertEquals('<p>This will be a paragraph</p>', parseMarkdown('This will be a paragraph'));
|
10
|
+
}
|
11
|
+
|
12
|
+
public function testParsingItalics()
|
13
|
+
{
|
14
|
+
$this->assertEquals('<p><i>This will be italic</i></p>', parseMarkdown('_This will be italic_'));
|
15
|
+
}
|
16
|
+
|
17
|
+
public function testParsingBoldText()
|
18
|
+
{
|
19
|
+
$this->assertEquals('<p><em>This will be bold</em></p>', parseMarkdown('__This will be bold__'));
|
20
|
+
}
|
21
|
+
|
22
|
+
public function testMixedNormalItalicsAndBoldText()
|
23
|
+
{
|
24
|
+
$this->assertEquals('<p>This will <i>be</i> <em>mixed</em></p>', parseMarkdown('This will _be_ __mixed__'));
|
25
|
+
}
|
26
|
+
|
27
|
+
public function testWithH1Headerlevel()
|
28
|
+
{
|
29
|
+
$this->assertEquals('<h1>This will be an h1</h1>', parseMarkdown('# This will be an h1'));
|
30
|
+
}
|
31
|
+
|
32
|
+
public function testWithH2Headerlevel()
|
33
|
+
{
|
34
|
+
$this->assertEquals('<h2>This will be an h2</h2>', parseMarkdown('## This will be an h2'));
|
35
|
+
}
|
36
|
+
|
37
|
+
public function testWithH6Headerlevel()
|
38
|
+
{
|
39
|
+
$this->assertEquals('<h6>This will be an h6</h6>', parseMarkdown('###### This will be an h6'));
|
40
|
+
}
|
41
|
+
|
42
|
+
public function testUnorderedLists()
|
43
|
+
{
|
44
|
+
$this->assertEquals(
|
45
|
+
'<ul><li><p>Item 1</p></li><li><p>Item 2</p></li></ul>',
|
46
|
+
parseMarkdown("* Item 1\n* Item 2")
|
47
|
+
);
|
48
|
+
}
|
49
|
+
|
50
|
+
public function testWithALittleBitOfEverything()
|
51
|
+
{
|
52
|
+
$this->assertEquals(
|
53
|
+
'<h1>Header!</h1><ul><li><em>Bold Item</em></li><li><i>Italic Item</i></li></ul>',
|
54
|
+
parseMarkdown("# Header!\n* __Bold Item__\n* _Italic Item_")
|
55
|
+
);
|
56
|
+
}
|
57
|
+
}
|
@@ -5,26 +5,52 @@ import hamming
|
|
5
5
|
|
6
6
|
class HammingTest(unittest.TestCase):
|
7
7
|
|
8
|
-
def
|
9
|
-
self.assertEqual(0, hamming.distance(
|
8
|
+
def test_identical_strands(self):
|
9
|
+
self.assertEqual(0, hamming.distance("A", "A"))
|
10
10
|
|
11
|
-
def
|
12
|
-
self.assertEqual(
|
11
|
+
def test_long_identical_strands(self):
|
12
|
+
self.assertEqual(0, hamming.distance("GGACTGA", "GGACTGA"))
|
13
13
|
|
14
|
-
def
|
15
|
-
self.assertEqual(
|
14
|
+
def test_complete_distance_in_single_nucleotide_strands(self):
|
15
|
+
self.assertEqual(1, hamming.distance("A", "G"))
|
16
16
|
|
17
|
-
def
|
18
|
-
self.assertEqual(
|
17
|
+
def test_complete_distance_in_small_strands(self):
|
18
|
+
self.assertEqual(2, hamming.distance("AG", "CT"))
|
19
19
|
|
20
|
-
def
|
21
|
-
self.assertEqual(1, hamming.distance(
|
20
|
+
def test_small_distance_in_small_strands(self):
|
21
|
+
self.assertEqual(1, hamming.distance("AT", "CT"))
|
22
22
|
|
23
|
-
def
|
24
|
-
self.assertEqual(
|
23
|
+
def test_small_distance(self):
|
24
|
+
self.assertEqual(1, hamming.distance("GGACG", "GGTCG"))
|
25
25
|
|
26
|
-
def
|
27
|
-
self.assertEqual(
|
26
|
+
def test_small_distance_in_long_strands(self):
|
27
|
+
self.assertEqual(2, hamming.distance("ACCAGGG", "ACTATGG"))
|
28
|
+
|
29
|
+
def test_non_unique_character_in_first_strand(self):
|
30
|
+
self.assertEqual(1, hamming.distance("AGA", "AGG"))
|
31
|
+
|
32
|
+
def test_non_unique_character_in_second_strand(self):
|
33
|
+
self.assertEqual(1, hamming.distance("AGG", "AGA"))
|
34
|
+
|
35
|
+
def test_same_nucleotides_in_different_positions(self):
|
36
|
+
self.assertEqual(2, hamming.distance("TAG", "GAT"))
|
37
|
+
|
38
|
+
def test_large_distance(self):
|
39
|
+
self.assertEqual(4, hamming.distance("GATACA", "GCATAA"))
|
40
|
+
|
41
|
+
def test_large_distance_in_off_by_one_strand(self):
|
42
|
+
self.assertEqual(9, hamming.distance("GGACGGATTCTG", "AGGACGGATTCT"))
|
43
|
+
|
44
|
+
def test_empty_strands(self):
|
45
|
+
self.assertEqual(0, hamming.distance("", ""))
|
46
|
+
|
47
|
+
def test_disallow_first_strand_longer(self):
|
48
|
+
with self.assertRaises(ValueError):
|
49
|
+
hamming.distance("AATG", "AAA")
|
50
|
+
|
51
|
+
def test_disallow_second_strand_longer(self):
|
52
|
+
with self.assertRaises(ValueError):
|
53
|
+
hamming.distance("ATA", "AGTG")
|
28
54
|
|
29
55
|
|
30
56
|
if __name__ == '__main__':
|
@@ -6,8 +6,13 @@ else:
|
|
6
6
|
maketrans = str.maketrans
|
7
7
|
|
8
8
|
|
9
|
-
|
9
|
+
DNA_CHARS = 'AGCT'
|
10
|
+
DNA_TO_RNA = maketrans(DNA_CHARS, 'UCGA')
|
10
11
|
|
11
12
|
|
12
13
|
def to_rna(dna_strand):
|
14
|
+
valid_chars = set(DNA_CHARS)
|
15
|
+
if any(char not in valid_chars for char in dna_strand):
|
16
|
+
return ''
|
17
|
+
|
13
18
|
return dna_strand.translate(DNA_TO_RNA)
|
@@ -20,6 +20,15 @@ class DNATests(unittest.TestCase):
|
|
20
20
|
def test_transcribes_all_occurences(self):
|
21
21
|
self.assertMultiLineEqual('UGCACCAGAAUU', to_rna('ACGTGGTCTTAA'))
|
22
22
|
|
23
|
+
def test_correctly_handles_single_invalid_input(self):
|
24
|
+
self.assertEqual('', to_rna('U'))
|
25
|
+
|
26
|
+
def test_correctly_handles_completely_invalid_input(self):
|
27
|
+
self.assertMultiLineEqual('', to_rna('XXX'))
|
28
|
+
|
29
|
+
def test_correctly_handles_partially_invalid_input(self):
|
30
|
+
self.assertMultiLineEqual('', to_rna('ACGTXXXCTTAA'))
|
31
|
+
|
23
32
|
|
24
33
|
if __name__ == '__main__':
|
25
34
|
unittest.main()
|
data/tracks/ruby/config.json
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
1
|
@@ -0,0 +1,149 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
gem 'minitest', '>= 5.0.0'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require_relative 'dominoes'
|
5
|
+
|
6
|
+
# Test data version: 82eb00d
|
7
|
+
class DominoesTest < Minitest::Test
|
8
|
+
def test_empty_input_empty_output
|
9
|
+
# skip
|
10
|
+
input_dominoes = []
|
11
|
+
output_chain = Dominoes.chain(input_dominoes)
|
12
|
+
assert_correct_chain(input_dominoes, output_chain)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_singleton_input_singleton_output
|
16
|
+
skip
|
17
|
+
input_dominoes = [[1, 1]]
|
18
|
+
output_chain = Dominoes.chain(input_dominoes)
|
19
|
+
assert_correct_chain(input_dominoes, output_chain)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_singleton_that_can_not_be_chained
|
23
|
+
skip
|
24
|
+
input_dominoes = [[1, 2]]
|
25
|
+
output_chain = Dominoes.chain(input_dominoes)
|
26
|
+
refute_correct_chain(input_dominoes, output_chain)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_three_elements
|
30
|
+
skip
|
31
|
+
input_dominoes = [[1, 2], [3, 1], [2, 3]]
|
32
|
+
output_chain = Dominoes.chain(input_dominoes)
|
33
|
+
assert_correct_chain(input_dominoes, output_chain)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_can_reverse_dominoes
|
37
|
+
skip
|
38
|
+
input_dominoes = [[1, 2], [1, 3], [2, 3]]
|
39
|
+
output_chain = Dominoes.chain(input_dominoes)
|
40
|
+
assert_correct_chain(input_dominoes, output_chain)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_can_not_be_chained
|
44
|
+
skip
|
45
|
+
input_dominoes = [[1, 2], [4, 1], [2, 3]]
|
46
|
+
output_chain = Dominoes.chain(input_dominoes)
|
47
|
+
refute_correct_chain(input_dominoes, output_chain)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_disconnected_simple
|
51
|
+
skip
|
52
|
+
input_dominoes = [[1, 1], [2, 2]]
|
53
|
+
output_chain = Dominoes.chain(input_dominoes)
|
54
|
+
refute_correct_chain(input_dominoes, output_chain)
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_disconnected_double_loop
|
58
|
+
skip
|
59
|
+
input_dominoes = [[1, 2], [2, 1], [3, 4], [4, 3]]
|
60
|
+
output_chain = Dominoes.chain(input_dominoes)
|
61
|
+
refute_correct_chain(input_dominoes, output_chain)
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_disconnected_single_isolated
|
65
|
+
skip
|
66
|
+
input_dominoes = [[1, 2], [2, 3], [3, 1], [4, 4]]
|
67
|
+
output_chain = Dominoes.chain(input_dominoes)
|
68
|
+
refute_correct_chain(input_dominoes, output_chain)
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_need_backtrack
|
72
|
+
skip
|
73
|
+
input_dominoes = [[1, 2], [2, 3], [3, 1], [2, 4], [2, 4]]
|
74
|
+
output_chain = Dominoes.chain(input_dominoes)
|
75
|
+
assert_correct_chain(input_dominoes, output_chain)
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_separate_loops
|
79
|
+
skip
|
80
|
+
input_dominoes = [[1, 2], [2, 3], [3, 1], [1, 1], [2, 2], [3, 3]]
|
81
|
+
output_chain = Dominoes.chain(input_dominoes)
|
82
|
+
assert_correct_chain(input_dominoes, output_chain)
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_ten_elements
|
86
|
+
skip
|
87
|
+
input_dominoes = [[1, 2], [5, 3], [3, 1], [1, 2], [2, 4], [1, 6], [2, 3], [3, 4], [5, 6]]
|
88
|
+
output_chain = Dominoes.chain(input_dominoes)
|
89
|
+
assert_correct_chain(input_dominoes, output_chain)
|
90
|
+
end
|
91
|
+
|
92
|
+
# Problems in exercism evolve over time, as we find better ways to ask
|
93
|
+
# questions.
|
94
|
+
# The version number refers to the version of the problem you solved,
|
95
|
+
# not your solution.
|
96
|
+
#
|
97
|
+
# Define a constant named VERSION inside of the top level BookKeeping
|
98
|
+
# module, which may be placed near the end of your file.
|
99
|
+
#
|
100
|
+
# In your file, it will look like this:
|
101
|
+
#
|
102
|
+
# module BookKeeping
|
103
|
+
# VERSION = 1 # Where the version number matches the one in the test.
|
104
|
+
# end
|
105
|
+
#
|
106
|
+
# If you are curious, read more about constants on RubyDoc:
|
107
|
+
# http://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/constants.html
|
108
|
+
def test_bookkeeping
|
109
|
+
skip
|
110
|
+
assert_equal 1, BookKeeping::VERSION
|
111
|
+
end
|
112
|
+
|
113
|
+
# It's infeasible to use example-based tests for this exercise,
|
114
|
+
# because the list of acceptable answers for a given input can be quite large.
|
115
|
+
# Instead, we verify certain properties of a correct chain.
|
116
|
+
|
117
|
+
def assert_correct_chain(input_dominoes, output_chain)
|
118
|
+
refute_nil output_chain, "There should be a chain for #{input_dominoes}"
|
119
|
+
assert_same_dominoes(input_dominoes, output_chain)
|
120
|
+
return if output_chain.empty?
|
121
|
+
assert_consecutive_dominoes_match(output_chain)
|
122
|
+
assert_dominoes_at_end_match(output_chain)
|
123
|
+
end
|
124
|
+
|
125
|
+
def assert_same_dominoes(input_dominoes, output_chain)
|
126
|
+
input_normal = input_dominoes.map(&:sort).sort
|
127
|
+
output_normal = output_chain.map(&:sort).sort
|
128
|
+
assert_equal input_normal, output_normal,
|
129
|
+
'Dominoes used in the output must be the same as the ones given in the input'
|
130
|
+
end
|
131
|
+
|
132
|
+
def assert_consecutive_dominoes_match(chain)
|
133
|
+
chain.each_cons(2).with_index { |(d1, d2), i|
|
134
|
+
assert_equal d1.last, d2.first,
|
135
|
+
"In chain #{chain}, right end of domino #{i} (#{d1}) and left end of domino #{i + 1} (#{d2}) must match"
|
136
|
+
}
|
137
|
+
end
|
138
|
+
|
139
|
+
def assert_dominoes_at_end_match(chain)
|
140
|
+
first_domino = chain.first
|
141
|
+
last_domino = chain.last
|
142
|
+
assert_equal first_domino.first, last_domino.last,
|
143
|
+
"In chain #{chain}, left end of first domino (#{first_domino}) and right end of last domino (#{last_domino}) must match"
|
144
|
+
end
|
145
|
+
|
146
|
+
def refute_correct_chain(input_dominoes, output_chain)
|
147
|
+
assert_nil output_chain, "There should be no chain for #{input_dominoes}"
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Dominoes
|
2
|
+
def self.chain(dominoes)
|
3
|
+
return dominoes if dominoes.empty?
|
4
|
+
|
5
|
+
first = dominoes.first
|
6
|
+
|
7
|
+
subchain = try_subchain(dominoes.drop(1), *first)
|
8
|
+
subchain && [first] + subchain
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.try_subchain(dominoes, chain_left, chain_right)
|
12
|
+
return chain_left == chain_right ? [] : nil if dominoes.empty?
|
13
|
+
|
14
|
+
dominoes.each_with_index { |domino, i|
|
15
|
+
other_dominoes = dominoes.take(i) + dominoes.drop(i + 1)
|
16
|
+
# Try adding the domino either flipped or unflipped.
|
17
|
+
[domino, domino.reverse].each { |candidate|
|
18
|
+
domino_left, domino_right = candidate
|
19
|
+
if domino_left == chain_right
|
20
|
+
if (subchain = try_subchain(other_dominoes, chain_left, domino_right))
|
21
|
+
return [candidate] + subchain
|
22
|
+
end
|
23
|
+
end
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
# Found no suitable chain.
|
28
|
+
# Note that for "no chain" we have to use nil instead of [].
|
29
|
+
# This is because [] is the valid answer for `Dominoes.chain([])`.
|
30
|
+
# If we used [] for "no chain", then the meaning of [] is ambiguous.
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
module BookKeeping
|
36
|
+
VERSION = 1
|
37
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
gem 'minitest', '>= 5.0.0'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require_relative 'dominoes'
|
5
|
+
|
6
|
+
# Test data version: <%= sha1 %>
|
7
|
+
class DominoesTest < Minitest::Test
|
8
|
+
<% test_cases.each do |test_case| %>
|
9
|
+
def <%= test_case.test_name %>
|
10
|
+
<%= test_case.skipped %>
|
11
|
+
<%= test_case.workload %>
|
12
|
+
end
|
13
|
+
|
14
|
+
<% end %>
|
15
|
+
<%= IO.read(XRUBY_LIB + '/bookkeeping.md') %>
|
16
|
+
def test_bookkeeping
|
17
|
+
skip
|
18
|
+
assert_equal <%= version.next %>, BookKeeping::VERSION
|
19
|
+
end
|
20
|
+
|
21
|
+
# It's infeasible to use example-based tests for this exercise,
|
22
|
+
# because the list of acceptable answers for a given input can be quite large.
|
23
|
+
# Instead, we verify certain properties of a correct chain.
|
24
|
+
|
25
|
+
def assert_correct_chain(input_dominoes, output_chain)
|
26
|
+
refute_nil output_chain, "There should be a chain for #{input_dominoes}"
|
27
|
+
assert_same_dominoes(input_dominoes, output_chain)
|
28
|
+
return if output_chain.empty?
|
29
|
+
assert_consecutive_dominoes_match(output_chain)
|
30
|
+
assert_dominoes_at_end_match(output_chain)
|
31
|
+
end
|
32
|
+
|
33
|
+
def assert_same_dominoes(input_dominoes, output_chain)
|
34
|
+
input_normal = input_dominoes.map(&:sort).sort
|
35
|
+
output_normal = output_chain.map(&:sort).sort
|
36
|
+
assert_equal input_normal, output_normal,
|
37
|
+
'Dominoes used in the output must be the same as the ones given in the input'
|
38
|
+
end
|
39
|
+
|
40
|
+
def assert_consecutive_dominoes_match(chain)
|
41
|
+
chain.each_cons(2).with_index { |(d1, d2), i|
|
42
|
+
assert_equal d1.last, d2.first,
|
43
|
+
"In chain #{chain}, right end of domino #{i} (#{d1}) and left end of domino #{i + 1} (#{d2}) must match"
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
def assert_dominoes_at_end_match(chain)
|
48
|
+
first_domino = chain.first
|
49
|
+
last_domino = chain.last
|
50
|
+
assert_equal first_domino.first, last_domino.last,
|
51
|
+
"In chain #{chain}, left end of first domino (#{first_domino}) and right end of last domino (#{last_domino}) must match"
|
52
|
+
end
|
53
|
+
|
54
|
+
def refute_correct_chain(input_dominoes, output_chain)
|
55
|
+
assert_nil output_chain, "There should be no chain for #{input_dominoes}"
|
56
|
+
end
|
57
|
+
end
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
3
|
@@ -4,16 +4,14 @@ gem 'minitest', '>= 5.0.0'
|
|
4
4
|
require 'minitest/autorun'
|
5
5
|
require_relative 'pangram'
|
6
6
|
|
7
|
-
# Test data version:
|
8
|
-
# <%= sha1 %>
|
7
|
+
# Test data version: # <%= sha1 %>
|
9
8
|
class PangramTest < Minitest::Test<% test_cases.each do |test_case| %>
|
10
|
-
def <%= test_case.name
|
11
|
-
|
12
|
-
|
13
|
-
assert<% else %>
|
14
|
-
refute<% end %> <%= test_case.do %>
|
9
|
+
def <%= test_case.name %>
|
10
|
+
<%= test_case.skipped? %>
|
11
|
+
<%= test_case.workload %>
|
15
12
|
end
|
16
13
|
<% end %>
|
14
|
+
|
17
15
|
<%= IO.read(XRUBY_LIB + '/bookkeeping.md') %>
|
18
16
|
def test_bookkeeping
|
19
17
|
skip
|