trackler 2.0.6.19 → 2.0.6.20
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/tracks/csharp/config.json +8 -0
- data/tracks/csharp/exercises/forth/Example.cs +257 -0
- data/tracks/csharp/exercises/forth/ForthTest.cs +134 -0
- data/tracks/fsharp/config.json +7 -1
- data/tracks/fsharp/exercises/exercises.fsproj +20 -0
- data/tracks/fsharp/exercises/lens-person/Example.fs +50 -0
- data/tracks/fsharp/exercises/lens-person/HINTS.md +2 -0
- data/tracks/fsharp/exercises/lens-person/LensPerson.fs +24 -0
- data/tracks/fsharp/exercises/lens-person/LensPersonTest.fs +43 -0
- data/tracks/fsharp/exercises/paket.references +2 -1
- data/tracks/fsharp/paket.dependencies +1 -0
- data/tracks/fsharp/paket.lock +1 -0
- data/tracks/javascript/exercises/{bob/bob.js → leap/leap.js} +3 -3
- data/tracks/julia/README.md +16 -0
- data/tracks/objective-c/config.json +17 -0
- data/tracks/objective-c/exercises/bracket-push/BracketPushExample.h +8 -0
- data/tracks/objective-c/exercises/bracket-push/BracketPushExample.m +386 -0
- data/tracks/objective-c/exercises/bracket-push/BracketPushTest.m +84 -0
- data/tracks/objective-c/exercises/sublist/SublistExample.h +7 -0
- data/tracks/objective-c/exercises/sublist/SublistExample.m +67 -0
- data/tracks/objective-c/exercises/sublist/SublistTest.m +139 -0
- data/tracks/objective-c/xcodeProject/ObjectiveC.xcodeproj/project.pbxproj +55 -2
- data/tracks/ocaml/exercises/dominoes/test.ml +11 -5
- data/tracks/ocaml/exercises/luhn/test.ml +3 -3
- data/tracks/ocaml/tools/test-generator/templates/dominoes/template.ml +11 -5
- data/tracks/pascal/config.json +1 -1
- data/tracks/pascal/docs/INSTALLATION.md +52 -0
- data/tracks/pascal/docs/img/00delphiwelcomepage.png +0 -0
- data/tracks/pascal/docs/img/01delphiclicktools.png +0 -0
- data/tracks/pascal/docs/img/02delphiclickoptions.png +0 -0
- data/tracks/pascal/docs/img/03delphioptionsenvironmentvariables.png +0 -0
- data/tracks/pascal/docs/img/04delphioptionsenvironmentvariablesclicknew.png +0 -0
- data/tracks/pascal/docs/img/05delphinewuservariable.png +0 -0
- data/tracks/pascal/docs/img/06delphioptionslibrary.png +0 -0
- data/tracks/pascal/docs/img/07delphiclicklibrarypathbutton.png +0 -0
- data/tracks/pascal/docs/img/08delphidirectoriesinputvarnameclickadd.png +0 -0
- data/tracks/pascal/docs/img/09delphidirectoriesclickok.png +0 -0
- data/tracks/pascal/docs/img/10delphioptonsclickok.png +0 -0
- data/tracks/pascal/exercises/nucleotide-count/uNucleotideCountExample.pas +9 -18
- data/tracks/pascal/exercises/nucleotide-count/uNucleotideCountTest.pas +16 -16
- data/tracks/php/config.json +7 -0
- data/tracks/php/exercises/book-store/book-store_test.php +146 -0
- data/tracks/php/exercises/book-store/example.php +38 -0
- data/tracks/swift/docs/TESTS.md +40 -35
- data/tracks/swift/docs/img/tests-fail.png +0 -0
- data/tracks/swift/docs/img/tests-pass.png +0 -0
- data/tracks/swift/docs/img/tests.png +0 -0
- metadata +28 -3
@@ -6,7 +6,7 @@ let assert_valid expected input _test_ctxt =
|
|
6
6
|
assert_equal ~printer:Bool.to_string expected (valid input)
|
7
7
|
|
8
8
|
let tests = [
|
9
|
-
"single digit strings
|
9
|
+
"single digit strings can not be valid" >::
|
10
10
|
assert_valid false "1";
|
11
11
|
"A single zero is invalid" >::
|
12
12
|
assert_valid false "0";
|
@@ -16,8 +16,8 @@ let tests = [
|
|
16
16
|
assert_valid false "046 454 287";
|
17
17
|
"invalid credit card" >::
|
18
18
|
assert_valid false "8273 1232 7352 0569";
|
19
|
-
"strings
|
20
|
-
assert_valid false "
|
19
|
+
"valid strings with a non-digit added become invalid" >::
|
20
|
+
assert_valid false "046a 454 286";
|
21
21
|
]
|
22
22
|
|
23
23
|
let () =
|
@@ -4,16 +4,22 @@ open Dominoes
|
|
4
4
|
|
5
5
|
let print_dominoe (d1, d2) = sprintf "(%d,%d)" d1 d2
|
6
6
|
|
7
|
+
let dominoes_printer xs = "[" ^ String.concat ~sep:";" (List.map xs ~f:print_dominoe) ^ "]"
|
7
8
|
let option_printer = function
|
8
9
|
| None -> "None"
|
9
|
-
| Some xs -> "Some
|
10
|
+
| Some xs -> "Some " ^ dominoes_printer xs
|
10
11
|
|
11
|
-
let
|
12
|
+
let rotate_1 xs = List.tl_exn xs @ [List.hd_exn xs]
|
12
13
|
|
13
|
-
let
|
14
|
+
let norm l =
|
15
|
+
let norm1 (x, y) = if x > y then (y, x) else (x, y) in
|
16
|
+
List.map ~f:norm1 l |> List.sort ~cmp:compare
|
17
|
+
|
18
|
+
let check_chain (input: dominoe list) (chained: dominoe list) =
|
19
|
+
assert_equal (norm input) (norm chained) ~printer:dominoes_printer ~msg:"chain doesn't use the same dominoes as the input";
|
14
20
|
let assert_dominoes_match d1 d2 =
|
15
21
|
if snd d1 <> fst d2 then failwith @@ sprintf "%s and %s cannot be chained together" (print_dominoe d1) (print_dominoe d2) else () in
|
16
|
-
let consecutives = List.zip_exn
|
22
|
+
let consecutives = List.zip_exn chained (rotate_1 chained) in
|
17
23
|
List.iter consecutives ~f:(fun (d1, d2) -> assert_dominoes_match d1 d2)
|
18
24
|
|
19
25
|
let assert_empty c = if List.is_empty c then () else failwith "Expected 0 length chain"
|
@@ -21,7 +27,7 @@ let assert_empty c = if List.is_empty c then () else failwith "Expected 0 length
|
|
21
27
|
let assert_valid_chain input _ctxt =
|
22
28
|
match chain input with
|
23
29
|
| None -> failwith "Expecting a chain"
|
24
|
-
| Some(c) -> (if List.is_empty input then assert_empty else check_chain) c
|
30
|
+
| Some(c) -> (if List.is_empty input then assert_empty else check_chain input) c
|
25
31
|
|
26
32
|
let assert_no_chain input _ctxt =
|
27
33
|
assert_equal None (chain input) ~printer:option_printer
|
data/tracks/pascal/config.json
CHANGED
@@ -17,4 +17,56 @@ With Delphi successfully installed, and working correctly, please follow these s
|
|
17
17
|
- 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).
|
18
18
|
- The Starter Edition of Delphi doesn't allow the use of project experts. DUnitX comes with an expert which will aid the student in creating a new DUnitX based project. The expert creates the project's .DPR file. The exercises in this track all include the .DPR file making the expert not necessary. DUnitX otherwise has no issues with projects created in Delphi versions starting with XE all the way up to and including the Starter Edition of Berlin.
|
19
19
|
|
20
|
+
### Delphi Configuration for DunitX ###
|
21
|
+
|
22
|
+
If you had to install DUnitX because your installation didn't already come with it then please follow the following illustrated steps to make the necessary configuration changes to Delphi in order for it to locate your installation of DUnitX.
|
23
|
+
|
24
|
+
*Note: it is assumed that you have completed the installation of Delphi by this point.*
|
25
|
+
|
26
|
+
- Start Delphi. If your installation is new you will most likely end up at a Welcome Page similar to this.
|
27
|
+
|
28
|
+
![Welcome Page](http://x.exercism.io/v3/tracks/pascal/docs/img/00delphiwelcomepage.png)
|
29
|
+
|
30
|
+
- Find and click `Tools` along the top menu.
|
31
|
+
|
32
|
+
![Tools](http://x.exercism.io/v3/tracks/pascal/docs/img/01delphiclicktools.png)
|
33
|
+
|
34
|
+
- Click `Options`.
|
35
|
+
|
36
|
+
![Options](http://x.exercism.io/v3/tracks/pascal/docs/img/02delphiclickoptions.png)
|
37
|
+
|
38
|
+
- Along the left side of the Options screen find and click on `Environment Variables`.
|
39
|
+
|
40
|
+
![Options Screen Environment Variables](http://x.exercism.io/v3/tracks/pascal/docs/img/03delphioptionsenvironmentvariables.png)
|
41
|
+
|
42
|
+
- Click the `New` button located in the `User overrides` group
|
43
|
+
|
44
|
+
![Click New](http://x.exercism.io/v3/tracks/pascal/docs/img/04delphioptionsenvironmentvariablesclicknew.png)
|
45
|
+
|
46
|
+
- A New User Variable window should appear that contains two fields. In the top field enter `DUNITX` for the Variable Name. In the bottom field enter the complete path to your copy of DUnitX, for example mine is `C:\Program Files\Embarcadero\Studio\18.0\source\DUnitX`. Click the `Ok` button to then close this window.
|
47
|
+
|
48
|
+
![New User Variable](http://x.exercism.io/v3/tracks/pascal/docs/img/05delphinewuservariable.png)
|
49
|
+
|
50
|
+
- Locate and click on `Library` along the left side of the Options screen.
|
51
|
+
|
52
|
+
![Library](http://x.exercism.io/v3/tracks/pascal/docs/img/06delphioptionslibrary.png)
|
53
|
+
|
54
|
+
- Click the `...` button associated with the Library path in the Directories group
|
55
|
+
|
56
|
+
![...button](http://x.exercism.io/v3/tracks/pascal/docs/img/07delphiclicklibrarypathbutton.png)
|
57
|
+
|
58
|
+
- In the Directories window enter the variable name that you created a few steps ago. The entry should appear like this `$(DUNITX)`
|
59
|
+
|
60
|
+
![Directories](http://x.exercism.io/v3/tracks/pascal/docs/img/08delphidirectoriesinputvarnameclickadd.png)
|
61
|
+
|
62
|
+
- Click the `Add` button to add this new item to the list.
|
63
|
+
|
64
|
+
- Click the `Ok` button to store the change.
|
65
|
+
|
66
|
+
![ClickOK](http://x.exercism.io/v3/tracks/pascal/docs/img/09delphidirectoriesclickok.png)
|
67
|
+
|
68
|
+
- Finally, click the `Ok` button on the Options window to save all the changes.
|
69
|
+
|
70
|
+
Delphi will now be able to locate units that pertain to the DUnitX testing framework library.
|
71
|
+
|
20
72
|
*Note: It is assumed that Delphi versions XE and higher are being utilized by the student.*
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -6,33 +6,19 @@ uses SysUtils, System.Generics.Collections;
|
|
6
6
|
type
|
7
7
|
EInvalidNucleotideException = class(Exception);
|
8
8
|
|
9
|
-
|
10
|
-
['{AE218E73-90BB-4445-B40E-D8693CA54E2F}']
|
11
|
-
function Count(aChar: char): integer;
|
12
|
-
function GetNucleotideCounts: TDictionary<char, integer>;
|
13
|
-
property NucleotideCounts: TDictionary<char, integer> read GetNucleotideCounts;
|
14
|
-
end;
|
15
|
-
|
16
|
-
function NewDNA(aSequence: string): IDNA;
|
17
|
-
|
18
|
-
implementation
|
19
|
-
|
20
|
-
type
|
21
|
-
TDNA = class(TInterfacedObject, IDNA)
|
9
|
+
TDNA = class
|
22
10
|
private
|
23
11
|
fNucleotideCounts: TDictionary<char, integer>;
|
24
|
-
protected
|
25
12
|
function GetNucleotideCounts: TDictionary<char, integer>;
|
26
13
|
public
|
27
14
|
constructor create(aSequence: string);
|
15
|
+
destructor destroy;
|
28
16
|
function Count(aChar: char): integer;
|
29
17
|
property NucleotideCounts: TDictionary<char, integer> read GetNucleotideCounts;
|
30
18
|
end;
|
31
19
|
|
32
|
-
|
33
|
-
|
34
|
-
result := TDNA.create(aSequence);
|
35
|
-
end;
|
20
|
+
implementation
|
21
|
+
|
36
22
|
|
37
23
|
constructor TDNA.create(aSequence: string);
|
38
24
|
var NucleotideList: TList<TPair<char, integer>>;
|
@@ -57,6 +43,11 @@ begin
|
|
57
43
|
end;
|
58
44
|
end;
|
59
45
|
|
46
|
+
destructor TDNA.Destroy;
|
47
|
+
begin
|
48
|
+
fNucleotideCounts.Free;
|
49
|
+
end;
|
50
|
+
|
60
51
|
function TDNA.GetNucleotideCounts: TDictionary<char, integer>;
|
61
52
|
begin
|
62
53
|
result := fNucleotideCounts;
|
@@ -81,7 +81,7 @@ begin
|
|
81
81
|
end;
|
82
82
|
|
83
83
|
procedure NucleoTideCountTest.Has_no_nucleotides;
|
84
|
-
var dna:
|
84
|
+
var dna: TDNA;
|
85
85
|
expected: TDictionary<char, integer>;
|
86
86
|
begin
|
87
87
|
expected := TDictionary<char, integer>.Create;
|
@@ -90,33 +90,33 @@ begin
|
|
90
90
|
expected.Add('C',0);
|
91
91
|
expected.Add('G',0);
|
92
92
|
|
93
|
-
dna :=
|
93
|
+
dna := TDNA.Create('');
|
94
94
|
|
95
95
|
CompareDictionaries(expected, dna.NucleotideCounts);
|
96
96
|
end;
|
97
97
|
|
98
98
|
procedure NucleoTideCountTest.Has_no_adenosine;
|
99
|
-
var dna:
|
99
|
+
var dna: TDNA;
|
100
100
|
inStr: string;
|
101
101
|
begin
|
102
102
|
inStr := '';
|
103
|
-
dna :=
|
103
|
+
dna := TDNA.Create(inStr);
|
104
104
|
|
105
105
|
Assert.AreEqual(length(inStr), dna.Count('A'));
|
106
106
|
end;
|
107
107
|
|
108
108
|
procedure NucleoTideCountTest.Repetitive_cytidine_gets_counts;
|
109
|
-
var dna:
|
109
|
+
var dna: TDNA;
|
110
110
|
inStr: string;
|
111
111
|
begin
|
112
112
|
inStr := 'CCCCC';
|
113
|
-
dna :=
|
113
|
+
dna := TDNA.Create(inStr);
|
114
114
|
|
115
115
|
Assert.AreEqual(length(inStr), dna.Count('C'));
|
116
116
|
end;
|
117
117
|
|
118
118
|
procedure NucleoTideCountTest.Repetitive_sequence_has_only_guanosine;
|
119
|
-
var dna:
|
119
|
+
var dna: TDNA;
|
120
120
|
expected: TDictionary<char, integer>;
|
121
121
|
inStr: string;
|
122
122
|
begin
|
@@ -127,27 +127,27 @@ begin
|
|
127
127
|
expected.Add('G',8);
|
128
128
|
inStr := 'GGGGGGGG';
|
129
129
|
|
130
|
-
dna :=
|
130
|
+
dna := TDNA.Create(inStr);
|
131
131
|
|
132
132
|
CompareDictionaries(expected, dna.NucleotideCounts);
|
133
133
|
end;
|
134
134
|
|
135
135
|
procedure NucleoTideCountTest.Counts_only_thymidine;
|
136
|
-
var dna:
|
136
|
+
var dna: TDNA;
|
137
137
|
inStr: string;
|
138
138
|
begin
|
139
139
|
inStr := 'GGGGTAACCCGG';
|
140
|
-
dna :=
|
140
|
+
dna := TDNA.Create(inStr);
|
141
141
|
|
142
142
|
Assert.AreEqual(length('T'), dna.Count('T'));
|
143
143
|
end;
|
144
144
|
|
145
145
|
procedure NucleoTideCountTest.Counts_a_nucleotide_only_once;
|
146
|
-
var dna:
|
146
|
+
var dna: TDNA;
|
147
147
|
inStr: string;
|
148
148
|
begin
|
149
149
|
inStr := 'GGTTGG';
|
150
|
-
dna :=
|
150
|
+
dna := TDNA.Create(inStr);
|
151
151
|
dna.Count('T');
|
152
152
|
|
153
153
|
Assert.AreEqual(2, dna.Count('T'));
|
@@ -157,11 +157,11 @@ procedure NucleoTideCountTest.Validates_nucleotides;
|
|
157
157
|
var MyProc: TTestLocalMethod;
|
158
158
|
begin
|
159
159
|
MyProc := procedure
|
160
|
-
var dna:
|
160
|
+
var dna: TDNA;
|
161
161
|
inStr: string;
|
162
162
|
begin
|
163
163
|
inStr := 'GGTTGG';
|
164
|
-
dna :=
|
164
|
+
dna := TDNA.Create(inStr);
|
165
165
|
dna.Count('X');
|
166
166
|
end;
|
167
167
|
|
@@ -169,7 +169,7 @@ begin
|
|
169
169
|
end;
|
170
170
|
|
171
171
|
procedure NucleoTideCountTest.Counts_all_nucleotides;
|
172
|
-
var dna:
|
172
|
+
var dna: TDNA;
|
173
173
|
expected: TDictionary<char, integer>;
|
174
174
|
inStr: string;
|
175
175
|
begin
|
@@ -180,7 +180,7 @@ begin
|
|
180
180
|
expected.Add('G',17);
|
181
181
|
inStr := 'AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC';
|
182
182
|
|
183
|
-
dna :=
|
183
|
+
dna := TDNA.Create(inStr);
|
184
184
|
|
185
185
|
CompareDictionaries(expected, dna.NucleotideCounts);
|
186
186
|
end;
|
data/tracks/php/config.json
CHANGED
@@ -0,0 +1,146 @@
|
|
1
|
+
<?php
|
2
|
+
|
3
|
+
include_once 'book-store.php';
|
4
|
+
|
5
|
+
/**
|
6
|
+
* Calculate lowest price for shopping basket only
|
7
|
+
* containing books from a single series. There is no
|
8
|
+
* discount advantage for having more than one copy of
|
9
|
+
* any single book in a grouping.
|
10
|
+
*/
|
11
|
+
|
12
|
+
class BookStoreTest extends PHPUnit_Framework_TestCase
|
13
|
+
{
|
14
|
+
|
15
|
+
/**
|
16
|
+
* A basket containing only a single book.
|
17
|
+
* Target grouping: [[1]]
|
18
|
+
*/
|
19
|
+
public function testSingleBook()
|
20
|
+
{
|
21
|
+
$basket = [1];
|
22
|
+
$this->assertEquals(8.0, total($basket));
|
23
|
+
}
|
24
|
+
|
25
|
+
/**
|
26
|
+
* A basket containing only two of the same book.
|
27
|
+
* Target grouping: [[2], [2]]
|
28
|
+
*/
|
29
|
+
public function testTwoSame()
|
30
|
+
{
|
31
|
+
$basket = [2, 2];
|
32
|
+
$this->assertEquals(16.0, total($basket));
|
33
|
+
}
|
34
|
+
|
35
|
+
/**
|
36
|
+
* No charge to carry around an empty basket.
|
37
|
+
* Target grouping: []
|
38
|
+
*/
|
39
|
+
public function testEmpty()
|
40
|
+
{
|
41
|
+
$basket = [];
|
42
|
+
$this->assertEquals(0.0, total($basket));
|
43
|
+
}
|
44
|
+
|
45
|
+
/**
|
46
|
+
* A basket containing only two different books.
|
47
|
+
* Target grouping: [[1, 2]]
|
48
|
+
*/
|
49
|
+
public function testTwoDifferent()
|
50
|
+
{
|
51
|
+
$basket = [1, 2];
|
52
|
+
$this->assertEquals(15.2, total($basket));
|
53
|
+
}
|
54
|
+
|
55
|
+
/**
|
56
|
+
* A basket of three different books.
|
57
|
+
* Target grouping: [[1, 2, 3]]
|
58
|
+
*/
|
59
|
+
public function testThreeDifferent()
|
60
|
+
{
|
61
|
+
$basket = [1, 2, 3];
|
62
|
+
$this->assertEquals(21.60, total($basket));
|
63
|
+
}
|
64
|
+
|
65
|
+
/**
|
66
|
+
* A basket of four different books.
|
67
|
+
* Target grouping: [[1, 2, 3, 4]]
|
68
|
+
*/
|
69
|
+
public function testFourDifferent()
|
70
|
+
{
|
71
|
+
$basket = [1, 2, 3, 4];
|
72
|
+
$this->assertEquals(25.60, total($basket));
|
73
|
+
}
|
74
|
+
|
75
|
+
/**
|
76
|
+
* A basket of five different books.
|
77
|
+
* Target grouping: [[1, 2, 3, 4, 5]]
|
78
|
+
*/
|
79
|
+
public function testFiveDifferent()
|
80
|
+
{
|
81
|
+
$basket = [1, 2, 3, 4, 5];
|
82
|
+
$this->assertEquals(30.00, total($basket));
|
83
|
+
}
|
84
|
+
|
85
|
+
/**
|
86
|
+
* A basket containing eight books consisting of a
|
87
|
+
* pair each of the first three books plus one copy
|
88
|
+
* each of the last two books. Please pay careful
|
89
|
+
* attention to this particular target grouping, it
|
90
|
+
* is not intuitive, but does grant the largest
|
91
|
+
* discount.
|
92
|
+
* Target grouping: [[1, 2, 3, 4], [1, 2, 3, 5]]
|
93
|
+
*/
|
94
|
+
public function testEight()
|
95
|
+
{
|
96
|
+
$basket = [1, 1, 2, 2, 3, 3, 4, 5];
|
97
|
+
$this->assertEquals(51.20, total($basket));
|
98
|
+
}
|
99
|
+
|
100
|
+
/**
|
101
|
+
* A basket containing nine books consisting of a
|
102
|
+
* pair each of the first four books plus one of
|
103
|
+
* the last book.
|
104
|
+
* Target grouping: [[1, 2, 3, 4, 5], [1, 2, 3, 4]],
|
105
|
+
*/
|
106
|
+
public function testFourPairsPlusOne()
|
107
|
+
{
|
108
|
+
$basket = [1, 1, 2, 2, 3, 3, 4, 4, 5];
|
109
|
+
$this->assertEquals(55.60, total($basket));
|
110
|
+
}
|
111
|
+
|
112
|
+
/**
|
113
|
+
* A basket containing ten books consisting of two
|
114
|
+
* copies of each book in the series.
|
115
|
+
* Target grouping: [[1, 2, 3, 4, 5], [1, 2, 3, 4, 5]]
|
116
|
+
*/
|
117
|
+
public function testFivePairs()
|
118
|
+
{
|
119
|
+
$basket = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5];
|
120
|
+
$this->assertEquals(60.00, total($basket));
|
121
|
+
}
|
122
|
+
|
123
|
+
/**
|
124
|
+
* A basket containing eleven books consisting
|
125
|
+
* of three copies of the first book plus two each
|
126
|
+
* of the remaining four books in the series.
|
127
|
+
* Target grouping: [[1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1]]
|
128
|
+
*/
|
129
|
+
public function testFivePairsPlusOne()
|
130
|
+
{
|
131
|
+
$basket = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 1];
|
132
|
+
$this->assertEquals(68.00, total($basket));
|
133
|
+
}
|
134
|
+
|
135
|
+
/**
|
136
|
+
* A basket containing twelve books consisting of
|
137
|
+
* three copies of the first two books, plus two
|
138
|
+
* each of the remaining three books in the series.
|
139
|
+
* Target grouping: [[1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2]]
|
140
|
+
*/
|
141
|
+
public function testTwelve()
|
142
|
+
{
|
143
|
+
$basket = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 1, 2];
|
144
|
+
$this->assertEquals(75.20, total($basket));
|
145
|
+
}
|
146
|
+
}
|