trackler 2.1.0.23 → 2.1.0.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/tracks/ceylon/LICENSE +2 -2
  4. data/tracks/ceylon/README.md +0 -5
  5. data/tracks/ecmascript/.editorconfig +7 -0
  6. data/tracks/ecmascript/Makefile +8 -0
  7. data/tracks/ecmascript/bin/md5-hash +21 -0
  8. data/tracks/ecmascript/exercises/connect/package.json +3 -3
  9. data/tracks/elixir/exercises/atbash-cipher/{atbash.exs → atbash_cipher.exs} +4 -0
  10. data/tracks/elixir/exercises/atbash-cipher/atbash_cipher_test.exs +29 -1
  11. data/tracks/elixir/exercises/atbash-cipher/example.exs +12 -6
  12. data/tracks/elixir/exercises/phone-number/example.exs +71 -29
  13. data/tracks/elixir/exercises/phone-number/phone_number.exs +22 -10
  14. data/tracks/elixir/exercises/phone-number/phone_number_test.exs +37 -12
  15. data/tracks/elm/.github/stale.yml +0 -0
  16. data/tracks/elm/.gitignore +1 -0
  17. data/tracks/elm/.travis.yml +20 -1
  18. data/tracks/elm/README.md +9 -20
  19. data/tracks/elm/bin/build.sh +15 -18
  20. data/tracks/elm/bin/install-elm-format +1 -1
  21. data/tracks/elm/config.json +172 -167
  22. data/tracks/elm/exercises/accumulate/elm-package.json +1 -3
  23. data/tracks/elm/exercises/accumulate/package.json +3 -3
  24. data/tracks/elm/exercises/accumulate/{Tests.elm → tests/Tests.elm} +1 -11
  25. data/tracks/elm/exercises/accumulate/tests/elm-package.json +16 -0
  26. data/tracks/elm/exercises/allergies/elm-package.json +2 -3
  27. data/tracks/elm/exercises/allergies/package.json +3 -3
  28. data/tracks/elm/exercises/allergies/{Tests.elm → tests/Tests.elm} +2 -12
  29. data/tracks/elm/exercises/allergies/tests/elm-package.json +16 -0
  30. data/tracks/elm/exercises/anagram/elm-package.json +2 -3
  31. data/tracks/elm/exercises/anagram/package.json +3 -3
  32. data/tracks/elm/exercises/anagram/{Tests.elm → tests/Tests.elm} +4 -14
  33. data/tracks/elm/exercises/anagram/tests/elm-package.json +16 -0
  34. data/tracks/elm/exercises/atbash-cipher/elm-package.json +2 -3
  35. data/tracks/elm/exercises/atbash-cipher/package.json +3 -3
  36. data/tracks/elm/exercises/atbash-cipher/{Tests.elm → tests/Tests.elm} +1 -11
  37. data/tracks/elm/exercises/atbash-cipher/tests/elm-package.json +16 -0
  38. data/tracks/elm/exercises/bob/elm-package.json +2 -3
  39. data/tracks/elm/exercises/bob/package.json +3 -3
  40. data/tracks/elm/exercises/bob/{Tests.elm → tests/Tests.elm} +1 -11
  41. data/tracks/elm/exercises/bob/tests/elm-package.json +16 -0
  42. data/tracks/elm/exercises/difference-of-squares/elm-package.json +2 -3
  43. data/tracks/elm/exercises/difference-of-squares/package.json +3 -3
  44. data/tracks/elm/exercises/difference-of-squares/{Tests.elm → tests/Tests.elm} +1 -11
  45. data/tracks/elm/exercises/difference-of-squares/tests/elm-package.json +16 -0
  46. data/tracks/elm/exercises/gigasecond/elm-package.json +2 -3
  47. data/tracks/elm/exercises/gigasecond/package.json +3 -3
  48. data/tracks/elm/exercises/gigasecond/{Tests.elm → tests/Tests.elm} +1 -11
  49. data/tracks/elm/exercises/gigasecond/tests/elm-package.json +16 -0
  50. data/tracks/elm/exercises/grade-school/elm-package.json +2 -3
  51. data/tracks/elm/exercises/grade-school/package.json +3 -3
  52. data/tracks/elm/exercises/grade-school/{Tests.elm → tests/Tests.elm} +1 -11
  53. data/tracks/elm/exercises/grade-school/tests/elm-package.json +16 -0
  54. data/tracks/elm/exercises/grains/Grains.elm +2 -0
  55. data/tracks/elm/exercises/grains/Grains.example.elm +9 -0
  56. data/tracks/elm/exercises/grains/elm-package.json +14 -0
  57. data/tracks/elm/exercises/grains/package.json +13 -0
  58. data/tracks/elm/exercises/grains/tests/Tests.elm +38 -0
  59. data/tracks/elm/exercises/grains/tests/elm-package.json +16 -0
  60. data/tracks/elm/exercises/hamming/elm-package.json +2 -3
  61. data/tracks/elm/exercises/hamming/package.json +3 -3
  62. data/tracks/elm/exercises/hamming/{Tests.elm → tests/Tests.elm} +1 -11
  63. data/tracks/elm/exercises/hamming/tests/elm-package.json +16 -0
  64. data/tracks/elm/exercises/hello-world/elm-package.json +2 -3
  65. data/tracks/elm/exercises/hello-world/package.json +3 -3
  66. data/tracks/elm/exercises/hello-world/{Tests.elm → tests/Tests.elm} +1 -11
  67. data/tracks/elm/exercises/hello-world/tests/elm-package.json +16 -0
  68. data/tracks/elm/exercises/largest-series-product/elm-package.json +2 -3
  69. data/tracks/elm/exercises/largest-series-product/package.json +3 -3
  70. data/tracks/elm/exercises/largest-series-product/{Tests.elm → tests/Tests.elm} +1 -11
  71. data/tracks/elm/exercises/largest-series-product/tests/elm-package.json +16 -0
  72. data/tracks/elm/exercises/leap/elm-package.json +2 -3
  73. data/tracks/elm/exercises/leap/package.json +3 -3
  74. data/tracks/elm/exercises/leap/{Tests.elm → tests/Tests.elm} +1 -11
  75. data/tracks/elm/exercises/leap/tests/elm-package.json +16 -0
  76. data/tracks/elm/exercises/list-ops/elm-package.json +2 -3
  77. data/tracks/elm/exercises/list-ops/package.json +3 -3
  78. data/tracks/elm/exercises/list-ops/{Tests.elm → tests/Tests.elm} +1 -11
  79. data/tracks/elm/exercises/list-ops/tests/elm-package.json +16 -0
  80. data/tracks/elm/exercises/nucleotide-count/elm-package.json +2 -3
  81. data/tracks/elm/exercises/nucleotide-count/package.json +3 -3
  82. data/tracks/elm/exercises/nucleotide-count/{Tests.elm → tests/Tests.elm} +1 -11
  83. data/tracks/elm/exercises/nucleotide-count/tests/elm-package.json +16 -0
  84. data/tracks/elm/exercises/pangram/elm-package.json +2 -3
  85. data/tracks/elm/exercises/pangram/package.json +3 -3
  86. data/tracks/elm/exercises/pangram/{Tests.elm → tests/Tests.elm} +1 -11
  87. data/tracks/elm/exercises/pangram/tests/elm-package.json +16 -0
  88. data/tracks/elm/exercises/phone-number/elm-package.json +2 -3
  89. data/tracks/elm/exercises/phone-number/package.json +3 -3
  90. data/tracks/elm/exercises/phone-number/{Tests.elm → tests/Tests.elm} +1 -11
  91. data/tracks/elm/exercises/phone-number/tests/elm-package.json +16 -0
  92. data/tracks/elm/exercises/raindrops/elm-package.json +2 -3
  93. data/tracks/elm/exercises/raindrops/package.json +3 -3
  94. data/tracks/elm/exercises/raindrops/{Tests.elm → tests/Tests.elm} +1 -11
  95. data/tracks/elm/exercises/raindrops/tests/elm-package.json +16 -0
  96. data/tracks/elm/exercises/rna-transcription/elm-package.json +2 -3
  97. data/tracks/elm/exercises/rna-transcription/package.json +3 -3
  98. data/tracks/elm/exercises/rna-transcription/{Tests.elm → tests/Tests.elm} +1 -11
  99. data/tracks/elm/exercises/rna-transcription/tests/elm-package.json +16 -0
  100. data/tracks/elm/exercises/robot-simulator/elm-package.json +2 -3
  101. data/tracks/elm/exercises/robot-simulator/package.json +3 -3
  102. data/tracks/elm/exercises/robot-simulator/{Tests.elm → tests/Tests.elm} +1 -11
  103. data/tracks/elm/exercises/robot-simulator/tests/elm-package.json +16 -0
  104. data/tracks/elm/exercises/roman-numerals/elm-package.json +2 -3
  105. data/tracks/elm/exercises/roman-numerals/package.json +3 -3
  106. data/tracks/elm/exercises/roman-numerals/{Tests.elm → tests/Tests.elm} +1 -11
  107. data/tracks/elm/exercises/roman-numerals/tests/elm-package.json +16 -0
  108. data/tracks/elm/exercises/run-length-encoding/elm-package.json +2 -3
  109. data/tracks/elm/exercises/run-length-encoding/package.json +3 -3
  110. data/tracks/elm/exercises/run-length-encoding/{Tests.elm → tests/Tests.elm} +1 -11
  111. data/tracks/elm/exercises/run-length-encoding/tests/elm-package.json +16 -0
  112. data/tracks/elm/exercises/say/elm-package.json +2 -3
  113. data/tracks/elm/exercises/say/package.json +3 -3
  114. data/tracks/elm/exercises/say/{Tests.elm → tests/Tests.elm} +1 -11
  115. data/tracks/elm/exercises/say/tests/elm-package.json +16 -0
  116. data/tracks/elm/exercises/scrabble-score/elm-package.json +2 -3
  117. data/tracks/elm/exercises/scrabble-score/package.json +3 -3
  118. data/tracks/elm/exercises/scrabble-score/{Tests.elm → tests/Tests.elm} +1 -11
  119. data/tracks/elm/exercises/scrabble-score/tests/elm-package.json +16 -0
  120. data/tracks/elm/exercises/series/elm-package.json +2 -3
  121. data/tracks/elm/exercises/series/package.json +3 -3
  122. data/tracks/elm/exercises/series/{Tests.elm → tests/Tests.elm} +1 -11
  123. data/tracks/elm/exercises/series/tests/elm-package.json +16 -0
  124. data/tracks/elm/exercises/space-age/elm-package.json +2 -3
  125. data/tracks/elm/exercises/space-age/package.json +3 -3
  126. data/tracks/elm/exercises/space-age/{Tests.elm → tests/Tests.elm} +1 -11
  127. data/tracks/elm/exercises/space-age/tests/elm-package.json +16 -0
  128. data/tracks/elm/exercises/strain/elm-package.json +2 -3
  129. data/tracks/elm/exercises/strain/package.json +3 -3
  130. data/tracks/elm/exercises/strain/{Tests.elm → tests/Tests.elm} +1 -11
  131. data/tracks/elm/exercises/strain/tests/elm-package.json +16 -0
  132. data/tracks/elm/exercises/sublist/elm-package.json +2 -3
  133. data/tracks/elm/exercises/sublist/package.json +3 -3
  134. data/tracks/elm/exercises/sublist/{Tests.elm → tests/Tests.elm} +1 -11
  135. data/tracks/elm/exercises/sublist/tests/elm-package.json +16 -0
  136. data/tracks/elm/exercises/sum-of-multiples/elm-package.json +2 -3
  137. data/tracks/elm/exercises/sum-of-multiples/package.json +3 -3
  138. data/tracks/elm/exercises/sum-of-multiples/{Tests.elm → tests/Tests.elm} +1 -11
  139. data/tracks/elm/exercises/sum-of-multiples/tests/elm-package.json +16 -0
  140. data/tracks/elm/exercises/triangle/elm-package.json +2 -3
  141. data/tracks/elm/exercises/triangle/package.json +3 -3
  142. data/tracks/elm/exercises/triangle/{Tests.elm → tests/Tests.elm} +1 -11
  143. data/tracks/elm/exercises/triangle/tests/elm-package.json +16 -0
  144. data/tracks/elm/exercises/word-count/elm-package.json +2 -3
  145. data/tracks/elm/exercises/word-count/package.json +3 -3
  146. data/tracks/elm/exercises/word-count/{Tests.elm → tests/Tests.elm} +1 -11
  147. data/tracks/elm/exercises/word-count/tests/elm-package.json +16 -0
  148. data/tracks/elm/package.json +2 -2
  149. data/tracks/java/exercises/clock/HINT.md +3 -0
  150. data/tracks/java/exercises/clock/src/test/java/ClockAddTest.java +3 -0
  151. data/tracks/java/exercises/clock/src/test/java/ClockCreationTest.java +3 -0
  152. data/tracks/java/exercises/clock/src/test/java/ClockEqualTest.java +21 -17
  153. data/tracks/java/exercises/simple-linked-list/src/example/java/SimpleLinkedList.java +13 -13
  154. data/tracks/java/exercises/sublist/src/example/java/RelationshipComputer.java +1 -1
  155. data/tracks/java/exercises/sublist/src/main/java/RelationshipComputer.java +1 -1
  156. data/tracks/perl5/docs/TESTS.md +2 -2
  157. data/tracks/ruby/LICENSE +2 -2
  158. data/tracks/ruby/README.md +0 -5
  159. data/tracks/typescript/LICENSE +2 -2
  160. data/tracks/typescript/README.md +0 -5
  161. data/tracks/vimscript/README.md +1 -0
  162. data/tracks/vimscript/TRACK_HINTS.md +26 -1
  163. data/tracks/vimscript/config.json +15 -0
  164. data/tracks/vimscript/docs/ABOUT.md +1 -1
  165. data/tracks/vimscript/exercises/nucleotide-count/example.vim +18 -0
  166. data/tracks/vimscript/exercises/nucleotide-count/nucleotide_count.vader +38 -0
  167. data/tracks/vimscript/exercises/nucleotide-count/nucleotide_count.vim +16 -0
  168. data/tracks/vimscript/exercises/phone-number/example.vim +4 -0
  169. data/tracks/vimscript/exercises/phone-number/phone_number.vader +36 -0
  170. data/tracks/vimscript/exercises/phone-number/phone_number.vim +11 -0
  171. data/tracks/vimscript/exercises/roman-numerals/example.vim +29 -0
  172. data/tracks/vimscript/exercises/roman-numerals/roman_numerals.vader +53 -0
  173. data/tracks/vimscript/exercises/roman-numerals/roman_numerals.vim +14 -0
  174. metadata +81 -35
  175. data/tracks/elm/elm-package.json +0 -46
  176. data/tracks/elm/exercises/hello-world/yarn.lock +0 -1136
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a5a1f4bc1094d7cab6ba4f22a20e28874665bbb9
4
- data.tar.gz: 66cd048370d77f78ffdfef48b573fe302129e99a
3
+ metadata.gz: f709e319865d19a3edd18d5e20ff5f0fabcd438b
4
+ data.tar.gz: 9a9e667cc9ef535f6cb3fd28270f4a09f8a4acf9
5
5
  SHA512:
6
- metadata.gz: d0632cd9d571b3d6f1a604b748380d1b6ba4b3f6501970f4bac7c84361a0ef0ede21d9e0b118968e9daa04dde82fd11619a6edf9cee61e18f0234ea691b9935e
7
- data.tar.gz: 3cd5cc5489046c92b192e7955f0c0a18be47eecf3b3c88735a5ba483fc2675027d52f2fca726f51253cdec7fe3c30951e6a10e63baadb47c0d11caef7117db45
6
+ metadata.gz: ae5e1c6d35bcbe9879f021fe2130ecfa6cf7a365e40d56271c7b04d66fc367fa80c768ebfb8d466a8ef6208a1e26bbd5cc2a9e0a61d6d8763cd945392afd7ed7
7
+ data.tar.gz: 946c99dd215e5e1f0d74089a72280e33e7ce035743381878fd8f363c960e63685a1e52ed2307a94098fbb1f047229e127030bd97783e6e09d6235f64d0319218
@@ -1,3 +1,3 @@
1
1
  module Trackler
2
- VERSION = "2.1.0.23"
2
+ VERSION = "2.1.0.24"
3
3
  end
@@ -1,6 +1,6 @@
1
- The MIT License (MIT)
1
+ MIT License
2
2
 
3
- Copyright (c) 2016 Katrina Owen, _@kytrinyx.com
3
+ Copyright (c) 2017 Exercism, Inc
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -149,11 +149,6 @@ The Travis CI run would need to uncomment the cases as well (without uncommentin
149
149
 
150
150
  The current maintainer does not have a good solution to this, so ideas here are welcome.
151
151
 
152
- ## License
153
-
154
- The MIT License (MIT)
155
-
156
- Copyright (c) 2016 Katrina Owen, _@kytrinyx.com
157
152
 
158
153
  ### Ceylon icon
159
154
  The Ceylon icon is assumed to be owned by Red Hat, Inc. It appears to be released under the [Creative Commons Attribution Share-Alike 3.0 license](https://creativecommons.org/licenses/by-sa/3.0/). We have modified its colour scheme for use on Exercism.
@@ -17,6 +17,13 @@ trim_trailing_whitespace = true
17
17
  indent_style = space
18
18
  indent_size = 2
19
19
 
20
+ ###########################################################
21
+ ; bash
22
+ ###########################################################
23
+
24
+ [{bin/*,*.sh}]
25
+ indent_size = 4
26
+
20
27
  ###########################################################
21
28
  ; make
22
29
  ###########################################################
@@ -11,6 +11,13 @@ FILEEXT := "js"
11
11
  EXAMPLE := "example.$(FILEEXT)"
12
12
  TSTFILE := "$(subst _,-,$(ASSIGNMENT)).spec.$(FILEEXT)"
13
13
 
14
+ # package.json MD5 hash
15
+ SOURCE_PKG_MD5 ?= "`./bin/md5-hash ./package.json`"
16
+ PKG_FILES= $(shell find ./exercises/*/* -name package.json)
17
+
18
+ test-package-files:
19
+ @for pkg in $(PKG_FILES); do ! ./bin/md5-hash $$pkg | grep -qv $(SOURCE_PKG_MD5) || exit 1; done
20
+
14
21
  test-assignment:
15
22
  @cp package.json exercises/$(ASSIGNMENT)
16
23
  @echo "running tests for: $(ASSIGNMENT)"
@@ -24,4 +31,5 @@ test-assignment:
24
31
  @rmdir $(OUTDIR)
25
32
 
26
33
  test:
34
+ @$(MAKE) -s test-package-files
27
35
  @for assignment in $(ASSIGNMENTS); do ASSIGNMENT=$$assignment $(MAKE) -s test-assignment || exit 1; done
@@ -0,0 +1,21 @@
1
+ #!/bin/bash
2
+ #
3
+ # Calculates the MD5 hash of a given file. It uses hashing utilities powered by
4
+ # operating systems, but wraps them into a consistent interface.
5
+
6
+ OS=$(
7
+ case $(uname) in
8
+ (Darwin*) echo "mac";;
9
+ (Linux*) echo "linux";;
10
+ # TODO: implement MD5 hashing on Windows
11
+ # (Windows*) echo "windows";;
12
+ (*) echo "linux";;
13
+ esac
14
+ )
15
+
16
+ case $OS in
17
+ mac )
18
+ md5 -q $@;;
19
+ linux )
20
+ md5sum $@ | sed -E 's/([a-z0-9]{32}).+$/\1/';;
21
+ esac
@@ -9,10 +9,10 @@
9
9
  "url": "https://github.com/exercism/xecmascript"
10
10
  },
11
11
  "devDependencies": {
12
- "babel-jest": "^19.0.0",
13
- "babel-preset-env": "^1.3.3",
12
+ "babel-jest": "^20.0.1",
13
+ "babel-preset-env": "^1.4.0",
14
14
  "eslint": "^3.19.0",
15
- "jest": "^19.0.2"
15
+ "jest": "^20.0.1"
16
16
  },
17
17
  "jest": {
18
18
  "modulePathIgnorePatterns": [
@@ -10,4 +10,8 @@ defmodule Atbash do
10
10
  @spec encode(String.t) :: String.t
11
11
  def encode(plaintext) do
12
12
  end
13
+
14
+ @spec decode(String.t) :: String.t
15
+ def decode(cipher) do
16
+ end
13
17
  end
@@ -1,5 +1,5 @@
1
1
  if !System.get_env("EXERCISM_TEST_EXAMPLES") do
2
- Code.load_file("atbash.exs", __DIR__)
2
+ Code.load_file("atbash_cipher.exs", __DIR__)
3
3
  end
4
4
 
5
5
  ExUnit.start
@@ -49,4 +49,32 @@ defmodule AtbashTest do
49
49
  cipher = "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt"
50
50
  assert Atbash.encode(plaintext) == cipher
51
51
  end
52
+
53
+ @tag :pending
54
+ test "decode exercism" do
55
+ cipher = "vcvix rhn"
56
+ plaintext = "exercism"
57
+ assert Atbash.decode(cipher) == plaintext
58
+ end
59
+
60
+ @tag :pending
61
+ test "decode a sentence" do
62
+ cipher = "zmlyh gzxov rhlug vmzhg vkkrm thglm v"
63
+ plaintext = "anobstacleisoftenasteppingstone"
64
+ assert Atbash.decode(cipher) == plaintext
65
+ end
66
+
67
+ @tag :pending
68
+ test "decode numbers" do
69
+ cipher = "gvhgr mt123 gvhgr mt"
70
+ plaintext = "testing123testing"
71
+ assert Atbash.decode(cipher) == plaintext
72
+ end
73
+
74
+ @tag :pending
75
+ test "decode all the letters" do
76
+ cipher = "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt"
77
+ plaintext = "thequickbrownfoxjumpsoverthelazydog"
78
+ assert Atbash.decode(cipher) == plaintext
79
+ end
52
80
  end
@@ -9,19 +9,25 @@ defmodule Atbash do
9
9
  iex> Atbash.encode("completely insecure")
10
10
  "xlnko vgvob rmhvx fiv"
11
11
  """
12
+ @spec encode(String.t) :: String.t
12
13
  def encode(plaintext) do
13
- plaintext |> normalize |> cipher |> chunk |> Enum.join(" ")
14
+ plaintext |> normalize |> transpose |> chunk |> Enum.join(" ")
15
+ end
16
+
17
+ @spec decode(String.t) :: String.t
18
+ def decode(cipher) do
19
+ cipher |> normalize |> transpose
14
20
  end
15
21
 
16
22
  defp normalize(input) do
17
23
  Regex.replace(~r{\W}, String.downcase(input), "")
18
24
  end
19
25
 
20
- defp cipher(plaintext) do
21
- plaintext
22
- |> String.to_char_list
23
- |> Enum.map(&convert/1)
24
- |> List.to_string
26
+ defp transpose(text) do
27
+ text
28
+ |> String.to_char_list
29
+ |> Enum.map(&convert/1)
30
+ |> List.to_string
25
31
  end
26
32
 
27
33
  defp convert(character) do
@@ -2,55 +2,97 @@ defmodule Phone do
2
2
  @moduledoc """
3
3
  Utilities to work with phone numbers.
4
4
  """
5
+ @invalid "0000000000"
5
6
 
6
7
  @doc """
7
- Clean up a phone number.
8
+ Remove formatting from a phone number.
8
9
 
9
- Returns 0000000000 if the phone number is bad.
10
+ Returns "0000000000" if phone number is not valid
11
+ (10 digits or "1" followed by 10 digits)
12
+
13
+ ## Examples
14
+
15
+ iex> Phone.number("212-555-0100")
16
+ "2125550100"
17
+
18
+ iex> Phone.number("+1 (212) 555-0100")
19
+ "2125550100"
20
+
21
+ iex> Phone.number("+1 (212) 055-0100")
22
+ "0000000000"
23
+
24
+ iex> Phone.number("(212) 555-0100")
25
+ "2125550100"
26
+
27
+ iex> Phone.number("867.5309")
28
+ "0000000000"
10
29
  """
11
30
  @spec number(String.t) :: String.t
12
31
  def number(raw) do
13
32
  raw
14
- |> to_parts
15
- |> to_string
33
+ |> String.replace(~r/[\s+.()-]/, "") # remove decorations
34
+ |> valid?
35
+ |> (fn false -> @invalid; num -> String.replace(num, ~r/^1/, "") end).()
16
36
  end
17
37
 
18
- @spec to_parts(String.t) :: [String.t]
19
- defp to_parts(raw) do
20
- Regex.run(~r/^\D*?1?\D*?(\d{3})\D*(\d{3})\D*(\d{4})$/, raw, [capture: :all_but_first]) || ["000", "000", "0000"]
38
+ defp valid?(num) do
39
+ Regex.match?(~r/^1?(?:[2-9][0-9]{2}){2}\d{4}$/, num)
40
+ |> (fn true -> num; false -> false end).()
21
41
  end
22
42
 
23
43
  @doc """
24
- Get the area code of a phone number.
44
+ Extract the area code from a phone number
45
+
46
+ Returns the first three digits from a phone number,
47
+ ignoring long distance indicator
48
+
49
+ ## Examples
50
+
51
+ iex> Phone.area_code("212-555-0100")
52
+ "212"
53
+
54
+ iex> Phone.area_code("+1 (212) 555-0100")
55
+ "212"
56
+
57
+ iex> Phone.area_code("+1 (012) 555-0100")
58
+ "000"
25
59
 
26
- The area code is the first three digits of a cleaned up phone number.
60
+ iex> Phone.area_code("867.5309")
61
+ "000"
27
62
  """
28
63
  @spec area_code(String.t) :: String.t
29
- def area_code(str) do
30
- str
31
- |> to_parts
32
- |> List.first
64
+ def area_code(raw) do
65
+ raw
66
+ |> __MODULE__.number
67
+ |> String.slice(0, 3) # the first three digits are area_code
33
68
  end
34
69
 
35
- @spec prefix(String.t) :: String.t
36
- def prefix(str) do
37
- str
38
- |> to_parts
39
- |> Enum.at(1)
40
- end
70
+ @doc """
71
+ Pretty print a phone number
41
72
 
42
- @spec line(String.t) :: String.t
43
- def line(str) do
44
- str
45
- |> to_parts
46
- |> List.last
47
- end
73
+ Wraps the area code in parentheses and separates
74
+ exchange and subscriber number with a dash.
48
75
 
49
- @doc """
50
- Pretty print a phone number.
76
+ ## Examples
77
+
78
+ iex> Phone.pretty("212-555-0100")
79
+ "(212) 555-0100"
80
+
81
+ iex> Phone.pretty("212-155-0100")
82
+ "(000) 000-0000"
83
+
84
+ iex> Phone.pretty("+1 (303) 555-1212")
85
+ "(303) 555-1212"
86
+
87
+ iex> Phone.pretty("867.5309")
88
+ "(000) 000-0000"
51
89
  """
52
90
  @spec pretty(String.t) :: String.t
53
- def pretty(str) do
54
- "(#{area_code(str)}) #{prefix(str)}-#{line(str)}"
91
+ def pretty(raw) do
92
+ raw
93
+ |> __MODULE__.number
94
+ |> (fn <<area_code::binary-size(3), exchange_code::binary-size(3), rest::binary>> ->
95
+ "(#{area_code}) #{exchange_code}-#{rest}"
96
+ end).()
55
97
  end
56
98
  end
@@ -7,11 +7,17 @@ defmodule Phone do
7
7
 
8
8
  ## Examples
9
9
 
10
- iex> Phone.number("123-456-7890")
11
- "1234567890"
10
+ iex> Phone.number("212-555-0100")
11
+ "2125550100"
12
12
 
13
- iex> Phone.number("+1 (303) 555-1212")
14
- "3035551212"
13
+ iex> Phone.number("+1 (212) 555-0100")
14
+ "2125550100"
15
+
16
+ iex> Phone.number("+1 (212) 055-0100")
17
+ "0000000000"
18
+
19
+ iex> Phone.number("(212) 555-0100")
20
+ "2125550100"
15
21
 
16
22
  iex> Phone.number("867.5309")
17
23
  "0000000000"
@@ -28,11 +34,14 @@ defmodule Phone do
28
34
 
29
35
  ## Examples
30
36
 
31
- iex> Phone.area_code("123-456-7890")
32
- "123"
37
+ iex> Phone.area_code("212-555-0100")
38
+ "212"
33
39
 
34
- iex> Phone.area_code("+1 (303) 555-1212")
35
- "303"
40
+ iex> Phone.area_code("+1 (212) 555-0100")
41
+ "212"
42
+
43
+ iex> Phone.area_code("+1 (012) 555-0100")
44
+ "000"
36
45
 
37
46
  iex> Phone.area_code("867.5309")
38
47
  "000"
@@ -49,8 +58,11 @@ defmodule Phone do
49
58
 
50
59
  ## Examples
51
60
 
52
- iex> Phone.pretty("123-456-7890")
53
- "(123) 456-7890"
61
+ iex> Phone.pretty("212-555-0100")
62
+ "(212) 555-0100"
63
+
64
+ iex> Phone.pretty("212-155-0100")
65
+ "(000) 000-0000"
54
66
 
55
67
  iex> Phone.pretty("+1 (303) 555-1212")
56
68
  "(303) 555-1212"
@@ -9,56 +9,81 @@ defmodule PhoneTest do
9
9
  use ExUnit.Case
10
10
 
11
11
  test "cleans number" do
12
- assert Phone.number("(123) 456-7890") == "1234567890"
12
+ assert Phone.number("(212) 555-0100") == "2125550100"
13
13
  end
14
14
 
15
15
  @tag :pending
16
16
  test "cleans number with dots" do
17
- assert Phone.number("123.456.7890") == "1234567890"
17
+ assert Phone.number("212.555.0100") == "2125550100"
18
18
  end
19
19
 
20
20
  @tag :pending
21
21
  test "valid when 11 digits and first is 1" do
22
- assert Phone.number("11234567890") == "1234567890"
22
+ assert Phone.number("12125550100") == "2125550100"
23
23
  end
24
24
 
25
25
  @tag :pending
26
- test "invalid when 11 digits" do
27
- assert Phone.number("21234567890") == "0000000000"
26
+ test "valid when 11 digits and some decorations" do
27
+ assert Phone.number("+1 (212) 555-0100") == "2125550100"
28
+ end
29
+
30
+ @tag :pending
31
+ test "invalid when country calling code is not 1" do
32
+ assert Phone.number("22125550100") == "0000000000"
28
33
  end
29
34
 
30
35
  @tag :pending
31
36
  test "invalid when 9 digits" do
32
- assert Phone.number("123456789") == "0000000000"
37
+ assert Phone.number("212555010") == "0000000000"
33
38
  end
34
39
 
35
40
  @tag :pending
36
41
  test "invalid when proper number of digits but letters mixed in" do
37
- assert Phone.number("1a2a3a4a5a6a7a8a9a0a") == "0000000000"
42
+ assert Phone.number("2a1a2a5a5a5a0a1a0a0a") == "0000000000"
38
43
  end
39
44
 
40
45
  @tag :pending
41
46
  test "invalid with correct number of characters but some are letters" do
42
- assert Phone.number("1a2a3a4a5a") == "0000000000"
47
+ assert Phone.number("2a1a2a5a5a") == "0000000000"
48
+ end
49
+
50
+ @tag :pending
51
+ test "invalid when area code begins with 1" do
52
+ assert Phone.number("1125550100") == "0000000000"
53
+ end
54
+
55
+ @tag :pending
56
+ test "invalid when area code begins with 0" do
57
+ assert Phone.number("0125550100") == "0000000000"
58
+ end
59
+
60
+ @tag :pending
61
+ test "invalid when exchange code begins with 1" do
62
+ assert Phone.number("2121550100") == "0000000000"
63
+ end
64
+
65
+ @tag :pending
66
+ test "invalid when exchange code begins with 0" do
67
+ assert Phone.number("2120550100") == "0000000000"
43
68
  end
44
69
 
45
70
  @tag :pending
46
71
  test "area code" do
47
- assert Phone.area_code("1234567890") == "123"
72
+ assert Phone.area_code("2125550100") == "212"
48
73
  end
49
74
 
50
75
  @tag :pending
51
76
  test "area code with full US phone number" do
52
- assert Phone.area_code("11234567890") == "123"
77
+ assert Phone.area_code("12125550100") == "212"
53
78
  end
54
79
 
55
80
  @tag :pending
56
81
  test "pretty print" do
57
- assert Phone.pretty("1234567890") == "(123) 456-7890"
82
+ assert Phone.pretty("2125550100") == "(212) 555-0100"
58
83
  end
59
84
 
60
85
  @tag :pending
61
86
  test "pretty print with full US phone number" do
62
- assert Phone.pretty("11234567890") == "(123) 456-7890"
87
+ assert Phone.pretty("12125550100") == "(212) 555-0100"
63
88
  end
64
89
  end