trackler 2.0.5.7 → 2.0.5.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/common/exercises/book-store/canonical-data.json +106 -0
  3. data/common/exercises/phone-number/canonical-data.json +57 -0
  4. data/lib/trackler/version.rb +1 -1
  5. data/tracks/elm/exercises/accumulate/package.json +1 -1
  6. data/tracks/elm/exercises/allergies/package.json +1 -1
  7. data/tracks/elm/exercises/anagram/package.json +1 -1
  8. data/tracks/elm/exercises/atbash-cipher/package.json +1 -1
  9. data/tracks/elm/exercises/bob/package.json +1 -1
  10. data/tracks/elm/exercises/difference-of-squares/package.json +1 -1
  11. data/tracks/elm/exercises/gigasecond/package.json +1 -1
  12. data/tracks/elm/exercises/grade-school/package.json +1 -1
  13. data/tracks/elm/exercises/hamming/package.json +1 -1
  14. data/tracks/elm/exercises/hello-world/package.json +1 -1
  15. data/tracks/elm/exercises/largest-series-product/package.json +1 -1
  16. data/tracks/elm/exercises/leap/package.json +1 -1
  17. data/tracks/elm/exercises/list-ops/package.json +1 -1
  18. data/tracks/elm/exercises/nucleotide-count/package.json +1 -1
  19. data/tracks/elm/exercises/pangram/package.json +1 -1
  20. data/tracks/elm/exercises/phone-number/package.json +1 -1
  21. data/tracks/elm/exercises/raindrops/package.json +1 -1
  22. data/tracks/elm/exercises/rna-transcription/package.json +1 -1
  23. data/tracks/elm/exercises/robot-simulator/package.json +1 -1
  24. data/tracks/elm/exercises/roman-numerals/package.json +1 -1
  25. data/tracks/elm/exercises/run-length-encoding/package.json +1 -1
  26. data/tracks/elm/exercises/say/package.json +1 -1
  27. data/tracks/elm/exercises/scrabble-score/package.json +1 -1
  28. data/tracks/elm/exercises/series/package.json +1 -1
  29. data/tracks/elm/exercises/space-age/package.json +1 -1
  30. data/tracks/elm/exercises/strain/package.json +1 -1
  31. data/tracks/elm/exercises/sublist/package.json +1 -1
  32. data/tracks/elm/exercises/sum-of-multiples/package.json +1 -1
  33. data/tracks/elm/exercises/triangle/package.json +1 -1
  34. data/tracks/elm/exercises/word-count/package.json +1 -1
  35. data/tracks/go/exercises/house/example.go +58 -28
  36. data/tracks/go/exercises/house/house_test.go +27 -36
  37. data/tracks/go/exercises/sum-of-multiples/example.go +9 -10
  38. data/tracks/go/exercises/sum-of-multiples/sum_of_multiples_test.go +9 -44
  39. data/tracks/pascal/README.md +9 -5
  40. data/tracks/pascal/config.json +123 -8
  41. data/tracks/pascal/docs/ABOUT.md +10 -0
  42. data/tracks/pascal/docs/INSTALLATION.md +18 -0
  43. data/tracks/pascal/docs/LEARNING.md +5 -0
  44. data/tracks/scala/exercises/bowling/build.sbt +2 -2
  45. data/tracks/scala/exercises/bowling/src/test/scala/BowlingSuite.scala +26 -104
  46. data/tracks/scala/exercises/forth/build.sbt +2 -2
  47. data/tracks/scala/exercises/forth/src/main/scala/Forth.scala +6 -0
  48. data/tracks/scala/exercises/nucleotide-count/HINTS.md +12 -12
  49. data/tracks/scala/exercises/nucleotide-count/build.sbt +2 -2
  50. data/tracks/scala/exercises/nucleotide-count/example.scala +4 -4
  51. data/tracks/scala/exercises/nucleotide-count/src/main/scala/DNA.scala +6 -0
  52. metadata +6 -3
  53. data/tracks/scala/exercises/nucleotide-count/src/main/scala/.keep +0 -0
@@ -1,16 +1,15 @@
1
1
  package summultiples
2
2
 
3
- func MultipleSummer(divisors ...int) func(int) int {
4
- return func(limit int) int {
5
- sum := 0
6
- for i := 1; i < limit; i++ {
7
- for _, d := range divisors {
8
- if i%d == 0 {
9
- sum += i
10
- break
11
- }
3
+ // SumMultiples returns the sum of the multiples of the given divisors
4
+ // up to, but not including, the given limit.
5
+ func SumMultiples(limit int, divisors ...int) (sum int) {
6
+ for i := 1; i < limit; i++ {
7
+ for _, d := range divisors {
8
+ if i%d == 0 {
9
+ sum += i
10
+ break
12
11
  }
13
12
  }
14
- return sum
15
13
  }
14
+ return
16
15
  }
@@ -2,50 +2,26 @@ package summultiples
2
2
 
3
3
  import "testing"
4
4
 
5
- var test35 = []struct {
6
- limit int
7
- sum int
8
- }{
9
- {1, 0},
10
- {4, 3},
11
- {10, 23},
12
- {100, 2318},
13
- {1000, 233168},
14
- }
15
-
16
5
  var varTests = []struct {
17
6
  divisors []int
18
7
  limit int
19
8
  sum int
20
9
  }{
10
+ {[]int{3, 5}, 1, 0},
11
+ {[]int{3, 5}, 4, 3},
12
+ {[]int{3, 5}, 10, 23},
13
+ {[]int{3, 5}, 100, 2318},
14
+ {[]int{3, 5}, 1000, 233168},
21
15
  {[]int{7, 13, 17}, 20, 51},
22
16
  {[]int{43, 47}, 10000, 2203160},
23
17
  {[]int{5, 10, 12}, 10000, 13331672},
24
18
  {[]int{1, 1}, 10000, 49995000},
25
- // Note: The following test case deviates from the README.
26
- // The README specifies some rather odd defaults, whereas
27
- // this has the more logical approach of not implementing any
28
- // defaults, which causes the resulting sum to be zero.
29
- // See discussion in:
30
- // https://github.com/exercism/xgo/issues/256 and
31
- // https://github.com/exercism/x-common/issues/198
32
19
  {[]int{}, 10000, 0},
33
20
  }
34
21
 
35
- func Test35(t *testing.T) {
36
- sum35 := MultipleSummer(3, 5)
37
- for _, test := range test35 {
38
- s := sum35(test.limit)
39
- if s != test.sum {
40
- t.Fatalf("Sum to %d returned %d, want %d.", test.limit, s, test.sum)
41
- }
42
- }
43
- }
44
-
45
- func TestVar(t *testing.T) {
22
+ func TestSumMultiples(t *testing.T) {
46
23
  for _, test := range varTests {
47
- sv := MultipleSummer(test.divisors...)
48
- s := sv(test.limit)
24
+ s := SumMultiples(test.limit, test.divisors...)
49
25
  if s != test.sum {
50
26
  t.Fatalf("Sum of multiples of %v to %d returned %d, want %d.",
51
27
  test.divisors, test.limit, s, test.sum)
@@ -53,21 +29,10 @@ func TestVar(t *testing.T) {
53
29
  }
54
30
  }
55
31
 
56
- func Benchmark35(b *testing.B) {
57
- sum35 := MultipleSummer(3, 5)
58
- b.ResetTimer() // bench just the sum function
59
- for i := 0; i < b.N; i++ {
60
- for _, test := range test35 {
61
- sum35(test.limit)
62
- }
63
- }
64
- }
65
-
66
- func BenchmarkVar(b *testing.B) {
67
- // bench combined time to bind sum function and call it.
32
+ func BenchmarkSumMultiples(b *testing.B) {
68
33
  for i := 0; i < b.N; i++ {
69
34
  for _, test := range varTests {
70
- MultipleSummer(test.divisors...)(test.limit)
35
+ SumMultiples(test.limit, test.divisors...)
71
36
  }
72
37
  }
73
38
  }
@@ -1,11 +1,15 @@
1
- # Exercism Pascal Track
1
+ # xPascal
2
2
 
3
- Exercism exercises in Pascal.
4
-
5
- ## TODO
3
+ [![Build Status](https://travis-ci.org/exercism/xpascal.png?branch=master)](https://travis-ci.org/exercism/xpascal)
6
4
 
7
- _Document how to contribute to the Pascal track._
5
+ Exercism exercises in Pascal.
8
6
 
9
7
  ## Contributing Guide
10
8
 
11
9
  Please see the [contributing guide](https://github.com/exercism/x-common/blob/master/CONTRIBUTING.md).
10
+
11
+ ## License
12
+
13
+ The MIT License (MIT)
14
+
15
+ Copyright (c) 2014 Katrina Owen, _@kytrinyx.com
@@ -3,19 +3,134 @@
3
3
  "language": "Pascal",
4
4
  "repository": "https://github.com/exercism/xpascal",
5
5
  "active": false,
6
- "test_pattern": "TODO",
7
6
  "exercises": [
8
-
9
- ],
10
- "deprecated": [
11
-
7
+ {
8
+ "slug": "hello-world",
9
+ "difficulty": 1,
10
+ "topics": [
11
+ "Text formatting",
12
+ "Optional values"
13
+ ]
14
+ },
15
+ {
16
+ "slug": "bob",
17
+ "difficulty": 1,
18
+ "topics": [
19
+ "Strings",
20
+ "Control-flow (if-else statements)"
21
+ ]
22
+ },
23
+ {
24
+ "slug": "leap",
25
+ "difficulty": 1,
26
+ "topics": [
27
+ "Integers"
28
+ ]
29
+ },
30
+ {
31
+ "slug": "hamming",
32
+ "difficulty": 2,
33
+ "topics": [
34
+ "Strings",
35
+ "Filtering"
36
+ ]
37
+ },
38
+ {
39
+ "slug": "bowling",
40
+ "difficulty": 6,
41
+ "topics": [
42
+ "Algorithms",
43
+ "Control-flow (loops)"
44
+ ]
45
+ },
46
+ {
47
+ "slug": "allergies",
48
+ "difficulty": 4,
49
+ "topics": [
50
+ "Bitwise operations",
51
+ "Filtering"
52
+ ]
53
+ },
54
+ {
55
+ "slug": "bank-account",
56
+ "difficulty": 2,
57
+ "topics": [
58
+ "Classes"
59
+ ]
60
+ },
61
+ {
62
+ "slug": "beer-song",
63
+ "difficulty": 3,
64
+ "topics": [
65
+ "Text formatting",
66
+ "Algorithms"
67
+ ]
68
+ },
69
+ {
70
+ "slug": "phone-number",
71
+ "difficulty": 3,
72
+ "topics": [
73
+ "Parsing",
74
+ "Transforming"
75
+ ]
76
+ },
77
+ {
78
+ "slug": "binary-search",
79
+ "difficulty": 3,
80
+ "topics": [
81
+ "Searching",
82
+ "Arrays"
83
+ ]
84
+ },
85
+ {
86
+ "slug": "book-store",
87
+ "difficulty": 6
88
+ },
89
+ {
90
+ "slug": "perfect-numbers",
91
+ "difficulty": 3,
92
+ "topics": [
93
+ "Integers"
94
+ ]
95
+ },
96
+ {
97
+ "slug": "nucleotide-count",
98
+ "difficulty": 2,
99
+ "topics": [
100
+ "Dictionaries",
101
+ "Strings"
102
+ ]
103
+ },
104
+ {
105
+ "slug": "etl",
106
+ "difficulty": 2,
107
+ "topics": [
108
+ "Dictionaries",
109
+ "Lists",
110
+ "Transforming"
111
+ ]
112
+ },
113
+ {
114
+ "slug": "binary-search",
115
+ "difficulty": 3,
116
+ "topics": [
117
+ "Searching",
118
+ "Arrays",
119
+ "Recursion"
120
+ ]
121
+ },
122
+ {
123
+ "slug": "clock",
124
+ "difficulty": 3,
125
+ "topics": [
126
+ "Time",
127
+ "Structural equality"
128
+ ]
129
+ }
12
130
  ],
13
131
  "ignored": [
14
132
  "bin",
15
133
  "img",
16
134
  "docs"
17
- ],
18
- "foregone": [
19
-
20
135
  ]
21
136
  }
@@ -0,0 +1,10 @@
1
+ ## Delphi (programming language) ##
2
+ *From Wikipedia, the free encyclopedia*
3
+
4
+ **Embarcadero Delphi** is a [programming language](https://en.wikipedia.org/wiki/Programming_language) and [software development kit](https://en.wikipedia.org/wiki/Software_development_kit) (SDK) for [desktop](https://en.wikipedia.org/wiki/Graphical_user_interface), [mobile](https://en.wikipedia.org/wiki/Mobile_app), [web](https://en.wikipedia.org/wiki/Web_application), and [console](https://en.wikipedia.org/wiki/Console_application) applications.[[1]](https://en.wikipedia.org/wiki/Delphi_(programming_language)#cite_note-Buchanan2003-1) Delphi's compilers use their own [Object Pascal](https://en.wikipedia.org/wiki/Object_Pascal) dialect of [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language)) and generate native code for several platforms: Windows ([x86](https://en.wikipedia.org/wiki/IA-32) and [x64](https://en.wikipedia.org/wiki/X86-64)), [OS X](https://en.wikipedia.org/wiki/MacOS) (32-bit only), [iOS](https://en.wikipedia.org/wiki/IOS) (32 and 64-bit) and [Android](https://en.wikipedia.org/wiki/Android_(operating_system)).
5
+
6
+ Delphi, part of [RAD Studio](https://en.wikipedia.org/wiki/Delphi_(programming_language)#RAD_Studio), includes a code editor with [Code Insight](https://en.wikipedia.org/wiki/Code_Insight) ([code completion](https://en.wikipedia.org/wiki/Autocomplete#In_source_code_editors)), [Error Insight](https://en.wikipedia.org/wiki/Error_Insight) (real-time error-checking), and other features; [refactoring](https://en.wikipedia.org/wiki/Code_refactoring); a visual forms designer for both [VCL](https://en.wikipedia.org/wiki/Visual_Component_Library) (native Windows) and [FMX](https://en.wikipedia.org/wiki/FireMonkey) (cross-platform, partially native per platform); an integrated debugger for all platforms including mobile; source control ([SVN](https://en.wikipedia.org/wiki/Apache_Subversion), [git](https://en.wikipedia.org/wiki/Git), and [Mercurial](https://en.wikipedia.org/wiki/Mercurial)); and support for third-party plugins. It has strong database support. Delphi is remarkably fast to compile:[[2]](https://en.wikipedia.org/wiki/Delphi_(programming_language)#cite_note-2) unlike any other common languages, including C# and Swift, it is not unusual for a Delphi project of a million lines to compile in a few seconds – one benchmark gave 170,000 lines per second.[[3]](https://en.wikipedia.org/wiki/Delphi_(programming_language)#cite_note-3)[[4]](https://en.wikipedia.org/wiki/Delphi_(programming_language)#cite_note-4) It is under active development, with (in 2016) releases every six months, with new platforms being added approximately every second release.[[5]](https://en.wikipedia.org/wiki/Delphi_(programming_language)#cite_note-5)
7
+
8
+ Delphi was originally developed by [Borland](https://en.wikipedia.org/wiki/Borland) as a [rapid application development](https://en.wikipedia.org/wiki/Rapid_application_development) tool for Windows as the successor of [Turbo Pascal](https://en.wikipedia.org/wiki/Turbo_Pascal). Delphi added full object-orientation to the existing language, and since then the language has grown and supports many other modern language features, including generics and anonymous methods, as well as unusual features such as inbuilt string types and native COM support. Delphi and its [C++](https://en.wikipedia.org/wiki/C%2B%2B) counterpart, [C++ Builder](https://en.wikipedia.org/wiki/C%2B%2BBuilder), share many core components, notably the IDE, the [Visual Component Library](https://en.wikipedia.org/wiki/Visual_Component_Library) (VCL), and much of the [RTL](https://en.wikipedia.org/wiki/Runtime_library), and are compatible with each other: C++ Builder 6 and onwards can consume Delphi-language files and C++ in the one project, and packages compiled with C++ Builder written in C++ can be used from within Delphi. In 2007, the products were released jointly as RAD Studio. [RAD Studio](https://en.wikipedia.org/wiki/Delphi_(programming_language)#RAD_Studio) is a shared host for Delphi and C++Builder, and can be purchased with either or both.
9
+
10
+ In 2006, Borland’s developer tools section were transferred from Borland to a wholly owned subsidiary known as [CodeGear](https://en.wikipedia.org/wiki/CodeGear), which was sold to [Embarcadero Technologies](https://en.wikipedia.org/wiki/Embarcadero_Technologies) in 2008. In 2015, Embarcadero was purchased by Idera, but the Embarcadero mark was retained for the developer tools division.
@@ -0,0 +1,18 @@
1
+ # Installing Delphi and DUnitX Testing Framework #
2
+ ### Windows ###
3
+
4
+ 30 day free trial of Embarcadero's RAD Studio or Delphi may be downloaded from [here](https://www.embarcadero.com/products?utm_source=google&utm_medium=cpc&utm_campaign=brand&utm_content=brand&utm_embarcadero&gclid=CjwKEAiAp97CBRDr2Oyl-faxqRMSJABx4kh9V8bOEuG0CznQ9AGToIyuKeTzvevljmHTboYXk4n6OxoC4Frw_wcB). Follow installation instructions included with the product.
5
+
6
+ ### Non-Windows based Operating Systems ###
7
+
8
+ Sorry, Delphi does not run natively on any other operating systems. However it should be possible to install Delphi into a virtual machine which is running Windows.
9
+
10
+
11
+ ### Installing DUnitX Test Framework ###
12
+ With Delphi successfully installed and working correctly please follow these steps for retrieving and installing DUnitX.
13
+
14
+ - DUnitX is an open source project by [VSoftTechnologies](https://www.github.com/VSoftTechnologies). The DUnitX github repo is available [here](https://github.com/VSoftTechnologies/DUnitX).
15
+ - It is best to fork the repo and then clone or otherwise download the fork to your local machine.
16
+ - Step-by-step instructions on how to install DUnitX into Delphi have been posted by Vincent Parrett in a blog post located [here](https://www.finalbuilder.com/resources/blogs/postid/702/dunitx-has-a-wizard).
17
+
18
+ *Note: It is assumed that Delphi versions XE and higher are being utilized by the student.*
@@ -0,0 +1,5 @@
1
+ Exercism provides exercises and feedback but can be difficult to jump into for those learning Pascal for the first time. These resources can help you get started:
2
+
3
+ * [Pascal Tutorial](https://www.tutorialspoint.com/pascal/index.htm) looks like a good place to get your feet we with Pascal if you have zero experience with this language. You do not need Delphi to complete the exercises covered in this tutorial. This may be a good place to practice up before jumping in to the exercises here, which do require Delphi to complete.
4
+ * [Pascal-Programming.info](http://www.pascal-programming.info/index.php) also appears to have a good tutorial for newcomers to the language.
5
+ * There are many more sources online for learning Pascal, too many to list here.
@@ -1,3 +1,3 @@
1
- scalaVersion := "2.11.7"
1
+ scalaVersion := "2.12.1"
2
2
 
3
- libraryDependencies += "org.scalatest" % "scalatest_2.11" % "2.2.5" % "test"
3
+ libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.1" % "test"
@@ -4,234 +4,156 @@ class BowlingSuite extends FunSuite with Matchers {
4
4
  // returns the final score of a bowling game
5
5
  test("should be able to score a game with all zeros") {
6
6
  val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
7
- score match {
8
- case Right(n) => assert(n == 0)
9
- case Left(_) => fail("should be able to score a game with all zeros")
10
- }
7
+ score should be (Right(0))
11
8
  }
12
9
 
13
10
  test("should be able to score a game with no strikes or spares") {
14
11
  pending
15
12
  val score = List(3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
16
- score match {
17
- case Right(n) => assert(n == 90)
18
- case Left(_) => fail("should be able to score a game with no strikes or spares")
19
- }
13
+ score should be (Right(90))
20
14
  }
21
15
 
22
16
  test("a spare followed by zeros is worth ten points") {
23
17
  pending
24
18
  val score = List(6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
25
- score match {
26
- case Right(n) => assert(n == 10)
27
- case Left(_) => fail("a spare followed by zeros is worth ten points")
28
- }
19
+ score should be (Right(10))
29
20
  }
30
21
 
31
22
  test("points scored in the roll after a spare are counted twice") {
32
23
  pending
33
24
  val score = List(6, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
34
- score match {
35
- case Right(n) => assert(n == 16)
36
- case Left(_) => fail("points scored in the roll after a spare are counted twice")
37
- }
25
+ score should be (Right(16))
38
26
  }
39
27
 
40
28
  test("consecutive spares each get a one roll bonus") {
41
29
  pending
42
30
  val score = List(5, 5, 3, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
43
- score match {
44
- case Right(n) => assert(n == 31)
45
- case Left(_) => fail("consecutive spares each get a one roll bonus")
46
- }
31
+ score should be (Right(31))
47
32
  }
48
33
 
49
34
  test("a spare in the last frame gets a one roll bonus that is counted once") {
50
35
  pending
51
36
  val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 7).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
52
- score match {
53
- case Right(n) => assert(n == 17)
54
- case Left(_) => fail("a spare in the last frame gets a one roll bonus that is counted once")
55
- }
37
+ score should be (Right(17))
56
38
  }
57
39
 
58
40
  test("a strike earns ten points in a frame with a single roll") {
59
41
  pending
60
42
  val score = List(10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
61
- score match {
62
- case Right(n) => assert(n == 10)
63
- case Left(_) => fail("a strike earns ten points in a frame with a single roll")
64
- }
43
+ score should be (Right(10))
65
44
  }
66
45
 
67
46
  test("points scored in the two rolls after a strike are counted twice as a bonus") {
68
47
  pending
69
48
  val score = List(10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
70
- score match {
71
- case Right(n) => assert(n == 26)
72
- case Left(_) => fail("points scored in the two rolls after a strike are counted twice as a bonus")
73
- }
49
+ score should be (Right(26))
74
50
  }
75
51
 
76
52
  test("consecutive strikes each get the two roll bonus") {
77
53
  pending
78
54
  val score = List(10, 10, 10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
79
- score match {
80
- case Right(n) => assert(n == 81)
81
- case Left(_) => fail("consecutive strikes each get the two roll bonus")
82
- }
55
+ score should be (Right(81))
83
56
  }
84
57
 
85
58
  test("a strike in the last frame gets a two roll bonus that is counted once") {
86
59
  pending
87
60
  val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 1).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
88
- score match {
89
- case Right(n) => assert(n == 18)
90
- case Left(_) => fail("a strike in the last frame gets a two roll bonus that is counted once")
91
- }
61
+ score should be (Right(18))
92
62
  }
93
63
 
94
64
  test("rolling a spare with the two roll bonus does not get a bonus roll") {
95
65
  pending
96
66
  val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 3).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
97
- score match {
98
- case Right(n) => assert(n == 20)
99
- case Left(_) => fail("rolling a spare with the two roll bonus does not get a bonus roll")
100
- }
67
+ score should be (Right(20))
101
68
  }
102
69
 
103
70
  test("strikes with the two roll bonus do not get bonus rolls") {
104
71
  pending
105
72
  val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
106
- score match {
107
- case Right(n) => assert(n == 30)
108
- case Left(_) => fail("strikes with the two roll bonus do not get bonus rolls")
109
- }
73
+ score should be (Right(30))
110
74
  }
111
75
 
112
76
  test("a strike with the one roll bonus after a spare in the last frame does not get a bonus") {
113
77
  pending
114
78
  val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 10).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
115
- score match {
116
- case Right(n) => assert(n == 20)
117
- case Left(_) => fail("a strike with the one roll bonus after a spare in the last frame does not get a bonus")
118
- }
79
+ score should be (Right(20))
119
80
  }
120
81
 
121
82
  test("all strikes is a perfect game") {
122
83
  pending
123
84
  val score = List(10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
124
- score match {
125
- case Right(n) => assert(n == 300)
126
- case Left(_) => fail("all strikes is a perfect game")
127
- }
85
+ score should be (Right(300))
128
86
  }
129
87
 
130
88
  test("rolls can not score negative points") {
131
89
  pending
132
90
  val score = List(-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
133
- score match {
134
- case Right(_) => fail("Unexpected score returned. Failure expected")
135
- case Left(_) =>
136
- }
91
+ score.isLeft should be (true)
137
92
  }
138
93
 
139
94
  test("a roll can not score more than 10 points") {
140
95
  pending
141
96
  val score = List(11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
142
- score match {
143
- case Right(_) => fail("Unexpected score returned. Failure expected")
144
- case Left(_) =>
145
- }
97
+ score.isLeft should be (true)
146
98
  }
147
99
 
148
100
  test("two rolls in a frame can not score more than 10 points") {
149
101
  pending
150
102
  val score = List(5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
151
- score match {
152
- case Right(_) => fail("Unexpected score returned. Failure expected")
153
- case Left(_) =>
154
- }
103
+ score.isLeft should be (true)
155
104
  }
156
105
 
157
106
  test("two bonus rolls after a strike in the last frame can not score more than 10 points") {
158
107
  pending
159
108
  val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5, 6).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
160
- score match {
161
- case Right(_) => fail("Unexpected score returned. Failure expected")
162
- case Left(_) =>
163
- }
109
+ score.isLeft should be (true)
164
110
  }
165
111
 
166
112
  test("two bonus rolls after a strike in the last frame can score more than 10 points if one is a strike") {
167
113
  pending
168
114
  val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 6).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
169
- score match {
170
- case Right(n) => assert(n == 26)
171
- case Left(_) => fail("two bonus rolls after a strike in the last frame can score more than 10 points if one is a strike")
172
- }
115
+ score should be (Right(26))
173
116
  }
174
117
 
175
118
  test("the second bonus rolls after a strike in the last frame can not be a strike if the first one is not a strike") {
176
119
  pending
177
120
  val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 6, 10).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
178
- score match {
179
- case Right(_) => fail("Unexpected score returned. Failure expected")
180
- case Left(_) =>
181
- }
121
+ score.isLeft should be (true)
182
122
  }
183
123
 
184
124
  test("an unstarted game can not be scored") {
185
125
  pending
186
126
  val score = List().foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
187
- score match {
188
- case Right(_) => fail("Unexpected score returned. Failure expected")
189
- case Left(_) =>
190
- }
127
+ score.isLeft should be (true)
191
128
  }
192
129
 
193
130
  test("an incomplete game can not be scored") {
194
131
  pending
195
132
  val score = List(0, 0).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
196
- score match {
197
- case Right(_) => fail("Unexpected score returned. Failure expected")
198
- case Left(_) =>
199
- }
133
+ score.isLeft should be (true)
200
134
  }
201
135
 
202
136
  test("a game with more than ten frames can not be scored") {
203
137
  pending
204
138
  val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
205
- score match {
206
- case Right(_) => fail("Unexpected score returned. Failure expected")
207
- case Left(_) =>
208
- }
139
+ score.isLeft should be (true)
209
140
  }
210
141
 
211
142
  test("bonus rolls for a strike in the last frame must be rolled before score can be calculated") {
212
143
  pending
213
144
  val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
214
- score match {
215
- case Right(_) => fail("Unexpected score returned. Failure expected")
216
- case Left(_) =>
217
- }
145
+ score.isLeft should be (true)
218
146
  }
219
147
 
220
148
  test("both bonus rolls for a strike in the last frame must be rolled before score can be calculated") {
221
149
  pending
222
150
  val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
223
- score match {
224
- case Right(_) => fail("Unexpected score returned. Failure expected")
225
- case Left(_) =>
226
- }
151
+ score.isLeft should be (true)
227
152
  }
228
153
 
229
154
  test("bonus roll for a spare in the last frame must be rolled before score can be calculated") {
230
155
  pending
231
156
  val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
232
- score match {
233
- case Right(_) => fail("Unexpected score returned. Failure expected")
234
- case Left(_) =>
235
- }
157
+ score.isLeft should be (true)
236
158
  }
237
159
  }
@@ -1,5 +1,5 @@
1
- scalaVersion := "2.11.7"
1
+ scalaVersion := "2.12.1"
2
2
 
3
3
 
4
- libraryDependencies += "org.scalatest" % "scalatest_2.11" % "2.2.5" % "test"
4
+ libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.1" % "test"
5
5
  libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.0.4"
@@ -0,0 +1,6 @@
1
+ import ForthError.ForthError
2
+
3
+
4
+ class Forth extends ForthEvaluator {
5
+ def eval(text: String): Either[ForthError, ForthEvaluatorState] = ???
6
+ }
@@ -3,10 +3,10 @@ A common use of `Either` is to indicate a computation that may possibly result i
3
3
  (if the actual error is of no interest then the simpler `Option` type might be a better choice).
4
4
  In the absence of an error the result is usually a `Right` (mnemonic: the "right" value)
5
5
  whereas an error is a `Left`, for example a `Left[String]` containing an error message.
6
- Note that in Scala `Either` is unbiased, so you have to make it biased with a `RightProjection` using `Either.right`.
7
- If you are unfamiliar with `Either` you may read [this tutorial](http://danielwestheide.com/blog/2013/01/02/the-neophytes-guide-to-scala-part-7-the-either-type.html).
8
- `Either` (or its `RightProjection` to be more exact) is a so-called [Monad](https://en.wikipedia.org/wiki/Monad_(functional_programming)) which
9
- covers a "computational aspect", in this case error handling.
6
+ Note that in Scala 2.12 `Either` is right-biased by default, so it works as expected for operations like `filter`, `map`, `flatMap` or in a for-comprehension.
7
+ If you are unfamiliar with `Either` you may read [this tutorial](http://danielwestheide.com/blog/2013/01/02/the-neophytes-guide-to-scala-part-7-the-either-type.html). But be aware that this tutorial is about Scala versions prior to 2.12. For Scala 2.12 you can safely ignore `RightProjection` and omit `.right`.
8
+ `Either` is a so-called [Monad](https://en.wikipedia.org/wiki/Monad_(functional_programming)) which covers a "computational aspect",
9
+ in this case error handling.
10
10
  Proper use of Monads can result in very concise yet elegant
11
11
  and readable code. Improper use can easily result in the contrary.
12
12
  Watch [this video](https://www.youtube.com/watch?v=Mw_Jnn_Y5iA) to learn more.
@@ -20,7 +20,7 @@ better have
20
20
  ```scala
21
21
  def add1(x: Int): Int = x + 1
22
22
  ```
23
- (there is `RightProjection.map` to apply such simple functions,
23
+ (there is `Either.map` to apply such simple functions,
24
24
  so you don't have to clutter them with `Either`).
25
25
  2. Don't "unwrap" if you don't really need to.
26
26
  Often there are built-in functions for your purpose. Indicators of premature
@@ -46,16 +46,16 @@ val xo: Either[String, Int] = ...
46
46
  val yo: Either[String, Int] = ...
47
47
  val zo: Either[String, Int] = ...
48
48
 
49
- xo.right.flatMap(x =>
50
- yo.right.flatMap(y =>
51
- zo.right.map(z =>
52
- x + y + z)))
49
+ xo.flatMap(x =>
50
+ yo.flatMap(y =>
51
+ zo.map(z =>
52
+ x + y + z)))
53
53
  ```
54
54
  better have
55
55
  ```scala
56
56
  for {
57
- x <- xo.right
58
- y <- yo.right
59
- z <- zo.right
57
+ x <- xo
58
+ y <- yo
59
+ z <- zo
60
60
  } yield x + y + z
61
61
  ```
@@ -1,3 +1,3 @@
1
- scalaVersion := "2.11.7"
1
+ scalaVersion := "2.12.1"
2
2
 
3
- libraryDependencies += "org.scalatest" % "scalatest_2.11" % "2.2.5" % "test"
3
+ libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.1" % "test"