trackler 2.1.0.27 → 2.1.0.28
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/common/CONTRIBUTING.md +9 -349
- data/common/exercises/forth/canonical-data.json +1 -7
- data/lib/trackler/version.rb +1 -1
- data/tracks/bash/config.json +5 -0
- data/tracks/bash/exercises/anagram/anagram_tests.sh +99 -0
- data/tracks/bash/exercises/anagram/example.sh +23 -0
- data/tracks/delphi/config.json +8 -1
- data/tracks/delphi/exercises/two-fer/twofer.dpr +60 -0
- data/tracks/delphi/exercises/two-fer/utwoferExample.pas +17 -0
- data/tracks/delphi/exercises/two-fer/utwoferTest.pas +71 -0
- data/tracks/dlang/README.md +9 -5
- data/tracks/dlang/bin/test-exercise +14 -5
- data/tracks/dlang/docs/INSTALLATION.md +24 -0
- data/tracks/dlang/docs/TESTS.md +6 -6
- data/tracks/dlang/exercises/bob/dub.sdl +2 -0
- data/tracks/dlang/exercises/bob/{bob_example.d → example/bob.d} +0 -5
- data/tracks/dlang/exercises/bob/{bob.d → source/bob.d} +0 -5
- data/tracks/dlang/exercises/circular-buffer/dub.sdl +2 -0
- data/tracks/dlang/exercises/circular-buffer/{circular_buffer_example.d → example/circular_buffer.d} +0 -5
- data/tracks/dlang/exercises/circular-buffer/{circular_buffer.d → source/circular_buffer.d} +0 -5
- data/tracks/dlang/exercises/crypto-square/dub.sdl +2 -0
- data/tracks/dlang/exercises/crypto-square/{crypto_square_example.d → example/crypto_square.d} +0 -5
- data/tracks/dlang/exercises/crypto-square/{crypto_square.d → source/crypto_square.d} +0 -5
- data/tracks/dlang/exercises/difference-of-squares/dub.sdl +2 -0
- data/tracks/dlang/exercises/difference-of-squares/{difference_of_squares_example.d → example/difference_of_squares.d} +0 -2
- data/tracks/dlang/exercises/difference-of-squares/{difference_of_squares.d → source/difference_of_squares.d} +0 -2
- data/tracks/dlang/exercises/etl/dub.sdl +2 -0
- data/tracks/dlang/exercises/etl/{etl_example.d → example/etl.d} +0 -5
- data/tracks/dlang/exercises/etl/{etl.d → source/etl.d} +0 -5
- data/tracks/dlang/exercises/gigasecond/dub.sdl +2 -0
- data/tracks/dlang/exercises/gigasecond/{gigasecond_example.d → example/gigasecond.d} +0 -2
- data/tracks/dlang/exercises/gigasecond/{gigasecond.d → source/gigasecond.d} +0 -2
- data/tracks/dlang/exercises/hamming/dub.sdl +2 -0
- data/tracks/dlang/exercises/hamming/{hamming_example.d → example/hamming.d} +0 -5
- data/tracks/dlang/exercises/hamming/{hamming.d → source/hamming.d} +0 -5
- data/tracks/dlang/exercises/hello-world/dub.sdl +2 -0
- data/tracks/dlang/exercises/hello-world/{hello_world_example.d → example/hello_world.d} +0 -2
- data/tracks/dlang/exercises/hello-world/{hello_world.d → source/hello_world.d} +0 -0
- data/tracks/dlang/exercises/leap/dub.sdl +2 -0
- data/tracks/dlang/exercises/leap/{leap_example.d → example/leap.d} +0 -2
- data/tracks/dlang/exercises/leap/{leap.d → source/leap.d} +0 -2
- data/tracks/dlang/exercises/nucleotide-count/dub.sdl +2 -0
- data/tracks/dlang/exercises/nucleotide-count/{nucleotide_count_example.d → example/nucleotide_count.d} +0 -4
- data/tracks/dlang/exercises/nucleotide-count/{nucleotide_count.d → source/nucleotide_count.d} +0 -4
- data/tracks/dlang/exercises/pangram/dub.sdl +2 -0
- data/tracks/dlang/exercises/pangram/{pangram_example.d → example/pangram.d} +0 -2
- data/tracks/dlang/exercises/pangram/{pangram.d → source/pangram.d} +0 -2
- data/tracks/dlang/exercises/raindrops/dub.sdl +2 -0
- data/tracks/dlang/exercises/raindrops/{raindrops_example.d → example/raindrops.d} +0 -2
- data/tracks/dlang/exercises/raindrops/{raindrops.d → source/raindrops.d} +0 -2
- data/tracks/dlang/exercises/react/dub.sdl +2 -0
- data/tracks/dlang/exercises/react/{react_example.d → example/react.d} +0 -2
- data/tracks/dlang/exercises/react/{react.d → source/react.d} +0 -2
- data/tracks/dlang/exercises/rna-transcription/dub.sdl +2 -0
- data/tracks/dlang/exercises/rna-transcription/{rna_transcription_example.d → example/rna_transcription.d} +0 -2
- data/tracks/dlang/exercises/rna-transcription/{rna_transcription.d → source/rna_transcription.d} +0 -2
- data/tracks/dlang/exercises/robot-name/dub.sdl +2 -0
- data/tracks/dlang/exercises/robot-name/{robot_name_example.d → example/robot_name.d} +0 -5
- data/tracks/dlang/exercises/robot-name/{robot_name.d → source/robot_name.d} +0 -4
- data/tracks/dlang/exercises/roman-numerals/dub.sdl +2 -0
- data/tracks/dlang/exercises/roman-numerals/{roman_numerals_example.d → example/roman_numerals.d} +0 -4
- data/tracks/dlang/exercises/roman-numerals/{roman_numerals.d → source/roman_numerals.d} +0 -4
- data/tracks/dlang/exercises/series/dub.sdl +2 -0
- data/tracks/dlang/exercises/series/{series_example.d → example/series.d} +0 -5
- data/tracks/dlang/exercises/series/{series.d → source/series.d} +0 -5
- data/tracks/dlang/exercises/triangle/dub.sdl +2 -0
- data/tracks/dlang/exercises/triangle/{triangle_example.d → example/triangle.d} +0 -5
- data/tracks/dlang/exercises/triangle/{triangle.d → source/triangle.d} +0 -5
- data/tracks/elisp/.github/stale.yml +0 -0
- data/tracks/elisp/exercises/grains/grains-test.el +12 -12
- data/tracks/elisp/exercises/robot-name/robot-name-test.el +8 -19
- data/tracks/elisp/exercises/word-count/word-count-test.el +27 -27
- data/tracks/fortran/Makefile +3 -2
- data/tracks/fortran/config.json +21 -2
- data/tracks/fortran/exercises/difference-of-squares/difference_of_squares.fun +42 -0
- data/tracks/fortran/exercises/difference-of-squares/example.f90 +35 -0
- data/tracks/fortran/exercises/{hello_world → hello-world}/example.f90 +0 -0
- data/tracks/fortran/exercises/{hello_world → hello-world}/hello_world.fun +0 -0
- data/tracks/fortran/exercises/raindrops/example.f90 +26 -0
- data/tracks/fortran/exercises/raindrops/raindrops.fun +78 -0
- data/tracks/fortran/exercises/rna-transcription/example.f90 +27 -0
- data/tracks/fortran/exercises/rna-transcription/rna_transcription.fun +38 -0
- data/tracks/go/exercises/acronym/.meta/gen.go +51 -0
- data/tracks/go/exercises/acronym/acronym_test.go +1 -15
- data/tracks/go/exercises/acronym/cases_test.go +37 -0
- data/tracks/go/exercises/acronym/example.go +1 -1
- data/tracks/go/exercises/secret-handshake/.meta/gen.go +49 -0
- data/tracks/go/exercises/secret-handshake/cases_test.go +24 -0
- data/tracks/go/exercises/secret-handshake/example.go +1 -1
- data/tracks/go/exercises/secret-handshake/secret_handshake_test.go +1 -17
- data/tracks/java/config.json +23 -23
- data/tracks/java/exercises/book-store/src/example/java/{Bookstore.java → BookStore.java} +5 -12
- data/tracks/java/exercises/book-store/src/test/java/BookStoreTest.java +113 -0
- data/tracks/java/exercises/saddle-points/src/example/java/Matrix.java +5 -4
- data/tracks/java/exercises/saddle-points/src/example/java/MatrixCoordinate.java +5 -5
- data/tracks/java/exercises/saddle-points/src/main/java/MatrixCoordinate.java +5 -5
- data/tracks/java/exercises/saddle-points/src/test/java/MatrixTest.java +10 -10
- data/tracks/purescript/config.json +7 -0
- data/tracks/purescript/exercises/hamming/bower.json +16 -0
- data/tracks/purescript/exercises/hamming/examples/src/Hamming.purs +14 -0
- data/tracks/purescript/exercises/hamming/test/Main.purs +46 -0
- data/tracks/scala/config.json +7 -0
- data/tracks/scala/exercises/bob/example.scala +3 -3
- data/tracks/scala/exercises/bob/src/main/scala/Bob.scala +2 -2
- data/tracks/scala/exercises/bob/src/test/scala/BobTest.scala +83 -53
- data/tracks/scala/exercises/book-store/build.sbt +3 -0
- data/tracks/scala/exercises/book-store/example.scala +49 -0
- data/tracks/scala/exercises/book-store/src/main/scala/.keep +0 -0
- data/tracks/scala/exercises/book-store/src/test/scala/BookStoreTest.scala +70 -0
- data/tracks/scala/exercises/difference-of-squares/example.scala +3 -3
- data/tracks/scala/exercises/difference-of-squares/src/main/scala/DifferenceOfSquares.scala +8 -0
- data/tracks/scala/exercises/difference-of-squares/src/test/scala/DifferenceOfSquaresTest.scala +49 -0
- data/tracks/scala/exercises/leap/example.scala +4 -3
- data/tracks/scala/exercises/leap/src/main/scala/Leap.scala +2 -2
- data/tracks/scala/exercises/leap/src/test/scala/LeapTest.scala +12 -20
- data/tracks/scala/exercises/raindrops/src/test/scala/RaindropsTest.scala +46 -35
- data/tracks/scala/testgen/src/main/scala/BobTestGenerator.scala +15 -0
- data/tracks/scala/testgen/src/main/scala/BookStoreTestGenerator.scala +15 -0
- data/tracks/scala/testgen/src/main/scala/DifferenceOfSquaresTestGenerator.scala +17 -0
- data/tracks/scala/testgen/src/main/scala/LeapTestGenerator.scala +15 -0
- data/tracks/scala/testgen/src/main/scala/RaindropsTestGenerator.scala +15 -0
- data/tracks/vimscript/config.json +5 -0
- data/tracks/vimscript/exercises/triangle/example.vim +28 -0
- data/tracks/vimscript/exercises/triangle/triangle.vader +92 -0
- data/tracks/vimscript/exercises/triangle/triangle.vim +24 -0
- metadata +93 -44
- data/tracks/java/exercises/book-store/src/test/java/BookstoreTest.java +0 -119
- data/tracks/scala/exercises/difference-of-squares/src/main/scala/Squares.scala +0 -8
- data/tracks/scala/exercises/difference-of-squares/src/test/scala/SquaresTest.scala +0 -56
@@ -0,0 +1,16 @@
|
|
1
|
+
{
|
2
|
+
"name": "hamming",
|
3
|
+
"ignore": [
|
4
|
+
"**/.*",
|
5
|
+
"node_modules",
|
6
|
+
"bower_components",
|
7
|
+
"output"
|
8
|
+
],
|
9
|
+
"dependencies": {
|
10
|
+
"purescript-prelude": "^3.0.0"
|
11
|
+
},
|
12
|
+
"devDependencies": {
|
13
|
+
"purescript-psci-support": "^3.0.0",
|
14
|
+
"purescript-test-unit": "^11.0.0"
|
15
|
+
}
|
16
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Hamming
|
2
|
+
( distance
|
3
|
+
) where
|
4
|
+
|
5
|
+
import Prelude
|
6
|
+
import Data.Maybe (Maybe(Just, Nothing))
|
7
|
+
import Data.Tuple (Tuple(..))
|
8
|
+
import Data.String (uncons)
|
9
|
+
|
10
|
+
distance :: String -> String -> Maybe Int
|
11
|
+
distance dna1 dna2 = case Tuple (uncons dna1) (uncons dna2) of
|
12
|
+
Tuple (Just {head: h1, tail: t1}) (Just {head: h2, tail: t2}) -> (if h1 /= h2 then ((+) 1) else id) <$> distance t1 t2
|
13
|
+
Tuple Nothing Nothing -> Just 0
|
14
|
+
Tuple _ _ -> Nothing
|
@@ -0,0 +1,46 @@
|
|
1
|
+
-- Test/exercise version: "1.0.0"
|
2
|
+
|
3
|
+
module Test.Main where
|
4
|
+
|
5
|
+
import Prelude
|
6
|
+
import Control.Monad.Eff (Eff)
|
7
|
+
import Test.Unit (suite, test)
|
8
|
+
import Test.Unit.Main (runTest)
|
9
|
+
import Test.Unit.Assert as Assert
|
10
|
+
import Data.String as String
|
11
|
+
import Data.Maybe (Maybe(Just, Nothing))
|
12
|
+
import Hamming (distance)
|
13
|
+
|
14
|
+
main :: Eff _ Unit
|
15
|
+
main = runTest do
|
16
|
+
suite "hamming" do
|
17
|
+
test "identical strands" $
|
18
|
+
Assert.equal (Just 0) (distance "A" "A")
|
19
|
+
test "long identical strands" $
|
20
|
+
Assert.equal (Just 0) (distance "GGACTGA" "GGACTGA")
|
21
|
+
test "complete distance in single nucleotide strands" $
|
22
|
+
Assert.equal (Just 1) (distance "A" "G")
|
23
|
+
test "complete distance in small strands" $
|
24
|
+
Assert.equal (Just 2) (distance "AG" "CT")
|
25
|
+
test "small distance in small strands" $
|
26
|
+
Assert.equal (Just 1) (distance "AT" "CT")
|
27
|
+
test "small distance" $
|
28
|
+
Assert.equal (Just 1) (distance "GGACG" "GGTCG")
|
29
|
+
test "small distance in long strands" $
|
30
|
+
Assert.equal (Just 2) (distance "ACCAGGG" "ACTATGG")
|
31
|
+
test "non-unique character in first strand" $
|
32
|
+
Assert.equal (Just 1) (distance "AGA" "AGG")
|
33
|
+
test "non-unique character in second strand" $
|
34
|
+
Assert.equal (Just 1) (distance "AGG" "AGA")
|
35
|
+
test "same nucleotides in different positions" $
|
36
|
+
Assert.equal (Just 2) (distance "TAG" "GAT")
|
37
|
+
test "large distance" $
|
38
|
+
Assert.equal (Just 4) (distance "GATACA" "GCATAA")
|
39
|
+
test "large distance in off-by-one strand" $
|
40
|
+
Assert.equal (Just 9) (distance "GGACGGATTCTG" "AGGACGGATTCT")
|
41
|
+
test "empty strands" $
|
42
|
+
Assert.equal (Just 0) (distance "" "")
|
43
|
+
test "disallow first strand longer" $
|
44
|
+
Assert.equal Nothing (distance "AATG" "AAA")
|
45
|
+
test "disallow second strand longer" $
|
46
|
+
Assert.equal Nothing (distance "ATA" "AGTG")
|
data/tracks/scala/config.json
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
def
|
1
|
+
object Bob {
|
2
|
+
def response(statement: String): String = statement match {
|
3
3
|
case Shouting() => "Whoa, chill out!"
|
4
4
|
case Question() => "Sure."
|
5
5
|
case Silence() => "Fine. Be that way!"
|
@@ -16,7 +16,7 @@ class Bob {
|
|
16
16
|
}
|
17
17
|
|
18
18
|
case object Question {
|
19
|
-
def unapply(statement: String) = statement.endsWith("?")
|
19
|
+
def unapply(statement: String) = statement.trim.endsWith("?")
|
20
20
|
}
|
21
21
|
|
22
22
|
case object Silence {
|
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
def
|
1
|
+
object Bob {
|
2
|
+
def response(statement: String): String = ???
|
3
3
|
}
|
@@ -1,102 +1,132 @@
|
|
1
|
-
import org.scalatest.
|
1
|
+
import org.scalatest.{Matchers, FunSuite}
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
/** @version 1.0.0 */
|
4
|
+
class BobTest extends FunSuite with Matchers {
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
response should be ("Whatever.")
|
6
|
+
test("stating something") {
|
7
|
+
Bob.response("Tom-ay-to, tom-aaaah-to.") should be ("Whatever.")
|
9
8
|
}
|
10
9
|
|
11
|
-
|
10
|
+
test("shouting") {
|
12
11
|
pending
|
13
|
-
|
14
|
-
response should be ("Whoa, chill out!")
|
12
|
+
Bob.response("WATCH OUT!") should be ("Whoa, chill out!")
|
15
13
|
}
|
16
14
|
|
17
|
-
|
15
|
+
test("shouting gibberish") {
|
18
16
|
pending
|
19
|
-
|
20
|
-
response should be ("Sure.")
|
17
|
+
Bob.response("FCECDFCAAB") should be ("Whoa, chill out!")
|
21
18
|
}
|
22
19
|
|
23
|
-
|
20
|
+
test("asking a question") {
|
24
21
|
pending
|
25
|
-
|
26
|
-
response should be ("Sure.")
|
22
|
+
Bob.response("Does this cryogenic chamber make me look fat?") should be ("Sure.")
|
27
23
|
}
|
28
24
|
|
29
|
-
|
25
|
+
test("asking a numeric question") {
|
30
26
|
pending
|
31
|
-
|
32
|
-
response should be ("Whatever.")
|
27
|
+
Bob.response("You are, what, like 15?") should be ("Sure.")
|
33
28
|
}
|
34
29
|
|
35
|
-
|
30
|
+
test("asking gibberish") {
|
36
31
|
pending
|
37
|
-
|
38
|
-
response should be ("Whatever.")
|
32
|
+
Bob.response("fffbbcbeab?") should be ("Sure.")
|
39
33
|
}
|
40
34
|
|
41
|
-
|
35
|
+
test("talking forcefully") {
|
42
36
|
pending
|
43
|
-
|
44
|
-
response should be ("Whoa, chill out!")
|
37
|
+
Bob.response("Let's go make out behind the gym!") should be ("Whatever.")
|
45
38
|
}
|
46
39
|
|
47
|
-
|
40
|
+
test("using acronyms in regular speech") {
|
48
41
|
pending
|
49
|
-
|
50
|
-
response should be ("Whoa, chill out!")
|
42
|
+
Bob.response("It's OK if you don't want to go to the DMV.") should be ("Whatever.")
|
51
43
|
}
|
52
44
|
|
53
|
-
|
45
|
+
test("forceful question") {
|
54
46
|
pending
|
55
|
-
|
56
|
-
response should be ("Whatever.")
|
47
|
+
Bob.response("WHAT THE HELL WERE YOU THINKING?") should be ("Whoa, chill out!")
|
57
48
|
}
|
58
49
|
|
59
|
-
|
50
|
+
test("shouting numbers") {
|
60
51
|
pending
|
61
|
-
|
62
|
-
response should be ("Sure.")
|
52
|
+
Bob.response("1, 2, 3 GO!") should be ("Whoa, chill out!")
|
63
53
|
}
|
64
54
|
|
65
|
-
|
55
|
+
test("only numbers") {
|
66
56
|
pending
|
67
|
-
|
68
|
-
response should be ("Whoa, chill out!")
|
57
|
+
Bob.response("1, 2, 3") should be ("Whatever.")
|
69
58
|
}
|
70
59
|
|
71
|
-
|
60
|
+
test("question with only numbers") {
|
72
61
|
pending
|
73
|
-
|
74
|
-
response should be ("Whatever.")
|
62
|
+
Bob.response("4?") should be ("Sure.")
|
75
63
|
}
|
76
64
|
|
77
|
-
|
65
|
+
test("shouting with special characters") {
|
78
66
|
pending
|
79
|
-
|
80
|
-
response should be ("Sure.")
|
67
|
+
Bob.response("ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!") should be ("Whoa, chill out!")
|
81
68
|
}
|
82
69
|
|
83
|
-
|
70
|
+
test("shouting with no exclamation mark") {
|
84
71
|
pending
|
85
|
-
|
86
|
-
response should be ("Fine. Be that way!")
|
72
|
+
Bob.response("I HATE YOU") should be ("Whoa, chill out!")
|
87
73
|
}
|
88
74
|
|
89
|
-
|
75
|
+
test("statement containing question mark") {
|
90
76
|
pending
|
91
|
-
|
92
|
-
response should be ("Fine. Be that way!")
|
77
|
+
Bob.response("Ending with ? means a question.") should be ("Whatever.")
|
93
78
|
}
|
94
79
|
|
95
|
-
|
80
|
+
test("non-letters with question") {
|
96
81
|
pending
|
97
|
-
|
82
|
+
Bob.response(":) ?") should be ("Sure.")
|
83
|
+
}
|
84
|
+
|
85
|
+
test("prattling on") {
|
86
|
+
pending
|
87
|
+
Bob.response("Wait! Hang on. Are you going to be OK?") should be ("Sure.")
|
88
|
+
}
|
89
|
+
|
90
|
+
test("silence") {
|
91
|
+
pending
|
92
|
+
Bob.response("") should be ("Fine. Be that way!")
|
93
|
+
}
|
94
|
+
|
95
|
+
test("prolonged silence") {
|
96
|
+
pending
|
97
|
+
Bob.response(" ") should be ("Fine. Be that way!")
|
98
|
+
}
|
99
|
+
|
100
|
+
test("alternate silence") {
|
101
|
+
pending
|
102
|
+
Bob.response(" ") should be ("Fine. Be that way!")
|
103
|
+
}
|
104
|
+
|
105
|
+
test("multiple line question") {
|
106
|
+
pending
|
107
|
+
Bob.response("""
|
98
108
|
Does this cryogenic chamber make me look fat?
|
99
|
-
no""")
|
100
|
-
|
109
|
+
no""") should be ("Whatever.")
|
110
|
+
}
|
111
|
+
|
112
|
+
test("starting with whitespace") {
|
113
|
+
pending
|
114
|
+
Bob.response(" hmmmmmmm...") should be ("Whatever.")
|
115
|
+
}
|
116
|
+
|
117
|
+
test("ending with whitespace") {
|
118
|
+
pending
|
119
|
+
Bob.response("Okay if like my spacebar quite a bit? ") should be ("Sure.")
|
120
|
+
}
|
121
|
+
|
122
|
+
test("other whitespace") {
|
123
|
+
pending
|
124
|
+
Bob.response("""
|
125
|
+
""") should be ("Fine. Be that way!")
|
126
|
+
}
|
127
|
+
|
128
|
+
test("non-question ending with whitespace") {
|
129
|
+
pending
|
130
|
+
Bob.response("This is a statement ending with whitespace ") should be ("Whatever.")
|
101
131
|
}
|
102
|
-
}
|
132
|
+
}
|
@@ -0,0 +1,49 @@
|
|
1
|
+
object BookStore {
|
2
|
+
private val bookPrice = 8
|
3
|
+
private val discounts =
|
4
|
+
Map((1, 0.0),
|
5
|
+
(2, 5.0),
|
6
|
+
(3, 10.0),
|
7
|
+
(4, 20.0),
|
8
|
+
(5, 25.0))
|
9
|
+
|
10
|
+
def total(books: List[Int]): Double = total(books, 0)
|
11
|
+
|
12
|
+
private def total(books: List[Int], acc: Double): Double = {
|
13
|
+
if (books.isEmpty) {
|
14
|
+
acc
|
15
|
+
} else {
|
16
|
+
val bookNums = books.distinct
|
17
|
+
|
18
|
+
(1 to bookNums.size).foldLeft(Double.MaxValue)((minPrice, groupSize) => {
|
19
|
+
val itemsToRemove = bookNums.take(groupSize)
|
20
|
+
val remainingBooks = getRemainingBooks(books, itemsToRemove)
|
21
|
+
val price = total(remainingBooks, acc + groupCost(groupSize))
|
22
|
+
scala.math.min(price, minPrice)
|
23
|
+
})
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
private def groupCost(groupSize: Int): Double = {
|
28
|
+
discounts get groupSize match {
|
29
|
+
case Some(discount) => bookPrice * groupSize * (100.0 - discount) / 100.0
|
30
|
+
case _ => bookPrice * groupSize
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
private def getRemainingBooks(books: List[Int], itemsToRemove: List[Int]): List[Int] = {
|
35
|
+
var remainingBooks = books
|
36
|
+
|
37
|
+
for (item <- itemsToRemove) {
|
38
|
+
remainingBooks = removeFirst(remainingBooks)(_ == item)
|
39
|
+
}
|
40
|
+
|
41
|
+
remainingBooks
|
42
|
+
}
|
43
|
+
|
44
|
+
// drops the first item in the passed in list that matches the predicate.
|
45
|
+
private def removeFirst[T](list: List[T])(pred: (T) => Boolean): List[T] = {
|
46
|
+
val (before, atAndAfter) = list span (x => !pred(x))
|
47
|
+
before ::: atAndAfter.drop(1)
|
48
|
+
}
|
49
|
+
}
|
File without changes
|
@@ -0,0 +1,70 @@
|
|
1
|
+
|
2
|
+
import org.scalatest.{Matchers, FunSuite}
|
3
|
+
|
4
|
+
/** @version 1.0.1 */
|
5
|
+
class BookStoreTest extends FunSuite with Matchers {
|
6
|
+
|
7
|
+
test("Only a single book") {
|
8
|
+
BookStore.total(List(1)) should be (8)
|
9
|
+
}
|
10
|
+
|
11
|
+
test("Two of the same book") {
|
12
|
+
pending
|
13
|
+
BookStore.total(List(2, 2)) should be (16)
|
14
|
+
}
|
15
|
+
|
16
|
+
test("Empty basket") {
|
17
|
+
pending
|
18
|
+
BookStore.total(List()) should be (0)
|
19
|
+
}
|
20
|
+
|
21
|
+
test("Two different books") {
|
22
|
+
pending
|
23
|
+
BookStore.total(List(1, 2)) should be (15.2)
|
24
|
+
}
|
25
|
+
|
26
|
+
test("Three different books") {
|
27
|
+
pending
|
28
|
+
BookStore.total(List(1, 2, 3)) should be (21.6)
|
29
|
+
}
|
30
|
+
|
31
|
+
test("Four different books") {
|
32
|
+
pending
|
33
|
+
BookStore.total(List(1, 2, 3, 4)) should be (25.6)
|
34
|
+
}
|
35
|
+
|
36
|
+
test("Five different books") {
|
37
|
+
pending
|
38
|
+
BookStore.total(List(1, 2, 3, 4, 5)) should be (30)
|
39
|
+
}
|
40
|
+
|
41
|
+
test("Two groups of four is cheaper than group of five plus group of three") {
|
42
|
+
pending
|
43
|
+
BookStore.total(List(1, 1, 2, 2, 3, 3, 4, 5)) should be (51.2)
|
44
|
+
}
|
45
|
+
|
46
|
+
test("Group of four plus group of two is cheaper than two groups of three") {
|
47
|
+
pending
|
48
|
+
BookStore.total(List(1, 1, 2, 2, 3, 4)) should be (40.8)
|
49
|
+
}
|
50
|
+
|
51
|
+
test("Two each of first 4 books and 1 copy each of rest") {
|
52
|
+
pending
|
53
|
+
BookStore.total(List(1, 1, 2, 2, 3, 3, 4, 4, 5)) should be (55.6)
|
54
|
+
}
|
55
|
+
|
56
|
+
test("Two copies of each book") {
|
57
|
+
pending
|
58
|
+
BookStore.total(List(1, 1, 2, 2, 3, 3, 4, 4, 5, 5)) should be (60)
|
59
|
+
}
|
60
|
+
|
61
|
+
test("Three copies of first book and 2 each of remaining") {
|
62
|
+
pending
|
63
|
+
BookStore.total(List(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 1)) should be (68)
|
64
|
+
}
|
65
|
+
|
66
|
+
test("Three each of first 2 books and 2 each of remaining books") {
|
67
|
+
pending
|
68
|
+
BookStore.total(List(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 1, 2)) should be (75.2)
|
69
|
+
}
|
70
|
+
}
|
@@ -1,10 +1,10 @@
|
|
1
1
|
import scala.math.pow
|
2
2
|
|
3
|
-
object
|
3
|
+
object DifferenceOfSquares {
|
4
4
|
|
5
5
|
def sumOfSquares(n: Int): Int = n * (n + 1) * (2 * n + 1) / 6
|
6
6
|
|
7
|
-
def
|
7
|
+
def squareOfSum(n: Int): Int = pow((n * (n + 1) / 2), 2).toInt
|
8
8
|
|
9
|
-
def
|
9
|
+
def differenceOfSquares(n: Int): Int = squareOfSum(n) - sumOfSquares(n)
|
10
10
|
}
|