trackler 2.0.8.11 → 2.0.8.12
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.
- checksums.yaml +4 -4
- data/common/README.md +70 -15
- data/common/canonical-schema.json +137 -0
- data/lib/trackler/version.rb +1 -1
- data/tracks/elixir/config.json +7 -0
- data/tracks/elixir/exercises/simple-linked-list/example.exs +86 -0
- data/tracks/elixir/exercises/simple-linked-list/linked_list.exs +83 -0
- data/tracks/elixir/exercises/simple-linked-list/linked_list_test.exs +154 -0
- data/tracks/factor/README.md +0 -6
- data/tracks/factor/config.json +13 -3
- data/tracks/factor/docs/INSTALLATION.md +26 -29
- data/tracks/factor/exercises/hello-world/hello-world-example.factor +2 -2
- data/tracks/factor/exercises/leap/leap-example.factor +9 -0
- data/tracks/factor/exercises/leap/leap-tests.factor +32 -0
- data/tracks/go/exercises/phone-number/phone_number_test.go +5 -2
- data/tracks/go/exercises/pig-latin/example.go +2 -0
- data/tracks/go/exercises/pig-latin/pig_latin_test.go +8 -0
- data/tracks/java/config.json +5 -0
- data/tracks/java/exercises/anagram/src/test/java/AnagramTest.java +14 -0
- data/tracks/java/exercises/ocr-numbers/build.gradle +17 -0
- data/tracks/java/exercises/ocr-numbers/src/example/java/Digit.java +63 -0
- data/tracks/java/exercises/ocr-numbers/src/example/java/OpticalCharacterReader.java +67 -0
- data/tracks/java/exercises/ocr-numbers/src/main/java/OpticalCharacterReader.java +5 -0
- data/tracks/java/exercises/ocr-numbers/src/test/java/OpticalCharacterReaderTest.java +248 -0
- data/tracks/java/exercises/perfect-numbers/src/example/java/NaturalNumber.java +1 -1
- data/tracks/java/exercises/perfect-numbers/src/test/java/NaturalNumberTest.java +52 -5
- data/tracks/java/exercises/settings.gradle +1 -0
- data/tracks/java/img/icon.png +0 -0
- data/tracks/javascript/exercises/phone-number/phone-number.spec.js +22 -2
- data/tracks/julia/exercises/bob/example.jl +1 -1
- data/tracks/julia/exercises/custom-set/HINTS.md +2 -0
- data/tracks/julia/exercises/custom-set/runtests.jl +2 -2
- data/tracks/julia/img/{logo.png → icon.png} +0 -0
- data/tracks/julia/img/{logo.svg → icon.svg} +0 -0
- data/tracks/prolog/README.md +6 -2
- data/tracks/prolog/config.json +1 -1
- data/tracks/prolog/img/icon.png +0 -0
- data/tracks/scala/exercises/simple-linked-list/build.sbt +3 -0
- data/tracks/vimscript/README.md +7 -0
- data/tracks/vimscript/img/icon.png +0 -0
- metadata +17 -5
- data/tracks/vimscript/img/.keep +0 -0
data/tracks/factor/README.md
CHANGED
@@ -70,12 +70,6 @@ Here's what you need to do to start working with the Factor code in the `exercis
|
|
70
70
|
|
71
71
|
If you think you've found a factual or technical error, or you just have a question or suggestion about some part of the Markdown or Factor documentation, we'd :heart: you to open an issue or pull request.
|
72
72
|
|
73
|
-
## License
|
74
|
-
|
75
|
-
The MIT License (MIT)
|
76
|
-
|
77
|
-
Copyright (c) 2016 Katrina Owen, _@kytrinyx.com
|
78
|
-
|
79
73
|
### [Factor icon](https://github.com/exercism/xfactor/tree/master/img/icon.png)
|
80
74
|
|
81
75
|
The Factor "Tyrannosaurus Rex" logo is owned by John Benediktsson. We have adapted it, changing the colour scheme, with his permission.
|
data/tracks/factor/config.json
CHANGED
@@ -6,7 +6,8 @@
|
|
6
6
|
"test_pattern": "TODO",
|
7
7
|
|
8
8
|
"problems": [
|
9
|
-
"hello-world"
|
9
|
+
"hello-world",
|
10
|
+
"leap"
|
10
11
|
],
|
11
12
|
|
12
13
|
"exercises": [
|
@@ -19,6 +20,16 @@
|
|
19
20
|
"text formatting",
|
20
21
|
"quotations"
|
21
22
|
]
|
23
|
+
},
|
24
|
+
{
|
25
|
+
"slug": "leap",
|
26
|
+
"difficulty": 2,
|
27
|
+
"topics": [
|
28
|
+
"quotations",
|
29
|
+
"word definition",
|
30
|
+
"conditionals",
|
31
|
+
"logical operators"
|
32
|
+
]
|
22
33
|
}
|
23
34
|
],
|
24
35
|
|
@@ -27,8 +38,7 @@
|
|
27
38
|
|
28
39
|
"ignored": [
|
29
40
|
"bin",
|
30
|
-
"docs"
|
31
|
-
"exercism-testing"
|
41
|
+
"docs"
|
32
42
|
],
|
33
43
|
|
34
44
|
"foregone": [
|
@@ -1,27 +1,19 @@
|
|
1
1
|
# Installing Factor, and making Factor and Exercism play nice
|
2
2
|
|
3
|
-
[**Even if you already have Factor installed, you still need to read the last section of this document for important information about testing Factor code in the Exercism environment.**](#play-nice)
|
3
|
+
[**Even if you already have Factor 0.98 installed, you still need to read the last section of this document for important information about testing Factor code in the Exercism environment.**](#play-nice)
|
4
4
|
|
5
5
|
---
|
6
6
|
|
7
7
|
## Installing Factor
|
8
8
|
|
9
|
-
To install Factor, you
|
9
|
+
To install Factor, you should use a [nightly](#nightly) or [bleeding-edge](#autobuild-from-source) build.
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
---
|
14
|
-
|
15
|
-
### Stable
|
16
|
-
|
17
|
-
Download a binary for your platform from <http://factorcode.org>, and run the installer.
|
18
|
-
|
19
|
-
These binaries and sources are typically a few months behind `git`. If you want the latest bugfixes and features (dark mode UI, perhaps?), or if your platform isn't listed on that page (i.e. not Windows, Linux or Mac), then see the ["build from source"](#autobuild-from-source) section below, to obtain the up-to-the-minute version.
|
11
|
+
***The last stable release of Factor was [0.97 released 2 Nov 2014](https://re-factor.blogspot.com/2014/11/factor-097-now-available.html) -- this is quite out of date and not recommended.***
|
20
12
|
|
21
13
|
---
|
22
14
|
### Nightly
|
23
15
|
|
24
|
-
|
16
|
+
<http://factorcode.org> also provides nightly binaries, built from git. Only builds that pass are shown.
|
25
17
|
|
26
18
|
---
|
27
19
|
|
@@ -29,12 +21,15 @@ The website also provides nightly binaries, built from git. Only builds that pas
|
|
29
21
|
|
30
22
|
If neither of the above options are good enough for you, and you need all the latest tech, then you will need a modern C++ compiler like GCC >=4.8 or Clang >=3.5, `make`, `curl`, and:
|
31
23
|
|
32
|
-
1. Download the `build` shell script: [**here** for
|
33
|
-
|
24
|
+
1. Download the `build` shell script: [**here** for Unix-likes / POSIX shells](https://raw.githubusercontent.com/factor/factor/master/build.sh) or [**here** for Windows](https://raw.githubusercontent.com/factor/factor/master/build.cmd). Put it in the directory where Factor should be installed.
|
25
|
+
|
26
|
+
2. Run it like `./build.sh install`, or `.\build.cmd install` on Windows. <sub>This will clone Factor's `git` repository, build it, and download a Factor VM image from <http://factorcode.org>. This process will take between 2 and 20 minutes, depending on the speed of your internet connection and processor.</sub>
|
27
|
+
|
34
28
|
3. You can now run the generated `factor` or `factor.exe` binary. Try `factor --help` for help. You can also access documentation from the command line, or by pressing <kbd>F1</kbd> in the GUI Listener, which will open the docs browser.
|
35
|
-
4. In the future, just `cd` into Factor's cloned repository and type `./build.sh update` or `.\build.cmd update`, respectively, to pull from git and rebuild in-place, and download a new VM image if the checksums differ.
|
36
29
|
|
37
|
-
|
30
|
+
4. In the future, just `cd` into Factor's installation and type `./build.sh update`, or `.\build.cmd update` on Windows, to pull from git and rebuild in-place, and download a new VM image if one exists.
|
31
|
+
|
32
|
+
The file structure may now look like this:
|
38
33
|
|
39
34
|
```
|
40
35
|
.
|
@@ -42,24 +37,17 @@ Your tree, from the working directory of the original build script, might look s
|
|
42
37
|
└── factor
|
43
38
|
├── basis
|
44
39
|
├── boot.unix-x86.64.image
|
45
|
-
├── boot.unix-x86.64.image.bak
|
46
40
|
├── build.cmd
|
47
41
|
├── build.sh
|
48
|
-
├── checksums.txt
|
49
42
|
├── core
|
50
43
|
├── extra
|
51
44
|
├── factor
|
52
45
|
├── Factor.app
|
53
|
-
├── factor.bak
|
54
46
|
├── factor.image
|
55
|
-
├── factor.image.bak
|
56
|
-
├── factor.image.fresh
|
57
47
|
├── GNUmakefile
|
58
|
-
├── key-log.txt
|
59
48
|
├── libfactor.a
|
60
49
|
├── libfactor-ffi-test.so
|
61
50
|
├── LICENSE.txt
|
62
|
-
├── logs
|
63
51
|
├── misc
|
64
52
|
├── Nmakefile
|
65
53
|
├── README.md
|
@@ -68,13 +56,13 @@ Your tree, from the working directory of the original build script, might look s
|
|
68
56
|
└── work
|
69
57
|
```
|
70
58
|
|
71
|
-
You no longer need the top level
|
59
|
+
You no longer need the top level `build.sh`.
|
72
60
|
|
73
61
|
---
|
74
62
|
|
75
|
-
###
|
63
|
+
### Manually build from source
|
76
64
|
|
77
|
-
|
65
|
+
Clone the [repository](https://github.com/factor/factor) and use `make` in that folder.
|
78
66
|
|
79
67
|
If `make` fails with an error about a non-present target, try `make factor` or, if you can read a Makefile, find the make target for your platform in `GNUmakefile`.
|
80
68
|
|
@@ -82,12 +70,21 @@ If *that* fails, open an issue on [factor/factor](https://github.com/factor/fact
|
|
82
70
|
|
83
71
|
---
|
84
72
|
|
73
|
+
#### Stable (not recommended)
|
74
|
+
|
75
|
+
**Note that [the automated test framework](languages/factor/tests) for Factor exercises on Exercism requires at least a [nightly build](#nightly)**.
|
76
|
+
|
77
|
+
If you *don't* want automated testing or thousands of new features and bugfixes, download a Stable release binary for your platform from <http://factorcode.org>, and run the installer.
|
78
|
+
|
79
|
+
---
|
80
|
+
|
85
81
|
## Making Exercism and Factor work together <a name="play-nice"> </a>
|
86
82
|
|
87
|
-
Name clashes between Exercism and the Factor standard library, Exercism and Factor's mutual strictness about filenames, and Factor's reluctance to find vocabularies outside its source tree are all **factor**s making it kind of tricky for Exercism users to test their Factor code.
|
88
83
|
|
89
|
-
|
84
|
+
Due to limitations like name clashes and filename disagreements, it's rather difficult to use `tools.test` on Exercism exercises out of the box.
|
85
|
+
|
86
|
+
Instead, there is a [wrapper vocabulary](https://github.com/catb0t/exercism.factor) for the Factor workflow in an Exercism context. Users and Exercism maintainers alike can write tests in a familiar way, with much less overhead.
|
90
87
|
|
91
|
-
To test your Factor
|
88
|
+
To test your Factor solutions in your `exercism/factor` folder, follow the directions in [the README](https://github.com/catb0t/exercism.factor#getting-started).
|
92
89
|
|
93
90
|
For information on using `exercism.testing`, refer to the [testing documentation](exercism.io/languages/factor#test), or to `exercism.testing`'s documentation by running `"exercism.testing" help` in Factor.
|
@@ -0,0 +1,32 @@
|
|
1
|
+
USING: io leap tools.test ;
|
2
|
+
IN: leap.tests
|
3
|
+
|
4
|
+
"Leap year:" print
|
5
|
+
|
6
|
+
"not very common" print
|
7
|
+
{ f } [ 2015 my-leap-year? ] unit-test
|
8
|
+
|
9
|
+
"introduced every 4 years to adjust about a day" print
|
10
|
+
{ t } [ 2016 my-leap-year? ] unit-test
|
11
|
+
|
12
|
+
"skipped every 100 years to remove an extra day" print
|
13
|
+
{ f } [ 1900 my-leap-year? ] unit-test
|
14
|
+
|
15
|
+
"reintroduced every 400 years to adjust yet another day" print
|
16
|
+
{ t } [ 2000 my-leap-year? ] unit-test
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
"Additional corner cases of leap years:" print
|
21
|
+
|
22
|
+
"not a leap year" print
|
23
|
+
{ f } [ 1978 my-leap-year? ] unit-test
|
24
|
+
|
25
|
+
"a common leap year" print
|
26
|
+
{ t } [ 1992 my-leap-year? ] unit-test
|
27
|
+
|
28
|
+
"is skipped every 100 years" print
|
29
|
+
{ f } [ 2100 my-leap-year? ] unit-test
|
30
|
+
|
31
|
+
"reintroduced every 400 years" print
|
32
|
+
{ f } [ 2100 my-leap-year? ] unit-test
|
@@ -21,10 +21,13 @@ var numberTests = []testCase{
|
|
21
21
|
{"123456789", "", true},
|
22
22
|
}
|
23
23
|
|
24
|
-
func
|
24
|
+
func TestTestVersion(t *testing.T) {
|
25
25
|
if testVersion != targetTestVersion {
|
26
|
-
t.
|
26
|
+
t.Fatalf("Found testVersion = %v, want %v", testVersion, targetTestVersion)
|
27
27
|
}
|
28
|
+
}
|
29
|
+
|
30
|
+
func TestNumber(t *testing.T) {
|
28
31
|
for _, test := range numberTests {
|
29
32
|
actual, actualErr := Number(test.input)
|
30
33
|
if !test.expectErr {
|
@@ -2,6 +2,8 @@ package igpay
|
|
2
2
|
|
3
3
|
import "testing"
|
4
4
|
|
5
|
+
const targetTestVersion = 1
|
6
|
+
|
5
7
|
var tests = []struct{ pl, in string }{
|
6
8
|
{"appleay", "apple"},
|
7
9
|
{"earay", "ear"},
|
@@ -20,6 +22,12 @@ var tests = []struct{ pl, in string }{
|
|
20
22
|
{"xrayay", "xray"},
|
21
23
|
}
|
22
24
|
|
25
|
+
func TestTestVersion(t *testing.T) {
|
26
|
+
if testVersion != targetTestVersion {
|
27
|
+
t.Fatalf("Found testVersion = %v, want %v", testVersion, targetTestVersion)
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
23
31
|
func TestPigLatin(t *testing.T) {
|
24
32
|
for _, test := range tests {
|
25
33
|
if pl := PigLatin(test.in); pl != test.pl {
|
data/tracks/java/config.json
CHANGED
@@ -116,4 +116,18 @@ public class AnagramTest {
|
|
116
116
|
List<String> anagrams = detector.match(Arrays.asList("cashregister", "Carthorse", "radishes"));
|
117
117
|
assertThat(anagrams, hasItem("Carthorse"));
|
118
118
|
}
|
119
|
+
|
120
|
+
@Ignore
|
121
|
+
@Test
|
122
|
+
public void testWordIsNotItsOwnAnagram() {
|
123
|
+
Anagram detector = new Anagram("banana");
|
124
|
+
assertTrue(detector.match(Arrays.asList("Banana")).isEmpty());
|
125
|
+
}
|
126
|
+
|
127
|
+
@Ignore
|
128
|
+
@Test
|
129
|
+
public void testAnagramMustUseAllLettersExactlyOnce() {
|
130
|
+
Anagram detector = new Anagram("tapper");
|
131
|
+
assertTrue(detector.match(Arrays.asList("patter")).isEmpty());
|
132
|
+
}
|
119
133
|
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
apply plugin: "java"
|
2
|
+
apply plugin: "eclipse"
|
3
|
+
apply plugin: "idea"
|
4
|
+
|
5
|
+
repositories {
|
6
|
+
mavenCentral()
|
7
|
+
}
|
8
|
+
|
9
|
+
dependencies {
|
10
|
+
testCompile "junit:junit:4.12"
|
11
|
+
}
|
12
|
+
test {
|
13
|
+
testLogging {
|
14
|
+
exceptionFormat = 'full'
|
15
|
+
events = ["passed", "failed", "skipped"]
|
16
|
+
}
|
17
|
+
}
|
@@ -0,0 +1,63 @@
|
|
1
|
+
import java.util.List;
|
2
|
+
|
3
|
+
import static java.util.Arrays.asList;
|
4
|
+
import static java.util.Arrays.stream;
|
5
|
+
|
6
|
+
enum Digit {
|
7
|
+
|
8
|
+
ZERO(asList(" _ ",
|
9
|
+
"| |",
|
10
|
+
"|_|")),
|
11
|
+
|
12
|
+
ONE(asList(" ",
|
13
|
+
" |",
|
14
|
+
" |")),
|
15
|
+
|
16
|
+
TWO(asList(" _ ",
|
17
|
+
" _|",
|
18
|
+
"|_ ")),
|
19
|
+
|
20
|
+
THREE(asList(" _ ",
|
21
|
+
" _|",
|
22
|
+
" _|")),
|
23
|
+
|
24
|
+
FOUR(asList(" ",
|
25
|
+
"|_|",
|
26
|
+
" |")),
|
27
|
+
|
28
|
+
FIVE(asList(" _ ",
|
29
|
+
"|_ ",
|
30
|
+
" _|")),
|
31
|
+
|
32
|
+
SIX(asList(" _ ",
|
33
|
+
"|_ ",
|
34
|
+
"|_|")),
|
35
|
+
|
36
|
+
SEVEN(asList(" _ ",
|
37
|
+
" |",
|
38
|
+
" |")),
|
39
|
+
|
40
|
+
EIGHT(asList(" _ ",
|
41
|
+
"|_|",
|
42
|
+
"|_|")),
|
43
|
+
|
44
|
+
NINE(asList(" _ ",
|
45
|
+
"|_|",
|
46
|
+
" _|"));
|
47
|
+
|
48
|
+
private final List<String> ssdRepresentation;
|
49
|
+
|
50
|
+
Digit(List<String> ssd) {
|
51
|
+
this.ssdRepresentation = ssd;
|
52
|
+
}
|
53
|
+
|
54
|
+
static String fromSsdConfiguration(final List<String> ssdConfiguration) {
|
55
|
+
return stream(values())
|
56
|
+
.filter(digit -> digit.ssdRepresentation.equals(ssdConfiguration))
|
57
|
+
.map(Digit::ordinal)
|
58
|
+
.map(Object::toString)
|
59
|
+
.findFirst()
|
60
|
+
.orElse("?");
|
61
|
+
}
|
62
|
+
|
63
|
+
}
|
@@ -0,0 +1,67 @@
|
|
1
|
+
import java.util.ArrayList;
|
2
|
+
import java.util.List;
|
3
|
+
|
4
|
+
/*
|
5
|
+
* This example solution uses the abbreviation "SSD", short for Seven-Segment Display, throughout.
|
6
|
+
*
|
7
|
+
* For more information, see https://en.wikipedia.org/wiki/Seven-segment_display.
|
8
|
+
*/
|
9
|
+
final class OpticalCharacterReader {
|
10
|
+
|
11
|
+
private static final int ROWS_PER_LINE = 4;
|
12
|
+
|
13
|
+
private static final int COLS_PER_SSD = 3;
|
14
|
+
|
15
|
+
String parse(final List<String> input) {
|
16
|
+
validateInput(input);
|
17
|
+
|
18
|
+
final List<String> parsedLines = new ArrayList<>();
|
19
|
+
|
20
|
+
for (int nLine = 0; nLine < input.size() / ROWS_PER_LINE; nLine++) {
|
21
|
+
final int nFirstRowCurrentLine = nLine * ROWS_PER_LINE;
|
22
|
+
final int nFirstRowNextLine = nFirstRowCurrentLine + ROWS_PER_LINE;
|
23
|
+
|
24
|
+
final List<String> currentLine = input.subList(nFirstRowCurrentLine, nFirstRowNextLine);
|
25
|
+
parsedLines.add(parseLine(currentLine));
|
26
|
+
}
|
27
|
+
|
28
|
+
return String.join(",", parsedLines);
|
29
|
+
}
|
30
|
+
|
31
|
+
private String parseLine(final List<String> currentLine) {
|
32
|
+
final List<String> parsedDigits = new ArrayList<>();
|
33
|
+
|
34
|
+
for (int nSsd = 0; nSsd < currentLine.get(0).length() / COLS_PER_SSD; nSsd++) {
|
35
|
+
final int nFirstColCurrentSsd = nSsd * COLS_PER_SSD;
|
36
|
+
final int nFirstColNextSsd = nFirstColCurrentSsd + COLS_PER_SSD;
|
37
|
+
|
38
|
+
final List<String> currentSsdConfiguration = new ArrayList<>();
|
39
|
+
|
40
|
+
// Bottom row of each line is a spacer, so we ignore that row when constructing SSD configurations.
|
41
|
+
for (int nRow = 0; nRow < ROWS_PER_LINE - 1; nRow++) {
|
42
|
+
currentSsdConfiguration.add(currentLine.get(nRow).substring(nFirstColCurrentSsd, nFirstColNextSsd));
|
43
|
+
}
|
44
|
+
|
45
|
+
parsedDigits.add(Digit.fromSsdConfiguration(currentSsdConfiguration));
|
46
|
+
}
|
47
|
+
|
48
|
+
return String.join("", parsedDigits);
|
49
|
+
}
|
50
|
+
|
51
|
+
private void validateInput(final List<String> input) {
|
52
|
+
final int inputRowCount = input.size();
|
53
|
+
|
54
|
+
if (inputRowCount == 0 || inputRowCount % 4 != 0) {
|
55
|
+
throw new IllegalArgumentException(
|
56
|
+
"Number of input rows must be a positive multiple of " + ROWS_PER_LINE);
|
57
|
+
}
|
58
|
+
|
59
|
+
final int inputColumnCount = input.get(0).length();
|
60
|
+
|
61
|
+
if (inputColumnCount == 0 || inputColumnCount % 3 != 0) {
|
62
|
+
throw new IllegalArgumentException(
|
63
|
+
"Number of input columns must be a positive multiple of " + COLS_PER_SSD);
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
}
|