trackler 2.2.1.57 → 2.2.1.58
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/problem-specifications/exercises/custom-set/canonical-data.json +8 -1
- data/tracks/c/README.md +2 -44
- data/tracks/c/docs/CONTRIBUTING.md +93 -0
- data/tracks/c/docs/C_STYLE_GUIDE.md +1 -1
- data/tracks/clojure/config.json +27 -0
- data/tracks/clojure/exercises/accumulate/project.clj +1 -1
- data/tracks/clojure/exercises/acronym/project.clj +1 -1
- data/tracks/clojure/exercises/all-your-base/project.clj +1 -1
- data/tracks/clojure/exercises/allergies/project.clj +1 -1
- data/tracks/clojure/exercises/anagram/project.clj +1 -1
- data/tracks/clojure/exercises/atbash-cipher/project.clj +1 -1
- data/tracks/clojure/exercises/bank-account/project.clj +1 -1
- data/tracks/clojure/exercises/beer-song/project.clj +1 -1
- data/tracks/clojure/exercises/binary/project.clj +1 -1
- data/tracks/clojure/exercises/binary-search/project.clj +1 -1
- data/tracks/clojure/exercises/binary-search-tree/project.clj +1 -1
- data/tracks/clojure/exercises/bob/project.clj +1 -1
- data/tracks/clojure/exercises/bracket-push/project.clj +1 -1
- data/tracks/clojure/exercises/change/project.clj +1 -1
- data/tracks/clojure/exercises/clock/project.clj +1 -1
- data/tracks/clojure/exercises/collatz-conjecture/project.clj +1 -1
- data/tracks/clojure/exercises/complex-numbers/project.clj +1 -1
- data/tracks/clojure/exercises/crypto-square/project.clj +1 -1
- data/tracks/clojure/exercises/diamond/README.md +51 -0
- data/tracks/clojure/exercises/diamond/project.clj +4 -0
- data/tracks/clojure/exercises/diamond/src/example.clj +22 -0
- data/tracks/clojure/exercises/diamond/test/diamond_test.clj +79 -0
- data/tracks/clojure/exercises/difference-of-squares/project.clj +1 -1
- data/tracks/clojure/exercises/etl/project.clj +1 -1
- data/tracks/clojure/exercises/flatten-array/project.clj +1 -1
- data/tracks/clojure/exercises/gigasecond/project.clj +1 -1
- data/tracks/clojure/exercises/grade-school/project.clj +1 -1
- data/tracks/clojure/exercises/grains/project.clj +1 -1
- data/tracks/clojure/exercises/hamming/project.clj +1 -1
- data/tracks/clojure/exercises/hello-world/project.clj +1 -1
- data/tracks/clojure/exercises/hexadecimal/project.clj +1 -1
- data/tracks/clojure/exercises/isogram/project.clj +1 -1
- data/tracks/clojure/exercises/kindergarten-garden/project.clj +1 -1
- data/tracks/clojure/exercises/largest-series-product/project.clj +1 -1
- data/tracks/clojure/exercises/leap/project.clj +1 -1
- data/tracks/clojure/exercises/luhn/project.clj +1 -1
- data/tracks/clojure/exercises/meetup/project.clj +1 -1
- data/tracks/clojure/exercises/minesweeper/project.clj +1 -1
- data/tracks/clojure/exercises/nth-prime/project.clj +1 -1
- data/tracks/clojure/exercises/nucleotide-count/project.clj +1 -1
- data/tracks/clojure/exercises/octal/project.clj +1 -1
- data/tracks/clojure/exercises/pascals-triangle/project.clj +1 -1
- data/tracks/clojure/exercises/perfect-numbers/project.clj +1 -1
- data/tracks/clojure/exercises/phone-number/project.clj +1 -1
- data/tracks/clojure/exercises/pig-latin/project.clj +1 -1
- data/tracks/clojure/exercises/prime-factors/project.clj +1 -1
- data/tracks/clojure/exercises/protein-translation/README.md +40 -0
- data/tracks/clojure/exercises/protein-translation/project.clj +4 -0
- data/tracks/clojure/exercises/protein-translation/src/example.clj +19 -0
- data/tracks/clojure/exercises/protein-translation/test/protein_translation_test.clj +36 -0
- data/tracks/clojure/exercises/queen-attack/project.clj +1 -1
- data/tracks/clojure/exercises/raindrops/project.clj +1 -1
- data/tracks/clojure/exercises/rna-transcription/project.clj +1 -1
- data/tracks/clojure/exercises/robot-name/project.clj +1 -1
- data/tracks/clojure/exercises/robot-simulator/project.clj +1 -1
- data/tracks/clojure/exercises/roman-numerals/project.clj +1 -1
- data/tracks/clojure/exercises/rotational-cipher/project.clj +1 -1
- data/tracks/clojure/exercises/run-length-encoding/README.md +36 -0
- data/tracks/clojure/exercises/run-length-encoding/project.clj +4 -0
- data/tracks/clojure/exercises/run-length-encoding/src/example.clj +20 -0
- data/tracks/clojure/exercises/run-length-encoding/src/run_length_encoding.clj +11 -0
- data/tracks/clojure/exercises/run-length-encoding/test/run_length_encoding_test.clj +57 -0
- data/tracks/clojure/exercises/scrabble-score/project.clj +1 -1
- data/tracks/clojure/exercises/secret-handshake/project.clj +1 -1
- data/tracks/clojure/exercises/series/project.clj +1 -1
- data/tracks/clojure/exercises/sieve/project.clj +1 -1
- data/tracks/clojure/exercises/space-age/project.clj +1 -1
- data/tracks/clojure/exercises/spiral-matrix/project.clj +1 -1
- data/tracks/clojure/exercises/strain/project.clj +1 -1
- data/tracks/clojure/exercises/sublist/project.clj +1 -1
- data/tracks/clojure/exercises/sum-of-multiples/project.clj +1 -1
- data/tracks/clojure/exercises/triangle/project.clj +1 -1
- data/tracks/clojure/exercises/trinary/project.clj +1 -1
- data/tracks/clojure/exercises/word-count/project.clj +1 -1
- data/tracks/clojure/exercises/wordy/project.clj +1 -1
- data/tracks/clojure/project.clj +2 -2
- data/tracks/ecmascript/config.json +10 -15
- data/tracks/ecmascript/docs/TESTS.md +15 -0
- data/tracks/ecmascript/exercises/complex-numbers/README.md +68 -0
- data/tracks/ecmascript/exercises/complex-numbers/complex-numbers.spec.js +216 -0
- data/tracks/ecmascript/exercises/complex-numbers/example.js +43 -0
- data/tracks/ecmascript/exercises/{transpose → complex-numbers}/package.json +2 -2
- data/tracks/elixir/config.json +22 -1
- data/tracks/elixir/exercises/isbn-verifier/README.md +80 -0
- data/tracks/elixir/exercises/isbn-verifier/example.exs +36 -0
- data/tracks/elixir/exercises/isbn-verifier/isbn_verifier.exs +18 -0
- data/tracks/elixir/exercises/isbn-verifier/isbn_verifier_test.exs +75 -0
- data/tracks/elixir/exercises/spiral-matrix/README.md +65 -0
- data/tracks/elixir/exercises/spiral-matrix/example.exs +27 -0
- data/tracks/elixir/exercises/spiral-matrix/spiral.exs +9 -0
- data/tracks/elixir/exercises/spiral-matrix/spiral_test.exs +58 -0
- data/tracks/erlang/config.json +10 -0
- data/tracks/erlang/exercises/complex-numbers/HINTS.md +2 -0
- data/tracks/erlang/exercises/complex-numbers/README.md +85 -0
- data/tracks/erlang/exercises/complex-numbers/include/exercism.hrl +11 -0
- data/tracks/erlang/exercises/complex-numbers/rebar.config +30 -0
- data/tracks/erlang/exercises/complex-numbers/src/complex_numbers.app.src +9 -0
- data/tracks/erlang/exercises/complex-numbers/src/complex_numbers.erl +29 -0
- data/tracks/erlang/exercises/complex-numbers/src/example.erl +44 -0
- data/tracks/erlang/exercises/complex-numbers/test/complex_numbers_tests.erl +152 -0
- data/tracks/erlang/testgen/src/tgen.erl +1 -1
- data/tracks/erlang/testgen/src/tgen_complex-numbers.erl +75 -0
- data/tracks/java/config.json +10 -5
- data/tracks/javascript/config.json +13 -0
- data/tracks/javascript/exercises/isbn-verifier/README.md +66 -0
- data/tracks/javascript/exercises/isbn-verifier/example.js +24 -0
- data/tracks/javascript/exercises/isbn-verifier/isbn-verifier.spec.js +68 -0
- data/tracks/perl6/config/maintainers.json +4 -4
- data/tracks/perl6/config.json +21 -21
- data/tracks/php/README.md +1 -0
- data/tracks/python/config/maintainers.json +3 -3
- data/tracks/python/exercises/alphametics/alphametics_test.py +6 -6
- data/tracks/python/exercises/queen-attack/queen_attack_test.py +60 -40
- data/tracks/sml/config.json +13 -2
- data/tracks/sml/exercises/flatten-array/{HINTS.md → .meta/hints.md} +0 -0
- data/tracks/sml/exercises/nth-prime/{HINTS.md → .meta/hints.md} +0 -0
- data/tracks/sml/exercises/pig-latin/README.md +54 -0
- data/tracks/sml/exercises/pig-latin/example.sml +23 -0
- data/tracks/sml/exercises/pig-latin/pig-latin.sml +2 -0
- data/tracks/sml/exercises/pig-latin/test.sml +90 -0
- data/tracks/sml/exercises/pig-latin/testlib.sml +159 -0
- data/tracks/typescript/config.json +16 -0
- data/tracks/typescript/exercises/ocr-numbers/README.md +110 -0
- data/tracks/typescript/exercises/ocr-numbers/ocr-numbers.example.ts +92 -0
- data/tracks/typescript/exercises/ocr-numbers/ocr-numbers.test.ts +155 -0
- data/tracks/typescript/exercises/ocr-numbers/ocr-numbers.ts +3 -0
- data/tracks/typescript/exercises/ocr-numbers/package.json +36 -0
- data/tracks/typescript/exercises/ocr-numbers/tsconfig.json +22 -0
- data/tracks/typescript/exercises/ocr-numbers/tslint.json +127 -0
- data/tracks/typescript/exercises/ocr-numbers/yarn.lock +2624 -0
- metadata +55 -8
- data/tracks/ecmascript/exercises/transpose/README.md +0 -94
- data/tracks/ecmascript/exercises/transpose/example.js +0 -12
- data/tracks/ecmascript/exercises/transpose/transpose.spec.js +0 -67
@@ -0,0 +1,159 @@
|
|
1
|
+
structure Expect =
|
2
|
+
struct
|
3
|
+
datatype expectation = Pass | Fail of string * string
|
4
|
+
|
5
|
+
local
|
6
|
+
fun failEq b a =
|
7
|
+
Fail ("Expected: " ^ b, "Got: " ^ a)
|
8
|
+
|
9
|
+
fun failExn b a =
|
10
|
+
Fail ("Expected: " ^ b, "Raised: " ^ a)
|
11
|
+
|
12
|
+
fun exnName (e: exn): string = General.exnName e
|
13
|
+
in
|
14
|
+
fun truthy a =
|
15
|
+
if a
|
16
|
+
then Pass
|
17
|
+
else failEq "true" "false"
|
18
|
+
|
19
|
+
fun falsy a =
|
20
|
+
if a
|
21
|
+
then failEq "false" "true"
|
22
|
+
else Pass
|
23
|
+
|
24
|
+
fun equalTo b a =
|
25
|
+
if a = b
|
26
|
+
then Pass
|
27
|
+
else failEq (PolyML.makestring b) (PolyML.makestring a)
|
28
|
+
|
29
|
+
fun nearTo b a =
|
30
|
+
if Real.== (a, b)
|
31
|
+
then Pass
|
32
|
+
else failEq (Real.toString b) (Real.toString a)
|
33
|
+
|
34
|
+
fun anyError f =
|
35
|
+
(
|
36
|
+
f ();
|
37
|
+
failExn "an exception" "Nothing"
|
38
|
+
) handle _ => Pass
|
39
|
+
|
40
|
+
fun error e f =
|
41
|
+
(
|
42
|
+
f ();
|
43
|
+
failExn (exnName e) "Nothing"
|
44
|
+
) handle e' => if exnMessage e' = exnMessage e
|
45
|
+
then Pass
|
46
|
+
else failExn (exnMessage e) (exnMessage e')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
structure TermColor =
|
51
|
+
struct
|
52
|
+
datatype color = Red | Green | Yellow | Normal
|
53
|
+
|
54
|
+
fun f Red = "\027[31m"
|
55
|
+
| f Green = "\027[32m"
|
56
|
+
| f Yellow = "\027[33m"
|
57
|
+
| f Normal = "\027[0m"
|
58
|
+
|
59
|
+
fun colorize color s = (f color) ^ s ^ (f Normal)
|
60
|
+
|
61
|
+
val redit = colorize Red
|
62
|
+
|
63
|
+
val greenit = colorize Green
|
64
|
+
|
65
|
+
val yellowit = colorize Yellow
|
66
|
+
end
|
67
|
+
|
68
|
+
structure Test =
|
69
|
+
struct
|
70
|
+
datatype testnode = TestGroup of string * testnode list
|
71
|
+
| Test of string * (unit -> Expect.expectation)
|
72
|
+
|
73
|
+
local
|
74
|
+
datatype evaluation = Success of string
|
75
|
+
| Failure of string * string * string
|
76
|
+
| Error of string * string
|
77
|
+
|
78
|
+
fun indent n s = (implode (List.tabulate (n, fn _ => #" "))) ^ s
|
79
|
+
|
80
|
+
fun fmt indentlvl ev =
|
81
|
+
let
|
82
|
+
val check = TermColor.greenit "\226\156\148 " (* ✔ *)
|
83
|
+
val cross = TermColor.redit "\226\156\150 " (* ✖ *)
|
84
|
+
val indentlvl = indentlvl * 2
|
85
|
+
in
|
86
|
+
case ev of
|
87
|
+
Success descr => indent indentlvl (check ^ descr)
|
88
|
+
| Failure (descr, exp, got) =>
|
89
|
+
String.concatWith "\n" [indent indentlvl (cross ^ descr),
|
90
|
+
indent (indentlvl + 2) exp,
|
91
|
+
indent (indentlvl + 2) got]
|
92
|
+
| Error (descr, reason) =>
|
93
|
+
String.concatWith "\n" [indent indentlvl (cross ^ descr),
|
94
|
+
indent (indentlvl + 2) (TermColor.redit reason)]
|
95
|
+
end
|
96
|
+
|
97
|
+
fun eval (TestGroup _) = raise Fail "Only a 'Test' can be evaluated"
|
98
|
+
| eval (Test (descr, thunk)) =
|
99
|
+
(
|
100
|
+
case thunk () of
|
101
|
+
Expect.Pass => ((1, 0, 0), Success descr)
|
102
|
+
| Expect.Fail (s, s') => ((0, 1, 0), Failure (descr, s, s'))
|
103
|
+
)
|
104
|
+
handle e => ((0, 0, 1), Error (descr, "Unexpected error: " ^ exnMessage e))
|
105
|
+
|
106
|
+
fun flatten depth testnode =
|
107
|
+
let
|
108
|
+
fun sum (x, y, z) (a, b, c) = (x + a, y + b, z + c)
|
109
|
+
|
110
|
+
fun aux (t, (counter, acc)) =
|
111
|
+
let
|
112
|
+
val (counter', texts) = flatten (depth + 1) t
|
113
|
+
in
|
114
|
+
(sum counter' counter, texts :: acc)
|
115
|
+
end
|
116
|
+
in
|
117
|
+
case testnode of
|
118
|
+
TestGroup (descr, ts) =>
|
119
|
+
let
|
120
|
+
val (counter, texts) = foldr aux ((0, 0, 0), []) ts
|
121
|
+
in
|
122
|
+
(counter, (indent (depth * 2) descr) :: List.concat texts)
|
123
|
+
end
|
124
|
+
| Test _ =>
|
125
|
+
let
|
126
|
+
val (counter, evaluation) = eval testnode
|
127
|
+
in
|
128
|
+
(counter, [fmt depth evaluation])
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
fun println s = print (s ^ "\n")
|
133
|
+
in
|
134
|
+
fun run suite =
|
135
|
+
let
|
136
|
+
val ((succeeded, failed, errored), texts) = flatten 0 suite
|
137
|
+
|
138
|
+
val summary = String.concatWith ", " [
|
139
|
+
TermColor.greenit ((Int.toString succeeded) ^ " passed"),
|
140
|
+
TermColor.redit ((Int.toString failed) ^ " failed"),
|
141
|
+
TermColor.redit ((Int.toString errored) ^ " errored"),
|
142
|
+
(Int.toString (succeeded + failed + errored)) ^ " total"
|
143
|
+
]
|
144
|
+
|
145
|
+
val status = if failed = 0 andalso errored = 0
|
146
|
+
then OS.Process.success
|
147
|
+
else OS.Process.failure
|
148
|
+
|
149
|
+
in
|
150
|
+
List.app println texts;
|
151
|
+
println "";
|
152
|
+
println ("Tests: " ^ summary);
|
153
|
+
OS.Process.exit status
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
fun describe description tests = Test.TestGroup (description, tests)
|
159
|
+
fun test description thunk = Test.Test (description, thunk)
|
@@ -479,6 +479,22 @@
|
|
479
479
|
],
|
480
480
|
"unlocked_by": "wordy",
|
481
481
|
"uuid": "abe907d0-7ca0-4fe5-83fd-72a4d2acab66"
|
482
|
+
},
|
483
|
+
{
|
484
|
+
"core": false,
|
485
|
+
"difficulty": 5,
|
486
|
+
"slug": "ocr-numbers",
|
487
|
+
"topics": [
|
488
|
+
"control_flow_conditionals",
|
489
|
+
"control_flow_loops",
|
490
|
+
"exception_handling",
|
491
|
+
"equality",
|
492
|
+
"parsing",
|
493
|
+
"integers",
|
494
|
+
"text_formatting"
|
495
|
+
],
|
496
|
+
"unlocked_by": "matrix",
|
497
|
+
"uuid": "61f0964f-0779-446d-bd6b-6bb988414302"
|
482
498
|
}
|
483
499
|
],
|
484
500
|
"foregone": [],
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# Ocr Numbers
|
2
|
+
|
3
|
+
Given a 3 x 4 grid of pipes, underscores, and spaces, determine which number is
|
4
|
+
represented, or whether it is garbled.
|
5
|
+
|
6
|
+
# Step One
|
7
|
+
|
8
|
+
To begin with, convert a simple binary font to a string containing 0 or 1.
|
9
|
+
|
10
|
+
The binary font uses pipes and underscores, four rows high and three columns wide.
|
11
|
+
|
12
|
+
```
|
13
|
+
_ #
|
14
|
+
| | # zero.
|
15
|
+
|_| #
|
16
|
+
# the fourth row is always blank
|
17
|
+
```
|
18
|
+
|
19
|
+
Is converted to "0"
|
20
|
+
|
21
|
+
```
|
22
|
+
#
|
23
|
+
| # one.
|
24
|
+
| #
|
25
|
+
# (blank fourth row)
|
26
|
+
```
|
27
|
+
|
28
|
+
Is converted to "1"
|
29
|
+
|
30
|
+
If the input is the correct size, but not recognizable, your program should return '?'
|
31
|
+
|
32
|
+
If the input is the incorrect size, your program should return an error.
|
33
|
+
|
34
|
+
# Step Two
|
35
|
+
|
36
|
+
Update your program to recognize multi-character binary strings, replacing garbled numbers with ?
|
37
|
+
|
38
|
+
# Step Three
|
39
|
+
|
40
|
+
Update your program to recognize all numbers 0 through 9, both individually and as part of a larger string.
|
41
|
+
|
42
|
+
```
|
43
|
+
_
|
44
|
+
_|
|
45
|
+
|_
|
46
|
+
|
47
|
+
```
|
48
|
+
|
49
|
+
Is converted to "2"
|
50
|
+
|
51
|
+
```
|
52
|
+
_ _ _ _ _ _ _ _ #
|
53
|
+
| _| _||_||_ |_ ||_||_|| | # decimal numbers.
|
54
|
+
||_ _| | _||_| ||_| _||_| #
|
55
|
+
# fourth line is always blank
|
56
|
+
```
|
57
|
+
|
58
|
+
Is converted to "1234567890"
|
59
|
+
|
60
|
+
# Step Four
|
61
|
+
|
62
|
+
Update your program to handle multiple numbers, one per line. When converting several lines, join the lines with commas.
|
63
|
+
|
64
|
+
```
|
65
|
+
_ _
|
66
|
+
| _| _|
|
67
|
+
||_ _|
|
68
|
+
|
69
|
+
_ _
|
70
|
+
|_||_ |_
|
71
|
+
| _||_|
|
72
|
+
|
73
|
+
_ _ _
|
74
|
+
||_||_|
|
75
|
+
||_| _|
|
76
|
+
|
77
|
+
```
|
78
|
+
|
79
|
+
Is converted to "123,456,789"
|
80
|
+
|
81
|
+
## Setup
|
82
|
+
|
83
|
+
Go through the setup instructions for TypeScript to
|
84
|
+
install the necessary dependencies:
|
85
|
+
|
86
|
+
http://exercism.io/languages/typescript
|
87
|
+
|
88
|
+
## Requirements
|
89
|
+
|
90
|
+
Install assignment dependencies:
|
91
|
+
|
92
|
+
```bash
|
93
|
+
$ yarn install
|
94
|
+
```
|
95
|
+
|
96
|
+
## Making the test suite pass
|
97
|
+
|
98
|
+
Execute the tests with:
|
99
|
+
|
100
|
+
```bash
|
101
|
+
$ yarn test
|
102
|
+
```
|
103
|
+
|
104
|
+
|
105
|
+
## Source
|
106
|
+
|
107
|
+
Inspired by the Bank OCR kata [http://codingdojo.org/cgi-bin/wiki.pl?KataBankOCR](http://codingdojo.org/cgi-bin/wiki.pl?KataBankOCR)
|
108
|
+
|
109
|
+
## Submitting Incomplete Solutions
|
110
|
+
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
@@ -0,0 +1,92 @@
|
|
1
|
+
interface Patterns {
|
2
|
+
[key: number]: string[]
|
3
|
+
}
|
4
|
+
|
5
|
+
const PATTERNS: Patterns = {
|
6
|
+
0: [' _ ',
|
7
|
+
'| |',
|
8
|
+
'|_|',
|
9
|
+
' '],
|
10
|
+
1: [' ',
|
11
|
+
' |',
|
12
|
+
' |',
|
13
|
+
' '],
|
14
|
+
2: [' _ ',
|
15
|
+
' _|',
|
16
|
+
'|_ ',
|
17
|
+
' '],
|
18
|
+
3: [' _ ',
|
19
|
+
' _|',
|
20
|
+
' _|',
|
21
|
+
' '],
|
22
|
+
4: [' ',
|
23
|
+
'|_|',
|
24
|
+
' |',
|
25
|
+
' '],
|
26
|
+
5: [' _ ',
|
27
|
+
'|_ ',
|
28
|
+
' _|',
|
29
|
+
' '],
|
30
|
+
6: [' _ ',
|
31
|
+
'|_ ',
|
32
|
+
'|_|',
|
33
|
+
' '],
|
34
|
+
7: [' _ ',
|
35
|
+
' |',
|
36
|
+
' |',
|
37
|
+
' '],
|
38
|
+
8: [' _ ',
|
39
|
+
'|_|',
|
40
|
+
'|_|',
|
41
|
+
' '],
|
42
|
+
9: [' _ ',
|
43
|
+
'|_|',
|
44
|
+
' _|',
|
45
|
+
' '],
|
46
|
+
}
|
47
|
+
|
48
|
+
export default class OcrParser {
|
49
|
+
static convert(text: string) {
|
50
|
+
return OcrParser.splitIntoRows(text).map(OcrParser.valuesInRow).join(',')
|
51
|
+
}
|
52
|
+
|
53
|
+
static valuesInRow(row: string) {
|
54
|
+
return OcrParser.splitIntoDigits(row).map(OcrParser.getDigit).join('')
|
55
|
+
}
|
56
|
+
|
57
|
+
static splitIntoRows(text: string) {
|
58
|
+
const rows = []
|
59
|
+
const lines = text.split('\n')
|
60
|
+
for (let rowNumber = 0; rowNumber < lines.length; rowNumber += 4) {
|
61
|
+
let row = ''
|
62
|
+
for (let rowLine = 0; rowLine < 4; rowLine++) {
|
63
|
+
row += `${lines[rowNumber + rowLine]}\n`
|
64
|
+
}
|
65
|
+
rows.push(row.slice(0, -1))
|
66
|
+
}
|
67
|
+
return rows
|
68
|
+
}
|
69
|
+
|
70
|
+
static splitIntoDigits(row: string) {
|
71
|
+
const digits = [],
|
72
|
+
rows = row.split('\n')
|
73
|
+
for (let digitNumber = 0; digitNumber < rows[0].length; digitNumber += 3) {
|
74
|
+
let digit = ''
|
75
|
+
for (const row of rows) {
|
76
|
+
digit += row.substr(digitNumber, 3)
|
77
|
+
}
|
78
|
+
digits.push(digit)
|
79
|
+
}
|
80
|
+
return digits
|
81
|
+
}
|
82
|
+
|
83
|
+
static getDigit(text: string) {
|
84
|
+
for (const digit in PATTERNS) {
|
85
|
+
if (PATTERNS[digit].join('') === text) {
|
86
|
+
return digit
|
87
|
+
}
|
88
|
+
}
|
89
|
+
return '?'
|
90
|
+
}
|
91
|
+
|
92
|
+
}
|
@@ -0,0 +1,155 @@
|
|
1
|
+
import OcrParser from "./ocr-numbers"
|
2
|
+
|
3
|
+
describe('ocr', () => {
|
4
|
+
it('recognizes zero', () => {
|
5
|
+
expect(OcrParser.convert(
|
6
|
+
' _ \n' +
|
7
|
+
'| |\n' +
|
8
|
+
'|_|\n' +
|
9
|
+
' ',
|
10
|
+
)).toBe('0')
|
11
|
+
})
|
12
|
+
|
13
|
+
xit('recognizes one', () => {
|
14
|
+
expect(OcrParser.convert(
|
15
|
+
' \n' +
|
16
|
+
' |\n' +
|
17
|
+
' |\n' +
|
18
|
+
' ',
|
19
|
+
)).toBe('1')
|
20
|
+
})
|
21
|
+
|
22
|
+
xit('recognizes two', () => {
|
23
|
+
expect(OcrParser.convert(
|
24
|
+
' _ \n' +
|
25
|
+
' _|\n' +
|
26
|
+
'|_ \n' +
|
27
|
+
' ',
|
28
|
+
)).toBe('2')
|
29
|
+
})
|
30
|
+
|
31
|
+
xit('recognizes three', () => {
|
32
|
+
expect(OcrParser.convert(
|
33
|
+
' _ \n' +
|
34
|
+
' _|\n' +
|
35
|
+
' _|\n' +
|
36
|
+
' ',
|
37
|
+
)).toBe('3')
|
38
|
+
})
|
39
|
+
|
40
|
+
xit('recognizes four', () => {
|
41
|
+
expect(OcrParser.convert(
|
42
|
+
' \n' +
|
43
|
+
'|_|\n' +
|
44
|
+
' |\n' +
|
45
|
+
' ',
|
46
|
+
)).toBe('4')
|
47
|
+
})
|
48
|
+
|
49
|
+
xit('recognizes five', () => {
|
50
|
+
expect(OcrParser.convert(
|
51
|
+
' _ \n' +
|
52
|
+
'|_ \n' +
|
53
|
+
' _|\n' +
|
54
|
+
' ',
|
55
|
+
)).toBe('5')
|
56
|
+
})
|
57
|
+
|
58
|
+
xit('recognizes six', () => {
|
59
|
+
expect(OcrParser.convert(
|
60
|
+
' _ \n' +
|
61
|
+
'|_ \n' +
|
62
|
+
'|_|\n' +
|
63
|
+
' ',
|
64
|
+
)).toBe('6')
|
65
|
+
})
|
66
|
+
|
67
|
+
xit('recognizes seven', () => {
|
68
|
+
expect(OcrParser.convert(
|
69
|
+
' _ \n' +
|
70
|
+
' |\n' +
|
71
|
+
' |\n' +
|
72
|
+
' ',
|
73
|
+
)).toBe('7')
|
74
|
+
})
|
75
|
+
|
76
|
+
xit('recognizes eight', () => {
|
77
|
+
expect(OcrParser.convert(
|
78
|
+
' _ \n' +
|
79
|
+
'|_|\n' +
|
80
|
+
'|_|\n' +
|
81
|
+
' ',
|
82
|
+
)).toBe('8')
|
83
|
+
})
|
84
|
+
|
85
|
+
xit('recognizes nine', () => {
|
86
|
+
expect(OcrParser.convert(
|
87
|
+
' _ \n' +
|
88
|
+
'|_|\n' +
|
89
|
+
' _|\n' +
|
90
|
+
' ',
|
91
|
+
)).toBe('9')
|
92
|
+
})
|
93
|
+
|
94
|
+
xit('recognizes ten', () => {
|
95
|
+
expect(OcrParser.convert(
|
96
|
+
' _ \n' +
|
97
|
+
' || |\n' +
|
98
|
+
' ||_|\n' +
|
99
|
+
' ',
|
100
|
+
)).toBe('10')
|
101
|
+
})
|
102
|
+
|
103
|
+
xit('identifies garble', () => {
|
104
|
+
expect(OcrParser.convert(
|
105
|
+
' \n' +
|
106
|
+
'| |\n' +
|
107
|
+
'| |\n' +
|
108
|
+
' ',
|
109
|
+
)).toBe('?')
|
110
|
+
})
|
111
|
+
|
112
|
+
xit('converts 110101100', () => {
|
113
|
+
expect(OcrParser.convert(
|
114
|
+
' _ _ _ _ \n' +
|
115
|
+
' | || | || | | || || |\n' +
|
116
|
+
' | ||_| ||_| | ||_||_|\n' +
|
117
|
+
' ',
|
118
|
+
)).toBe('110101100')
|
119
|
+
})
|
120
|
+
|
121
|
+
xit('identifies garble mixed in', () => {
|
122
|
+
expect(OcrParser.convert(
|
123
|
+
' _ _ _ \n' +
|
124
|
+
' | || | || | || || |\n' +
|
125
|
+
' | | _| ||_| | ||_||_|\n' +
|
126
|
+
' ',
|
127
|
+
)).toBe('11?10?1?0')
|
128
|
+
})
|
129
|
+
|
130
|
+
xit('converts 1234567890', () => {
|
131
|
+
expect(OcrParser.convert(
|
132
|
+
' _ _ _ _ _ _ _ _ \n' +
|
133
|
+
' | _| _||_||_ |_ ||_||_|| |\n' +
|
134
|
+
' ||_ _| | _||_| ||_| _||_|\n' +
|
135
|
+
' ',
|
136
|
+
)).toBe('1234567890')
|
137
|
+
})
|
138
|
+
|
139
|
+
xit('converts 123 456 789', () => {
|
140
|
+
expect(OcrParser.convert(
|
141
|
+
' _ _ \n' +
|
142
|
+
' | _| _|\n' +
|
143
|
+
' ||_ _|\n' +
|
144
|
+
' \n' +
|
145
|
+
' _ _ \n' +
|
146
|
+
'|_||_ |_ \n' +
|
147
|
+
' | _||_|\n' +
|
148
|
+
' \n' +
|
149
|
+
' _ _ _ \n' +
|
150
|
+
' ||_||_|\n' +
|
151
|
+
' ||_| _|\n' +
|
152
|
+
' ',
|
153
|
+
)).toBe('123,456,789')
|
154
|
+
})
|
155
|
+
})
|
@@ -0,0 +1,36 @@
|
|
1
|
+
{
|
2
|
+
"name": "xtypescript",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"description": "Exercism exercises in Typescript.",
|
5
|
+
"author": "",
|
6
|
+
"private": true,
|
7
|
+
"repository": {
|
8
|
+
"type": "git",
|
9
|
+
"url": "https://github.com/exercism/xtypescript"
|
10
|
+
},
|
11
|
+
"devDependencies": {},
|
12
|
+
"scripts": {
|
13
|
+
"test": "tsc --noEmit -p . && jest --no-cache",
|
14
|
+
"lint": "tsc --noEmit -p . && tslint \"*.ts?(x)\"",
|
15
|
+
"lintci": "tslint \"*.ts?(x)\" --force"
|
16
|
+
},
|
17
|
+
"dependencies": {
|
18
|
+
"@types/jest": "^21.1.5",
|
19
|
+
"@types/node": "^8.0.47",
|
20
|
+
"jest": "^21.2.1",
|
21
|
+
"ts-jest": "^21.1.3",
|
22
|
+
"tslint": "^5.8.0",
|
23
|
+
"typescript": "^2.5.3"
|
24
|
+
},
|
25
|
+
"jest": {
|
26
|
+
"transform": {
|
27
|
+
".(ts|tsx)": "<rootDir>/node_modules/ts-jest/preprocessor.js"
|
28
|
+
},
|
29
|
+
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
|
30
|
+
"moduleFileExtensions": [
|
31
|
+
"ts",
|
32
|
+
"tsx",
|
33
|
+
"js"
|
34
|
+
]
|
35
|
+
}
|
36
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
{
|
2
|
+
"compilerOptions": {
|
3
|
+
"target": "es2017",
|
4
|
+
"module": "commonjs",
|
5
|
+
"alwaysStrict": true,
|
6
|
+
"noUnusedLocals": true,
|
7
|
+
"noUnusedParameters": true,
|
8
|
+
"noImplicitAny": true,
|
9
|
+
"strictNullChecks": true,
|
10
|
+
"preserveConstEnums": true,
|
11
|
+
"noFallthroughCasesInSwitch":true,
|
12
|
+
"noImplicitThis":true,
|
13
|
+
"noImplicitReturns":true,
|
14
|
+
"sourceMap": true,
|
15
|
+
"noEmitOnError": true,
|
16
|
+
"outDir": "./build"
|
17
|
+
},
|
18
|
+
"compileOnSave": true,
|
19
|
+
"exclude": [
|
20
|
+
"node_modules"
|
21
|
+
]
|
22
|
+
}
|