trackler 2.0.0.5 → 2.0.0.6

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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/tracks/bash/docs/TESTS.md +1 -1
  4. data/tracks/bash/exercises/bob/bob_test.sh +2 -0
  5. data/tracks/bash/exercises/gigasecond/gigasecond_test.sh +2 -0
  6. data/tracks/bash/exercises/hamming/hamming_test.sh +2 -0
  7. data/tracks/bash/exercises/hello-world/hello_world_test.sh +2 -0
  8. data/tracks/bash/exercises/leap/leap_test.sh +2 -0
  9. data/tracks/bash/exercises/raindrops/raindrops_test.sh +2 -0
  10. data/tracks/bash/exercises/rna-transcription/rna_transcription_test.sh +2 -0
  11. data/tracks/c/bin/verify-indent +5 -1
  12. data/tracks/c/config.json +10 -1
  13. data/tracks/c/exercises/clock/src/clock.h +1 -1
  14. data/tracks/c/exercises/largest-series-product/test/test_largest_series_product.c +1 -1
  15. data/tracks/c/exercises/phone-number/src/example.c +4 -2
  16. data/tracks/c/exercises/roman-numerals/src/example.c +20 -21
  17. data/tracks/c/exercises/roman-numerals/src/example.h +1 -1
  18. data/tracks/c/exercises/roman-numerals/test/test_roman_numerals.c +1 -0
  19. data/tracks/c/exercises/sum-of-multiples/src/example.c +3 -1
  20. data/tracks/c/exercises/sum-of-multiples/src/example.h +3 -1
  21. data/tracks/c/exercises/sum-of-multiples/test/test_sum_of_multiples.c +44 -22
  22. data/tracks/c/exercises/word-count/makefile +16 -0
  23. data/tracks/c/exercises/word-count/src/example.c +65 -0
  24. data/tracks/c/exercises/word-count/src/word_count.h +22 -0
  25. data/tracks/c/exercises/word-count/test/test_word_count.c +372 -0
  26. data/tracks/c/exercises/word-count/test/vendor/unity.c +1300 -0
  27. data/tracks/c/exercises/word-count/test/vendor/unity.h +274 -0
  28. data/tracks/c/exercises/word-count/test/vendor/unity_internals.h +701 -0
  29. data/tracks/crystal/.gitignore +1 -0
  30. data/tracks/crystal/Makefile +6 -0
  31. data/tracks/crystal/README.md +25 -0
  32. data/tracks/crystal/config.json +10 -2
  33. data/tracks/crystal/exercises/acronym/spec/acronym_spec.cr +32 -0
  34. data/tracks/crystal/exercises/acronym/src/example.cr +7 -0
  35. data/tracks/crystal/exercises/hello-world/spec/hello_world_spec.cr +8 -10
  36. data/tracks/crystal/exercises/hello-world/src/example.cr +1 -1
  37. data/tracks/crystal/src/generator/exercises/acronym.cr +34 -0
  38. data/tracks/crystal/src/generator/exercises/exercise_generator.cr +39 -0
  39. data/tracks/crystal/src/generator/exercises/exercise_test_case.cr +8 -0
  40. data/tracks/crystal/src/generator/exercises/hello_world.cr +38 -0
  41. data/tracks/crystal/src/generator/exercises/templates/example.tt +10 -0
  42. data/tracks/crystal/src/generator/generate.cr +15 -0
  43. data/tracks/crystal/src/generator/spec/exercise_generator_spec.cr +27 -0
  44. data/tracks/crystal/src/generator/spec/exercise_test_case_spec.cr +23 -0
  45. data/tracks/elixir/exercises/space-age/space_age.exs +1 -1
  46. data/tracks/elm/config.json +5 -31
  47. data/tracks/elm/elm-package.json +1 -0
  48. data/tracks/elm/exercises/bob/BobTests.elm +1 -1
  49. data/tracks/elm/exercises/run-length-encoding/RunLengthEncoding.elm +5 -0
  50. data/tracks/elm/exercises/scrabble-score/ScrabbleScore.elm +1 -0
  51. data/tracks/elm/exercises/scrabble-score/ScrabbleScore.example +32 -0
  52. data/tracks/elm/exercises/scrabble-score/ScrabbleScoreTests.elm +43 -0
  53. data/tracks/elm/exercises/scrabble-score/elm-package.json +16 -0
  54. data/tracks/elm/exercises/scrabble-score/runtests.bat +1 -0
  55. data/tracks/elm/exercises/scrabble-score/runtests.sh +2 -0
  56. data/tracks/elm/exercises/sublist/Sublist.elm +5 -0
  57. data/tracks/fsharp/exercises/sum-of-multiples/SumOfMultiplesTest.fs +6 -1
  58. data/tracks/haskell/docs/LEARNING.md +11 -2
  59. data/tracks/haskell/exercises/list-ops/test/Tests.hs +2 -0
  60. data/tracks/java/config.json +13 -1
  61. data/tracks/java/exercises/etl/src/test/java/EtlTest.java +101 -55
  62. data/tracks/java/exercises/hello-world/TUTORIAL.md +1 -1
  63. data/tracks/java/exercises/largest-series-product/build.gradle +17 -0
  64. data/tracks/java/exercises/largest-series-product/src/example/java/LargestSeriesProductCalculator.java +56 -0
  65. data/tracks/java/exercises/largest-series-product/src/main/java/LargestSeriesProductCalculator.java +5 -0
  66. data/tracks/java/exercises/largest-series-product/src/test/java/LargestSeriesProductCalculatorTest.java +218 -0
  67. data/tracks/java/exercises/queen-attack/build.gradle +17 -0
  68. data/tracks/java/exercises/queen-attack/src/example/java/BoardCoordinate.java +39 -0
  69. data/tracks/java/exercises/queen-attack/src/example/java/QueenAttackCalculator.java +54 -0
  70. data/tracks/java/exercises/queen-attack/src/main/java/BoardCoordinate.java +5 -0
  71. data/tracks/java/exercises/queen-attack/src/main/java/QueenAttackCalculator.java +5 -0
  72. data/tracks/java/exercises/queen-attack/src/test/java/QueenAttackCalculatorTest.java +135 -0
  73. data/tracks/java/exercises/settings.gradle +2 -0
  74. data/tracks/ocaml/exercises/leap/test.ml +17 -6
  75. data/tracks/rust/_test/check-exercises.sh +5 -0
  76. data/tracks/swift/docs/TESTS.md +23 -3
  77. metadata +35 -2
@@ -16,3 +16,4 @@ bin/configlet
16
16
  bin/configlet.exe
17
17
  CHECKLIST
18
18
  tmp/
19
+ bin/generate
@@ -1,6 +1,7 @@
1
1
  ASSIGNMENT ?= ""
2
2
  IGNOREDIRS := "^(\.git|.crystal|docs|bin|img|script)$$"
3
3
  EXERCISESDIR ?= "exercises"
4
+ GENERATORDIR ?= "src/generator"
4
5
  ASSIGNMENTS = $(shell find exercises -maxdepth 1 -mindepth 1 -type d | cut -d'/' -f2 | sort | grep -Ev $(IGNOREDIRS))
5
6
 
6
7
  FILEEXT := "cr"
@@ -23,3 +24,8 @@ test-assignment:
23
24
 
24
25
  test:
25
26
  @for assignment in $(ASSIGNMENTS); do ASSIGNMENT=$$assignment $(MAKE) -s test-assignment || exit 1; done
27
+ @echo "running generator tests"
28
+ @cd $(GENERATORDIR) && crystal spec
29
+
30
+ build_generator:
31
+ @crystal build $(GENERATORDIR)/generate.$(FILEEXT) -o bin/generate
@@ -18,6 +18,31 @@ Run single assignments with:
18
18
  $ make test-assignment ASSIGNMENT=test-folder-name
19
19
  ```
20
20
 
21
+ ## The Test Generator
22
+
23
+ ### Creating a New Generator
24
+
25
+ Navigate to `src/generator/exercises` and create a new generator file (i.e. `hello_world.cr`).
26
+
27
+ This file should contain 2 classes:
28
+ * An exercise generator which must inherit from the ExerciseGenerator class.
29
+ * A test case class which inherits from ExerciseTestCase.
30
+
31
+ The x-common repo must reside at the same level as the developer's crystal directory, and must contain a canonical-data.json file for the given exercise.
32
+
33
+ ### Running the Generator
34
+
35
+ From within the xcrystal directory:
36
+ ```bash
37
+ $ crystal src/generator/generate.cr hello-world
38
+ ```
39
+
40
+ Or build a binary:
41
+ ```bash
42
+ $ make build_generator
43
+ $ bin/generate hello-world
44
+ ```
45
+
21
46
  ## Contributing Guide
22
47
 
23
48
  Please see the [contributing guide](https://github.com/exercism/x-api/blob/master/CONTRIBUTING.md#the-exercise-data)
@@ -19,7 +19,8 @@
19
19
  "roman-numerals",
20
20
  "atbash-cipher",
21
21
  "anagram",
22
- "react"
22
+ "react",
23
+ "acronym"
23
24
  ],
24
25
  "exercises": [
25
26
  {
@@ -111,6 +112,12 @@
111
112
  "difficulty": 1,
112
113
  "topics": [
113
114
  ]
115
+ },
116
+ {
117
+ "slug": "acronym",
118
+ "difficulty": 1,
119
+ "topics": [
120
+ ]
114
121
  }
115
122
  ],
116
123
  "deprecated": [
@@ -118,7 +125,8 @@
118
125
  "ignored": [
119
126
  "bin",
120
127
  "docs",
121
- "img"
128
+ "img",
129
+ "src"
122
130
  ],
123
131
  "foregone": [
124
132
  ]
@@ -0,0 +1,32 @@
1
+ require "spec"
2
+ require "../src/*"
3
+
4
+ describe "Acronym" do
5
+ it "tests basic" do
6
+ Acronym.abbreviate("Portable Network Graphics").should eq("PNG")
7
+ end
8
+
9
+ it "tests lowercase words" do
10
+ Acronym.abbreviate("Ruby on Rails").should eq("ROR")
11
+ end
12
+
13
+ it "tests camelcase" do
14
+ Acronym.abbreviate("HyperText Markup Language").should eq("HTML")
15
+ end
16
+
17
+ it "tests punctuation" do
18
+ Acronym.abbreviate("First In, First Out").should eq("FIFO")
19
+ end
20
+
21
+ it "tests all caps words" do
22
+ Acronym.abbreviate("PHP: Hypertext Preprocessor").should eq("PHP")
23
+ end
24
+
25
+ it "tests non-acronym all caps word" do
26
+ Acronym.abbreviate("GNU Image Manipulation Program").should eq("GIMP")
27
+ end
28
+
29
+ it "tests hyphenated" do
30
+ Acronym.abbreviate("Complementary metal-oxide semiconductor").should eq("CMOS")
31
+ end
32
+ end
@@ -0,0 +1,7 @@
1
+ class Acronym
2
+ def self.abbreviate(phrase)
3
+ phrase.scan(/[A-Z]+[a-z]*|[a-z]+/).map do |word|
4
+ word[0][0].upcase
5
+ end.join
6
+ end
7
+ end
@@ -2,17 +2,15 @@ require "spec"
2
2
  require "../src/*"
3
3
 
4
4
  describe "HelloWorld" do
5
- describe "#hello" do
6
- it "says hello with default 'World'" do
7
- HelloWorld.hello.should eq "Hello, World"
8
- end
5
+ it "tests no name" do
6
+ HelloWorld.hello.should eq("Hello, World!")
7
+ end
9
8
 
10
- pending "says hello with one name" do
11
- HelloWorld.hello("Max").should eq "Hello, Max"
12
- end
9
+ pending "tests sample name" do
10
+ HelloWorld.hello("Alice").should eq("Hello, Alice!")
11
+ end
13
12
 
14
- pending "says hello with another name" do
15
- HelloWorld.hello("Alice").should eq "Hello, Alice"
16
- end
13
+ pending "tests other sample name" do
14
+ HelloWorld.hello("Bob").should eq("Hello, Bob!")
17
15
  end
18
16
  end
@@ -1,5 +1,5 @@
1
1
  class HelloWorld
2
2
  def self.hello(name : String = "World")
3
- "Hello, #{name}"
3
+ "Hello, #{name}!"
4
4
  end
5
5
  end
@@ -0,0 +1,34 @@
1
+ require "./exercise_generator"
2
+ require "./exercise_test_case"
3
+
4
+ class AcronymGenerator < ExerciseGenerator
5
+ def exercise_name
6
+ "acronym"
7
+ end
8
+
9
+ def test_cases
10
+ JSON.parse(data)["abbreviate"]["cases"].map do |test_case|
11
+ AcronymTestCase.new(test_case)
12
+ end
13
+ end
14
+ end
15
+
16
+ class AcronymTestCase < ExerciseTestCase
17
+ private getter phrase : JSON::Any
18
+ private getter description : JSON::Any
19
+ private getter expected : JSON::Any
20
+
21
+ def initialize(test_case)
22
+ @phrase = test_case["phrase"]
23
+ @description = test_case["description"]
24
+ @expected = test_case["expected"]
25
+ end
26
+
27
+ def workload
28
+ "Acronym.abbreviate(\"#{phrase}\").should eq(\"#{expected}\")"
29
+ end
30
+
31
+ def test_name
32
+ description
33
+ end
34
+ end
@@ -0,0 +1,39 @@
1
+ require "ecr"
2
+ require "json"
3
+
4
+ abstract class ExerciseGenerator
5
+ METADATA_REPOSITORY = "x-common"
6
+
7
+ def self.generate
8
+ new.generate
9
+ end
10
+
11
+ def generate
12
+ File.write(test_file, to_s)
13
+ end
14
+
15
+ def describe_name
16
+ exercise_name.split('-').map(&.capitalize).join
17
+ end
18
+
19
+ abstract def exercise_name : String
20
+ abstract def test_cases : Array(ExerciseTestCase)
21
+
22
+ private def root
23
+ File.expand_path(File.join("..", "..", "..", ".."), __FILE__)
24
+ end
25
+
26
+ private def test_file
27
+ File.expand_path(File.join("exercises", exercise_name, "spec", "#{exercise_name.tr("-", "_")}_spec.cr"), root)
28
+ end
29
+
30
+ private def metadata_dir
31
+ File.expand_path(File.join("..", METADATA_REPOSITORY, "exercises", exercise_name), root)
32
+ end
33
+
34
+ private def data
35
+ File.read(File.join(metadata_dir, "canonical-data.json"))
36
+ end
37
+
38
+ ECR.def_to_s "#{__DIR__}/templates/example.tt"
39
+ end
@@ -0,0 +1,8 @@
1
+ abstract class ExerciseTestCase
2
+ abstract def workload
3
+ abstract def test_name
4
+
5
+ def pending?(index)
6
+ index == 0 ? "it" : "pending"
7
+ end
8
+ end
@@ -0,0 +1,38 @@
1
+ require "./exercise_generator"
2
+ require "./exercise_test_case"
3
+
4
+ class HelloWorldGenerator < ExerciseGenerator
5
+ def exercise_name
6
+ "hello-world"
7
+ end
8
+
9
+ def test_cases
10
+ JSON.parse(data)["cases"].map do |test_case|
11
+ HelloWorldTestCase.new(test_case)
12
+ end
13
+ end
14
+ end
15
+
16
+ class HelloWorldTestCase < ExerciseTestCase
17
+ private getter description : JSON::Any
18
+ private getter name : JSON::Any | Nil
19
+ private getter expected : JSON::Any
20
+
21
+ def initialize(test_case)
22
+ @description = test_case["description"]
23
+ @name = test_case["name"]?
24
+ @expected = test_case["expected"]
25
+ end
26
+
27
+ def workload
28
+ if name
29
+ "HelloWorld.hello(\"#{name}\").should eq(\"#{expected}\")"
30
+ else
31
+ "HelloWorld.hello.should eq(\"#{expected}\")"
32
+ end
33
+ end
34
+
35
+ def test_name
36
+ description
37
+ end
38
+ end
@@ -0,0 +1,10 @@
1
+ require "spec"
2
+ require "../src/*"
3
+
4
+ describe <%= "#{describe_name.inspect} do" %>
5
+ <% test_cases.each_with_index do |test_case, index| %>
6
+ <%= test_case.pending?(index) %> "tests <%= test_case.test_name %>" do
7
+ <%= test_case.workload %>
8
+ end
9
+ <% end -%>
10
+ end
@@ -0,0 +1,15 @@
1
+ require "./exercises/*"
2
+
3
+ if ARGV.empty?
4
+ STDERR.puts "Exercise name required!\n"
5
+ exit
6
+ end
7
+
8
+ exercise = ARGV[0]
9
+
10
+ klass = {{ExerciseGenerator.subclasses}}.find do |generator|
11
+ generator.to_s == "#{exercise.split('-').map(&.capitalize).join}Generator"
12
+ end
13
+
14
+ raise "Undefined Generator" unless klass
15
+ klass.generate
@@ -0,0 +1,27 @@
1
+ require "spec"
2
+ require "../exercises/exercise_generator"
3
+ require "../exercises/exercise_test_case"
4
+
5
+ class DummyGenerator < ExerciseGenerator
6
+ def exercise_name
7
+ "dummy"
8
+ end
9
+
10
+ def test_cases
11
+ [] of ExerciseTestCase
12
+ end
13
+ end
14
+
15
+ describe "ExerciseGenerator" do
16
+ describe "#describe_name" do
17
+ it "will return the name of the exercise in camel case" do
18
+ DummyGenerator.new.describe_name.should eq("Dummy")
19
+ end
20
+ end
21
+
22
+ describe "#to_s" do
23
+ it "will output the generator test file using the example.tt" do
24
+ DummyGenerator.new.to_s.should eq("require \"spec\"\nrequire \"../src/*\"\n\ndescribe \"Dummy\" do\nend\n")
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,23 @@
1
+ require "spec"
2
+ require "json"
3
+ require "../exercises/exercise_test_case"
4
+
5
+ class DummyTestCase < ExerciseTestCase
6
+ def workload; end
7
+
8
+ def test_name; end
9
+ end
10
+
11
+ describe "DummyTestCase" do
12
+ describe "#pending" do
13
+ it "outputs 'it' if the given integer is 0" do
14
+ dummy_test_case = DummyTestCase.new
15
+ dummy_test_case.pending?(0).should eq("it")
16
+ end
17
+
18
+ it "outputs 'pending' if the given integer is greater than 0" do
19
+ dummy_test_case = DummyTestCase.new
20
+ dummy_test_case.pending?(1).should eq("pending")
21
+ end
22
+ end
23
+ end
@@ -1,6 +1,6 @@
1
1
  defmodule SpaceAge do
2
2
  @type planet :: :mercury | :venus | :earth | :mars | :jupiter
3
- | :saturn | :neptune | :uranus
3
+ | :saturn | :uranus | :neptune
4
4
 
5
5
  @doc """
6
6
  Return the number of years a person that has lived for 'seconds' seconds is
@@ -3,37 +3,6 @@
3
3
  "language": "Elm",
4
4
  "repository": "https://github.com/exercism/xelm",
5
5
  "active": true,
6
- "problems": [
7
- "hello-world",
8
- "bob",
9
- "leap",
10
- "raindrops",
11
- "pangram",
12
- "accumulate",
13
- "triangle",
14
- "anagram",
15
- "space-age",
16
- "strain",
17
- "difference-of-squares",
18
- "word-count",
19
- "sum-of-multiples",
20
- "hamming",
21
- "rna-transcription",
22
- "run-length-encoding",
23
- "sublist",
24
- "nucleotide-count",
25
- "series",
26
- "phone-number",
27
- "grade-school",
28
- "allergies",
29
- "robot-simulator",
30
- "list-ops",
31
- "atbash-cipher",
32
- "say",
33
- "largest-series-product",
34
- "roman-numerals",
35
- "gigasecond"
36
- ],
37
6
  "exercises": [
38
7
  {
39
8
  "slug": "hello-world",
@@ -70,6 +39,11 @@
70
39
  "difficulty": 1,
71
40
  "topics": []
72
41
  },
42
+ {
43
+ "slug": "scrabble-score",
44
+ "difficulty": 1,
45
+ "topics": []
46
+ },
73
47
  {
74
48
  "slug": "anagram",
75
49
  "difficulty": 1,
@@ -17,6 +17,7 @@
17
17
  "./exercises/anagram",
18
18
  "./exercises/raindrops",
19
19
  "./exercises/triangle",
20
+ "./exercises/scrabble-score",
20
21
  "./exercises/accumulate",
21
22
  "./exercises/sublist",
22
23
  "./exercises/sum-of-multiples",
@@ -76,7 +76,7 @@ tests =
76
76
  \() ->
77
77
  Expect.equal
78
78
  "Whoa, chill out!"
79
- (Bob.hey "ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!)")
79
+ (Bob.hey "ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!")
80
80
  , test "shouting with no exclamation mark" <|
81
81
  \() ->
82
82
  Expect.equal
@@ -1 +1,6 @@
1
1
  module RunLengthEncoding exposing (..)
2
+
3
+
4
+ version : Int
5
+ version =
6
+ 2
@@ -0,0 +1 @@
1
+ module ScrabbleScore exposing (..)
@@ -0,0 +1,32 @@
1
+ module ScrabbleScore exposing (..)
2
+
3
+ import String exposing (contains, foldl, fromChar, toUpper)
4
+
5
+
6
+ addLetterScore : Char -> Int -> Int
7
+ addLetterScore s total =
8
+ let
9
+ c =
10
+ toUpper (fromChar s)
11
+ in
12
+ if contains c "AEIOULNRST" then
13
+ total + 1
14
+ else if contains c "DG" then
15
+ total + 2
16
+ else if contains c "BCMP" then
17
+ total + 3
18
+ else if contains c "FHVWY" then
19
+ total + 4
20
+ else if contains c "K" then
21
+ total + 5
22
+ else if contains c "JX" then
23
+ total + 8
24
+ else if contains c "QZ" then
25
+ total + 10
26
+ else
27
+ total
28
+
29
+
30
+ scoreWord : String -> Int
31
+ scoreWord x =
32
+ x |> foldl addLetterScore 0
@@ -0,0 +1,43 @@
1
+ port module Main exposing (..)
2
+
3
+ import Test.Runner.Node exposing (run)
4
+ import Json.Encode exposing (Value)
5
+ import Test exposing (..)
6
+ import Expect
7
+ import ScrabbleScore exposing (scoreWord)
8
+
9
+
10
+ tests : Test
11
+ tests =
12
+ describe "Grains"
13
+ [ test "lowercase letter" <|
14
+ \() -> Expect.equal 1 (scoreWord "a")
15
+ , test "uppercase letter" <|
16
+ \() -> Expect.equal 1 (scoreWord "A")
17
+ , test "valuable letter" <|
18
+ \() -> Expect.equal 4 (scoreWord "f")
19
+ , test "short word" <|
20
+ \() -> Expect.equal 2 (scoreWord "at")
21
+ , test "short, valuable word" <|
22
+ \() -> Expect.equal 12 (scoreWord "zoo")
23
+ , test "medium word" <|
24
+ \() -> Expect.equal 6 (scoreWord "street")
25
+ , test "medium, valuable word" <|
26
+ \() -> Expect.equal 22 (scoreWord "quirky")
27
+ , test "long, mixed-case word" <|
28
+ \() -> Expect.equal 41 (scoreWord "OxyphenButazone")
29
+ , test "english-like word" <|
30
+ \() -> Expect.equal 8 (scoreWord "pinata")
31
+ , test "non-english letter is not scored" <|
32
+ \() -> Expect.equal 7 (scoreWord "piñata")
33
+ , test "empty input" <|
34
+ \() -> Expect.equal 0 (scoreWord "")
35
+ ]
36
+
37
+
38
+ main : Program Value
39
+ main =
40
+ run emit tests
41
+
42
+
43
+ port emit : ( String, Value ) -> Cmd msg
@@ -0,0 +1,16 @@
1
+ {
2
+ "version": "3.0.0",
3
+ "summary": "Exercism problems in Elm.",
4
+ "repository": "https://github.com/exercism/xelm.git",
5
+ "license": "BSD3",
6
+ "source-directories": [
7
+ "."
8
+ ],
9
+ "exposed-modules": [],
10
+ "dependencies": {
11
+ "elm-lang/core": "4.0.0 <= v < 5.0.0",
12
+ "elm-community/elm-test": "2.0.0 <= v < 3.0.0",
13
+ "rtfeldman/node-test-runner": "2.0.0 <= v < 3.0.0"
14
+ },
15
+ "elm-version": "0.17.0 <= v < 0.18.0"
16
+ }
@@ -0,0 +1 @@
1
+ ECHO We've changed how tests are run! Please review the latest install/running docs at http://exercism.io/languages/elm and report any issues at https://github.com/exercism/xelm
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env bash
2
+ echo "We've changed how tests are run! Please review the latest install/running docs at http://exercism.io/languages/elm and report any issues at https://github.com/exercism/xelm"
@@ -1 +1,6 @@
1
1
  module Sublist exposing (..)
2
+
3
+
4
+ version : Int
5
+ version =
6
+ 2
@@ -12,6 +12,11 @@ let ``Sum to 1`` () =
12
12
  let ``Sum to 3`` () =
13
13
  Assert.That(sumOfMultiples [3; 5] 3, Is.EqualTo(0))
14
14
 
15
+ [<Test>]
16
+ [<Ignore("Remove to run test")>]
17
+ let ``Sum to 4`` () =
18
+ Assert.That(sumOfMultiples [3; 5] 4, Is.EqualTo(3))
19
+
15
20
  [<Test>]
16
21
  [<Ignore("Remove to run test")>]
17
22
  let ``Sum to 10`` () =
@@ -25,4 +30,4 @@ let ``Sum to 20`` () =
25
30
  [<Test>]
26
31
  [<Ignore("Remove to run test")>]
27
32
  let ``Sum to 10000`` () =
28
- Assert.That(sumOfMultiples [43; 47] 10000, Is.EqualTo(2203160))
33
+ Assert.That(sumOfMultiples [43; 47] 10000, Is.EqualTo(2203160))
@@ -5,5 +5,14 @@ commonly taught [object oriented approach](https://en.wikipedia.org/wiki/Object-
5
5
  learning Haskell can feel different than simply picking up another language.
6
6
 
7
7
  Fortunately there are numerous resources which presume some programming knowledge to begin with, such
8
- as the popular [Learn You a Haskell For Great Good!](http://learnyouahaskell.com/) In addition, you may refer to the Haskell
9
- [wiki](https://wiki.haskell.org/Learning_Haskell#Online_tutorials) for an abundance of resources on beginning.
8
+ as
9
+ - the popular [Learn You a Haskell For Great Good!](http://learnyouahaskell.com/)
10
+ - University of Glasgow's [Functional Programming in Haskell](https://www.futurelearn.com/courses/functional-programming-haskell) course
11
+ - FP Complete's [School of Haskell](https://www.schoolofhaskell.com/)
12
+ - and the [Happy Learn Haskell Tutorial](http://www.happylearnhaskelltutorial.com/).
13
+
14
+ Some recent Haskell books include
15
+ - [Haskell Programming From First Principles](http://haskellbook.com) by Christopher Allen and Julie Moronuki (this book does not presume prior programming knowledge)
16
+ - [Programming in Haskell](http://www.cambridge.org/us/academic/subjects/computer-science/programming-languages-and-applied-logic/programming-haskell-2nd-edition?format=PB&isbn=9781316626221) by Graham Hutton
17
+
18
+ You may also refer to the [Haskell wiki](https://wiki.haskell.org/Learning_Haskell#Online_tutorials) for an abundance of other resources on beginning.
@@ -7,6 +7,7 @@ import Test.Hspec.Runner (configFastFail, defaultConfig, hspecWith)
7
7
  import Prelude hiding
8
8
  ( (++)
9
9
  , concat
10
+ , filter
10
11
  , foldr
11
12
  , length
12
13
  , map
@@ -16,6 +17,7 @@ import Prelude hiding
16
17
  import ListOps
17
18
  ( (++)
18
19
  , concat
20
+ , filter
19
21
  , foldl'
20
22
  , foldr
21
23
  , length
@@ -43,7 +43,9 @@
43
43
  "nth-prime",
44
44
  "pascals-triangle",
45
45
  "beer-song",
46
- "difference-of-squares"
46
+ "difference-of-squares",
47
+ "largest-series-product",
48
+ "queen-attack"
47
49
  ],
48
50
  "exercises": [
49
51
  {
@@ -245,6 +247,16 @@
245
247
  "slug": "difference-of-squares",
246
248
  "difficulty": 1,
247
249
  "topics": []
250
+ },
251
+ {
252
+ "slug": "largest-series-product",
253
+ "difficulty": 1,
254
+ "topics": []
255
+ },
256
+ {
257
+ "slug": "queen-attack",
258
+ "difficulty": 1,
259
+ "topics": []
248
260
  }
249
261
  ],
250
262
  "deprecated": [