trackler 2.0.0.5 → 2.0.0.6

Sign up to get free protection for your applications and to get access to all the features.
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": [