trackler 2.2.1.175 → 2.2.1.176
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/tracks/clojure/config.json +1 -0
- data/tracks/clojure/docs/ABOUT.md +13 -0
- data/tracks/clojure/docs/INSTALLATION.md +21 -0
- data/tracks/clojure/docs/LEARNING.md +29 -0
- data/tracks/clojure/docs/RESOURCES.md +9 -0
- data/tracks/clojure/docs/{TESTS.org → TESTS.md} +22 -27
- data/tracks/clojure/exercises/anagram/src/anagram.clj +1 -1
- data/tracks/clojure/exercises/armstrong-numbers/src/armstrong_numbers.clj +1 -1
- data/tracks/clojure/exercises/beer-song/src/beer_song.clj +1 -1
- data/tracks/clojure/exercises/bob/src/bob.clj +1 -1
- data/tracks/clojure/exercises/clock/src/clock.clj +3 -3
- data/tracks/clojure/exercises/collatz-conjecture/src/collatz_conjecture.clj +1 -1
- data/tracks/clojure/exercises/etl/src/etl.clj +1 -1
- data/tracks/clojure/exercises/flatten-array/src/flatten_array.clj +1 -1
- data/tracks/clojure/exercises/grade-school/src/grade_school.clj +3 -3
- data/tracks/clojure/exercises/hamming/src/hamming.clj +2 -2
- data/tracks/clojure/exercises/leap/src/leap.clj +1 -1
- data/tracks/clojure/exercises/nucleotide-count/src/nucleotide_count.clj +2 -2
- data/tracks/clojure/exercises/phone-number/src/phone_number.clj +3 -3
- data/tracks/clojure/exercises/reverse-string/src/reverse_string.clj +1 -1
- data/tracks/clojure/exercises/rna-transcription/src/rna_transcription.clj +1 -1
- data/tracks/clojure/exercises/robot-name/src/robot_name.clj +2 -2
- data/tracks/clojure/exercises/run-length-encoding/src/run_length_encoding.clj +3 -3
- data/tracks/clojure/exercises/say/src/say.clj +1 -1
- data/tracks/clojure/exercises/series/src/series.clj +1 -1
- data/tracks/clojure/exercises/sublist/src/sublist.clj +1 -1
- data/tracks/clojure/exercises/two-fer/src/two_fer.clj +1 -1
- data/tracks/clojure/exercises/word-count/src/word_count.clj +1 -1
- data/tracks/ecmascript/config.json +12 -0
- data/tracks/ecmascript/exercises/reverse-string/README.md +42 -0
- data/tracks/ecmascript/exercises/reverse-string/example.js +9 -0
- data/tracks/ecmascript/exercises/reverse-string/package.json +70 -0
- data/tracks/ecmascript/exercises/reverse-string/reverse-string.spec.js +33 -0
- data/tracks/erlang/config.json +11 -0
- data/tracks/erlang/exercises/armstrong-numbers/README.md +53 -0
- data/tracks/erlang/exercises/armstrong-numbers/rebar.config +30 -0
- data/tracks/erlang/exercises/armstrong-numbers/src/armstrong_numbers.app.src +9 -0
- data/tracks/erlang/exercises/armstrong-numbers/src/armstrong_numbers.erl +8 -0
- data/tracks/erlang/exercises/armstrong-numbers/src/example.erl +29 -0
- data/tracks/erlang/exercises/armstrong-numbers/test/armstrong_numbers_tests.erl +33 -0
- data/tracks/erlang/exercises/bracket-push/src/example.erl +1 -1
- data/tracks/erlang/exercises/isbn-verifier/src/example.erl +1 -1
- data/tracks/julia/config.json +12 -0
- data/tracks/julia/docs/ABOUT.md +3 -3
- data/tracks/julia/exercises/spiral-matrix/README.md +31 -0
- data/tracks/julia/exercises/spiral-matrix/example.jl +9 -0
- data/tracks/julia/exercises/spiral-matrix/runtests.jl +25 -0
- data/tracks/julia/exercises/spiral-matrix/spiral-matrix.jl +3 -0
- data/tracks/perl5/config.json +1 -0
- data/tracks/perl5/docs/ABOUT.md +4 -3
- data/tracks/perl6/config.json +1 -0
- data/tracks/powershell/config.json +1 -1
- data/tracks/python/exercises/hello-world/example.py +2 -5
- data/tracks/python/exercises/hello-world/hello_world.py +1 -1
- data/tracks/reasonml/.gitignore +1 -0
- data/tracks/reasonml/Makefile +6 -3
- data/tracks/reasonml/config.json +21 -0
- data/tracks/reasonml/exercises/anagram/src/Anagram.rei +1 -0
- data/tracks/reasonml/exercises/anagram/src/Example.re +10 -12
- data/tracks/reasonml/exercises/binary-search/src/BinarySearch.rei +1 -0
- data/tracks/reasonml/exercises/bob/src/Bob.rei +1 -0
- data/tracks/reasonml/exercises/change/src/Change.rei +2 -0
- data/tracks/reasonml/exercises/change/src/Example.re +16 -15
- data/tracks/reasonml/exercises/hello-world/src/HelloWorld.rei +1 -0
- data/tracks/reasonml/exercises/leap/src/Leap.rei +1 -0
- data/tracks/reasonml/exercises/pangram/README.md +21 -0
- data/tracks/reasonml/exercises/pangram/__tests__/Pangram_test.re +36 -0
- data/tracks/reasonml/exercises/pangram/bsconfig.json +30 -0
- data/tracks/reasonml/exercises/pangram/package.json +20 -0
- data/tracks/reasonml/exercises/pangram/src/Example.re +36 -0
- data/tracks/reasonml/exercises/pangram/src/Pangram.rei +1 -0
- data/tracks/reasonml/exercises/phone-number/.gitignore +6 -0
- data/tracks/reasonml/exercises/phone-number/README.md +43 -0
- data/tracks/reasonml/exercises/phone-number/__tests__/PhoneNumber_test.re +48 -0
- data/tracks/reasonml/exercises/phone-number/bsconfig.json +27 -0
- data/tracks/reasonml/exercises/phone-number/package-lock.json +5853 -0
- data/tracks/reasonml/exercises/phone-number/package.json +20 -0
- data/tracks/reasonml/exercises/phone-number/src/Example.re +13 -0
- data/tracks/reasonml/exercises/phone-number/src/PhoneNumber.rei +1 -0
- data/tracks/reasonml/exercises/raindrops/src/Raindrops.rei +1 -0
- data/tracks/reasonml/exercises/rna-transcription/src/Example.re +13 -6
- data/tracks/reasonml/exercises/rna-transcription/src/RnaTranscription.rei +13 -0
- data/tracks/reasonml/exercises/run-length-encoding/src/RunLengthEncoding.rei +2 -0
- data/tracks/reasonml/exercises/space-age/__tests__/SpaceAge_test.re +8 -8
- data/tracks/reasonml/exercises/space-age/src/Example.re +3 -5
- data/tracks/reasonml/exercises/space-age/src/SpaceAge.rei +11 -0
- data/tracks/reasonml/exercises/word-count/src/WordCount.rei +1 -0
- data/tracks/sml/config.json +1 -0
- data/tracks/swift/.gitignore +5 -3
- data/tracks/swift/.travis.yml +8 -1
- data/tracks/swift/Package.swift +70 -11
- data/tracks/swift/exercises/atbash-cipher/Package.swift +1 -1
- data/tracks/swift/exercises/atbash-cipher/Sources/{Atbash.swift → AtbashCipher.swift} +0 -0
- data/tracks/swift/exercises/atbash-cipher/Sources/{AtbashExample.swift → AtbashCipherExample.swift} +1 -1
- data/tracks/swift/exercises/atbash-cipher/Tests/{AtbashTests/AtbashTests.swift → AtbashCipherTests/AtbashCipherTests.swift} +11 -11
- data/tracks/swift/exercises/atbash-cipher/Tests/LinuxMain.swift +2 -2
- data/tracks/swift/exercises/custom-set/Sources/CustomSetExample.swift +6 -2
- data/tracks/swift/exercises/poker/Sources/PokerExample.swift +2 -2
- metadata +49 -14
- data/tracks/clojure/docs/ABOUT.org +0 -24
- data/tracks/clojure/docs/INSTALLATION.org +0 -26
- data/tracks/clojure/docs/LEARNING.org +0 -35
- data/tracks/clojure/docs/RESOURCES.org +0 -9
- data/tracks/swift/.swift-version +0 -1
- data/tracks/swift/allProjects.xcworkspace.source/contents.xcworkspacedata +0 -4
- data/tracks/swift/allProjects.xcworkspace.source/xcshareddata/xcschemes/AllTest.xcscheme +0 -46
- data/tracks/swift/allProjectsPopulateWorkspace.sh +0 -35
data/tracks/perl6/config.json
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
def hello(
|
1
|
+
def hello():
|
2
2
|
pass
|
data/tracks/reasonml/.gitignore
CHANGED
data/tracks/reasonml/Makefile
CHANGED
@@ -9,19 +9,22 @@ OUTDIR ?= "tmp"
|
|
9
9
|
|
10
10
|
# language specific config (tweakable per language)
|
11
11
|
FILEEXT := "re"
|
12
|
+
SIGFILEEXT := "rei"
|
12
13
|
EXAMPLE := "Example.$(FILEEXT)"
|
13
14
|
SRCFILE := "$(shell echo $(EXERCISE) | sed -r 's/(^|-)([a-z])/\U\2/g')"
|
14
15
|
TSTFILE := "$(SRCFILE)_test.$(FILEEXT)"
|
16
|
+
SIGFILE := "$(SRCFILE).$(SIGFILEEXT)"
|
15
17
|
# Any additional arguments, such as -p for pretty output and others
|
16
18
|
ARGS ?= ""
|
17
19
|
|
18
|
-
# copy example and test
|
20
|
+
# copy example, interface and test files for single exercise to OUTDIR
|
19
21
|
# Rename Example.re to ExerciseName.re in the process
|
20
22
|
copy-exercise:
|
21
|
-
@cp exercises/$(EXERCISE)/__tests__/$(TSTFILE) $(OUTDIR)/__tests__/
|
22
23
|
@cp exercises/$(EXERCISE)/src/$(EXAMPLE) $(OUTDIR)/src/$(SRCFILE).$(FILEEXT)
|
24
|
+
@cp exercises/$(EXERCISE)/src/$(SIGFILE) $(OUTDIR)/src/
|
25
|
+
@cp exercises/$(EXERCISE)/__tests__/$(TSTFILE) $(OUTDIR)/__tests__/
|
23
26
|
|
24
|
-
# copy
|
27
|
+
# copy source files for all exercises to OUTDIR - easier to compile from there
|
25
28
|
copy-all-exercises:
|
26
29
|
@echo "Copying files..."
|
27
30
|
@mkdir -p $(OUTDIR)/src
|
data/tracks/reasonml/config.json
CHANGED
@@ -102,6 +102,16 @@
|
|
102
102
|
"list_map_function"
|
103
103
|
]
|
104
104
|
},
|
105
|
+
{
|
106
|
+
"slug": "pangram",
|
107
|
+
"uuid": "dddf877a-a8d4-45d7-8543-882c08bad2e8",
|
108
|
+
"core": false,
|
109
|
+
"unlocked_by": null,
|
110
|
+
"difficulty": 3,
|
111
|
+
"topics": [
|
112
|
+
"strings"
|
113
|
+
]
|
114
|
+
},
|
105
115
|
{
|
106
116
|
"slug": "binary-search",
|
107
117
|
"uuid": "eb635d37-a70b-47b2-883b-8ec9ca6098ef",
|
@@ -135,6 +145,17 @@
|
|
135
145
|
"recursion",
|
136
146
|
"dynamic_programming"
|
137
147
|
]
|
148
|
+
},
|
149
|
+
{
|
150
|
+
"slug": "phone-number",
|
151
|
+
"uuid": "2721c31b-773e-43c5-93ab-f704d62e5cde",
|
152
|
+
"core": false,
|
153
|
+
"unlocked_by": null,
|
154
|
+
"difficulty": 3,
|
155
|
+
"topics": [
|
156
|
+
"strings",
|
157
|
+
"regular_expressions"
|
158
|
+
]
|
138
159
|
}
|
139
160
|
]
|
140
161
|
}
|
@@ -0,0 +1 @@
|
|
1
|
+
let anagrams: (string, list(string)) => list(string);
|
@@ -1,26 +1,24 @@
|
|
1
|
-
let stringToCharArray =
|
1
|
+
let stringToCharArray = s => {
|
2
2
|
let len = String.length(s);
|
3
3
|
Array.init(len, n => s.[n]);
|
4
|
-
}
|
4
|
+
};
|
5
5
|
|
6
|
-
let isAnagram = (base, word) =>
|
7
|
-
if(String.length(base) != String.length(word)) {
|
8
|
-
false
|
6
|
+
let isAnagram = (base, word) =>
|
7
|
+
if (String.length(base) != String.length(word)) {
|
8
|
+
false;
|
9
9
|
} else {
|
10
10
|
let base = String.lowercase(base);
|
11
11
|
let word = String.lowercase(word);
|
12
|
-
if(base == word) {
|
13
|
-
false
|
12
|
+
if (base == word) {
|
13
|
+
false;
|
14
14
|
} else {
|
15
15
|
let base = stringToCharArray(base);
|
16
16
|
Array.sort(Char.compare, base);
|
17
17
|
let word = stringToCharArray(word);
|
18
18
|
Array.sort(Char.compare, word);
|
19
19
|
base == word;
|
20
|
-
}
|
21
|
-
}
|
22
|
-
};
|
20
|
+
};
|
21
|
+
};
|
23
22
|
|
24
|
-
let anagrams = (base, candidates) =>
|
23
|
+
let anagrams = (base, candidates) =>
|
25
24
|
List.filter(isAnagram(base), candidates);
|
26
|
-
};
|
@@ -0,0 +1 @@
|
|
1
|
+
let find: (array(int), int) => option(int);
|
@@ -0,0 +1 @@
|
|
1
|
+
let hey: string => string;
|
@@ -1,31 +1,32 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
type coins = list(int);
|
2
|
+
|
3
|
+
let intCompare = (n1: int, n2: int) =>
|
4
|
+
if (n1 == n2) {
|
5
|
+
0;
|
6
|
+
} else if (n1 > n2) {
|
7
|
+
1;
|
6
8
|
} else {
|
7
|
-
-1
|
8
|
-
}
|
9
|
-
};
|
9
|
+
(-1);
|
10
|
+
};
|
10
11
|
|
11
12
|
let findSmallestCoinsListMeetingTarget =
|
12
|
-
(cache: array(option(
|
13
|
+
(cache: array(option(coins)), coins, target: int)
|
13
14
|
: option(list(int)) => {
|
14
|
-
let findCoinsMeetingTargetMinusCoin =
|
15
|
+
let findCoinsMeetingTargetMinusCoin = coin =>
|
15
16
|
if (target == coin) {
|
16
17
|
Some([coin]);
|
17
18
|
} else {
|
18
|
-
Belt.Option.map(cache[target - coin],
|
19
|
+
Belt.Option.map(cache[target - coin], cs => [coin, ...cs]);
|
19
20
|
};
|
20
|
-
List.filter(
|
21
|
+
List.filter(x => x <= target, coins)
|
21
22
|
|> List.map(findCoinsMeetingTargetMinusCoin)
|
22
|
-
|> Belt.List.keepMap(_,
|
23
|
+
|> Belt.List.keepMap(_, x => x)
|
23
24
|
|> List.sort((xs, ys) => intCompare(List.length(xs), List.length(ys)))
|
24
25
|
|> Belt.List.head;
|
25
26
|
};
|
26
27
|
|
27
|
-
let makeChange = (target: int, coins
|
28
|
-
switch(target) {
|
28
|
+
let makeChange = (target: int, coins) : option(coins) =>
|
29
|
+
switch (target) {
|
29
30
|
| 0 => Some([])
|
30
31
|
| _ when target < 0 => None
|
31
32
|
| _ =>
|
@@ -0,0 +1 @@
|
|
1
|
+
let hello: unit => string;
|
@@ -0,0 +1 @@
|
|
1
|
+
let isLeapYear: int => bool;
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Pangram
|
2
|
+
|
3
|
+
Determine if a sentence is a pangram. A pangram (Greek: παν γράμμα, pan gramma,
|
4
|
+
"every letter") is a sentence using every letter of the alphabet at least once.
|
5
|
+
The best known English pangram is:
|
6
|
+
> The quick brown fox jumps over the lazy dog.
|
7
|
+
|
8
|
+
The alphabet used consists of ASCII letters `a` to `z`, inclusive, and is case
|
9
|
+
insensitive. Input will not contain non-ASCII symbols.
|
10
|
+
|
11
|
+
# Build + Watch
|
12
|
+
|
13
|
+
```
|
14
|
+
npm start
|
15
|
+
```
|
16
|
+
|
17
|
+
# Test + Watch
|
18
|
+
|
19
|
+
```
|
20
|
+
npm test
|
21
|
+
```
|
@@ -0,0 +1,36 @@
|
|
1
|
+
open Jest;
|
2
|
+
open Expect;
|
3
|
+
open Pangram;
|
4
|
+
|
5
|
+
describe("Pangram", () => {
|
6
|
+
test("sentence empty", () =>
|
7
|
+
expect(isPangram("")) |> toEqual(false)
|
8
|
+
);
|
9
|
+
test("recognizes a perfect lower case pangram", () =>
|
10
|
+
expect(isPangram("abcdefghijklmnopqrstuvwxyz")) |> toEqual(true)
|
11
|
+
);
|
12
|
+
test("pangram with only lower case", () =>
|
13
|
+
expect(isPangram("the quick brown fox jumps over the lazy dog")) |> toEqual(true)
|
14
|
+
);
|
15
|
+
test("missing character 'x'", () =>
|
16
|
+
expect(isPangram("a quick movement of the enemy will jeopardize five gunboats")) |> toEqual(false)
|
17
|
+
);
|
18
|
+
test("another missing character, e.g. 'h'", () =>
|
19
|
+
expect(isPangram("five boxing wizards jump quickly at it")) |> toEqual(false)
|
20
|
+
);
|
21
|
+
test("pangram with underscores", () =>
|
22
|
+
expect(isPangram("the_quick_brown_fox_jumps_over_the_lazy_dog")) |> toEqual(true)
|
23
|
+
);
|
24
|
+
test("pangram with numbers", () =>
|
25
|
+
expect(isPangram("the 1 quick brown fox jumps over the 2 lazy dogs")) |> toEqual(true)
|
26
|
+
);
|
27
|
+
test("missing letters replaced by numbers", () =>
|
28
|
+
expect(isPangram("7h3 qu1ck brown fox jumps ov3r 7h3 lazy dog")) |> toEqual(false)
|
29
|
+
);
|
30
|
+
test("pangram with mixed case and punctuation", () =>
|
31
|
+
expect(isPangram("\"Five quacking Zephyrs jolt my wax bed.\"")) |> toEqual(true)
|
32
|
+
);
|
33
|
+
test("upper and lower case versions of the same character should not be counted separately", () =>
|
34
|
+
expect(isPangram("the quick brown fox jumps over with lazy FX")) |> toEqual(false)
|
35
|
+
);
|
36
|
+
});
|
@@ -0,0 +1,30 @@
|
|
1
|
+
// This is the configuration file used by BuckleScript's build system bsb. Its documentation lives here: http://bucklescript.github.io/bucklescript/docson/#build-schema.json
|
2
|
+
// BuckleScript comes with its own parser for bsconfig.json, which is normal JSON, with the extra support of comments and trailing commas.
|
3
|
+
{
|
4
|
+
"name": "pangram",
|
5
|
+
"version": "0.1.0",
|
6
|
+
"sources": [
|
7
|
+
{
|
8
|
+
"dir" : "src",
|
9
|
+
"subdirs" : true
|
10
|
+
},
|
11
|
+
{
|
12
|
+
"dir": "__tests__",
|
13
|
+
"type": "dev"
|
14
|
+
}
|
15
|
+
],
|
16
|
+
"package-specs": {
|
17
|
+
"module": "commonjs",
|
18
|
+
"in-source": true
|
19
|
+
},
|
20
|
+
"suffix": ".bs.js",
|
21
|
+
"bs-dependencies": [
|
22
|
+
// add your dependencies here. You'd usually install them normally through `npm install my-dependency`. If my-dependency has a bsconfig.json too, then everything will work seamlessly.
|
23
|
+
],
|
24
|
+
"bs-dev-dependencies": ["@glennsl/bs-jest"],
|
25
|
+
"warnings": {
|
26
|
+
"error" : "+101"
|
27
|
+
},
|
28
|
+
"namespace": true,
|
29
|
+
"refmt": 3
|
30
|
+
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
{
|
2
|
+
"name": "pangram",
|
3
|
+
"version": "0.1.0",
|
4
|
+
"scripts": {
|
5
|
+
"build": "bsb -make-world",
|
6
|
+
"start": "bsb -make-world -w",
|
7
|
+
"clean": "bsb -clean-world",
|
8
|
+
"test": "jest --watchAll",
|
9
|
+
"test:ci": "jest --ci --bail --no-cache"
|
10
|
+
},
|
11
|
+
"keywords": [
|
12
|
+
"BuckleScript"
|
13
|
+
],
|
14
|
+
"author": "",
|
15
|
+
"license": "MIT",
|
16
|
+
"devDependencies": {
|
17
|
+
"@glennsl/bs-jest": "^0.4.2",
|
18
|
+
"bs-platform": "^3.1.5"
|
19
|
+
}
|
20
|
+
}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
exception Finished(int);
|
2
|
+
|
3
|
+
let rec stringFold = (s: string, init: 'a, step: ('a, char) => 'a): 'a => {
|
4
|
+
switch(String.length(s)) {
|
5
|
+
| 0 => init;
|
6
|
+
| _ => {
|
7
|
+
let tail = String.sub(s, 1, String.length(s) - 1);
|
8
|
+
let next = step(init, s.[0]);
|
9
|
+
stringFold(tail, next, step);
|
10
|
+
}
|
11
|
+
}
|
12
|
+
};
|
13
|
+
|
14
|
+
let isUppercaseAlpha = (ch) => Char.code(ch) >= 65 && Char.code(ch) <= 90;
|
15
|
+
|
16
|
+
let isPangram = (s: string) => {
|
17
|
+
let alphabetBits = 1 lsl 26 - 1;
|
18
|
+
let updateBits = (b, ch) => {
|
19
|
+
let updated = {
|
20
|
+
let ch = Char.uppercase(ch);
|
21
|
+
if (isUppercaseAlpha(ch)) {
|
22
|
+
b lor 1 lsl (Char.code(ch) - Char.code('A'));
|
23
|
+
} else {
|
24
|
+
b;
|
25
|
+
};
|
26
|
+
};
|
27
|
+
if (updated == alphabetBits) {
|
28
|
+
raise(Finished(alphabetBits));
|
29
|
+
} else {
|
30
|
+
updated;
|
31
|
+
};
|
32
|
+
};
|
33
|
+
try (stringFold(s, 0, updateBits) == alphabetBits) {
|
34
|
+
| Finished(bitSet) => bitSet == alphabetBits
|
35
|
+
};
|
36
|
+
};
|
@@ -0,0 +1 @@
|
|
1
|
+
let isPangram: string => bool;
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# Phone Number
|
2
|
+
Clean up user-entered phone numbers so that they can be sent SMS messages.
|
3
|
+
|
4
|
+
The **North American Numbering Plan (NANP)** is a telephone numbering system used by many countries in North America like the United States, Canada or Bermuda. All NANP-countries share the same international country code: `1`.
|
5
|
+
|
6
|
+
NANP numbers are ten-digit numbers consisting of a three-digit Numbering Plan Area code, commonly known as *area code*, followed by a seven-digit local number. The first three digits of the local number represent the *exchange code*, followed by the unique four-digit number which is the *subscriber number*.
|
7
|
+
|
8
|
+
The format is usually represented as
|
9
|
+
|
10
|
+
```text
|
11
|
+
(NXX)-NXX-XXXX
|
12
|
+
```
|
13
|
+
|
14
|
+
where `N` is any digit from 2 through 9 and `X` is any digit from 0 through 9.
|
15
|
+
|
16
|
+
Your task is to clean up differently formatted telephone numbers by removing punctuation and the country code (1) if present.
|
17
|
+
|
18
|
+
For example, the inputs
|
19
|
+
- `+1 (613)-995-0253`
|
20
|
+
- `613-995-0253`
|
21
|
+
- `1 613 995 0253`
|
22
|
+
- `613.995.0253`
|
23
|
+
|
24
|
+
should all produce the output
|
25
|
+
|
26
|
+
`6139950253`
|
27
|
+
|
28
|
+
**Note:** As this exercise only deals with telephone numbers used in NANP-countries, only 1 is considered a valid country code.
|
29
|
+
|
30
|
+
# Build
|
31
|
+
```
|
32
|
+
npm run build
|
33
|
+
```
|
34
|
+
|
35
|
+
# Build + Watch
|
36
|
+
|
37
|
+
```
|
38
|
+
npm run start
|
39
|
+
```
|
40
|
+
|
41
|
+
|
42
|
+
# Editor
|
43
|
+
If you use `vscode`, Press `Windows + Shift + B` it will build automatically
|
@@ -0,0 +1,48 @@
|
|
1
|
+
open Jest;
|
2
|
+
open Expect;
|
3
|
+
open PhoneNumber;
|
4
|
+
|
5
|
+
describe("PhoneNumber", () => {
|
6
|
+
test("cleans the number", () =>
|
7
|
+
expect(phoneNumber("(223) 456-7890")) |> toEqual(Some("2234567890"))
|
8
|
+
);
|
9
|
+
test("cleans numbers with dots", () =>
|
10
|
+
expect(phoneNumber("223.456.7890")) |> toEqual(Some("2234567890"))
|
11
|
+
);
|
12
|
+
test("cleans numbers with multiple spaces", () =>
|
13
|
+
expect(phoneNumber("223 456 7890 ")) |> toEqual(Some("2234567890"))
|
14
|
+
);
|
15
|
+
test("invalid when 9 digits", () =>
|
16
|
+
expect(phoneNumber("123456789")) |> toEqual(None)
|
17
|
+
);
|
18
|
+
test("invalid when 11 digits does not start with a 1", () =>
|
19
|
+
expect(phoneNumber("22234567890")) |> toEqual(None)
|
20
|
+
);
|
21
|
+
test("valid when 11 digits and starting with 1", () =>
|
22
|
+
expect(phoneNumber("12234567890")) |> toEqual(Some("2234567890"))
|
23
|
+
);
|
24
|
+
test("valid when 11 digits and starting with 1 even with punctuation", () =>
|
25
|
+
expect(phoneNumber("+1 (223) 456-7890")) |> toEqual(Some("2234567890"))
|
26
|
+
);
|
27
|
+
test("invalid when more than 11 digits", () =>
|
28
|
+
expect(phoneNumber("321234567890")) |> toEqual(None)
|
29
|
+
);
|
30
|
+
test("invalid with letters", () =>
|
31
|
+
expect(phoneNumber("123-abc-7890")) |> toEqual(None)
|
32
|
+
);
|
33
|
+
test("invalid with punctuations", () =>
|
34
|
+
expect(phoneNumber("123-@:!-7890")) |> toEqual(None)
|
35
|
+
);
|
36
|
+
test("invalid if area code starts with 0", () =>
|
37
|
+
expect(phoneNumber("(023) 456-7890")) |> toEqual(None)
|
38
|
+
);
|
39
|
+
test("invalid if area code starts with 1", () =>
|
40
|
+
expect(phoneNumber("(123) 456-7890")) |> toEqual(None)
|
41
|
+
);
|
42
|
+
test("invalid if exchange code starts with 0", () =>
|
43
|
+
expect(phoneNumber("(123) 056-7890")) |> toEqual(None)
|
44
|
+
);
|
45
|
+
test("invalid if exchange code starts with 1", () =>
|
46
|
+
expect(phoneNumber("(123) 156-7890")) |> toEqual(None)
|
47
|
+
);
|
48
|
+
});
|