trackler 2.2.1.86 → 2.2.1.87
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/problem-specifications/exercises/reverse-string/metadata.yml +0 -1
- data/tracks/bash/CONTRIBUTING.md +129 -28
- data/tracks/bash/config/exercise_readme.go.tmpl +10 -4
- data/tracks/bash/exercises/acronym/README.md +8 -11
- data/tracks/bash/exercises/acronym/{acronym_tests.sh → acronym_test.sh} +0 -0
- data/tracks/bash/exercises/anagram/README.md +6 -1
- data/tracks/bash/exercises/anagram/anagram_test.sh +1 -1
- data/tracks/bash/exercises/armstrong-numbers/README.md +10 -2
- data/tracks/bash/exercises/atbash-cipher/README.md +6 -6
- data/tracks/bash/exercises/bob/README.md +8 -1
- data/tracks/bash/exercises/collatz-conjecture/README.md +11 -2
- data/tracks/bash/exercises/collatz-conjecture/{collatz_test.sh → collatz_conjecture_test.sh} +6 -6
- data/tracks/bash/exercises/difference-of-squares/README.md +6 -1
- data/tracks/bash/exercises/error-handling/README.md +13 -5
- data/tracks/bash/exercises/error-handling/error_handling_test.sh +18 -22
- data/tracks/bash/exercises/error-handling/example.sh +7 -6
- data/tracks/bash/exercises/gigasecond/.meta/hints.md +0 -5
- data/tracks/bash/exercises/gigasecond/README.md +36 -1
- data/tracks/bash/exercises/grains/README.md +10 -2
- data/tracks/bash/exercises/hamming/README.md +6 -1
- data/tracks/bash/exercises/hello-world/README.md +7 -2
- data/tracks/bash/exercises/leap/README.md +7 -2
- data/tracks/bash/exercises/luhn/README.md +7 -2
- data/tracks/bash/exercises/nucleotide-count/README.md +13 -22
- data/tracks/bash/exercises/pangram/README.md +7 -2
- data/tracks/bash/exercises/phone-number/README.md +10 -4
- data/tracks/bash/exercises/raindrops/README.md +6 -1
- data/tracks/bash/exercises/reverse-string/README.md +11 -2
- data/tracks/bash/exercises/rna-transcription/README.md +7 -2
- data/tracks/bash/exercises/roman-numerals/README.md +11 -2
- data/tracks/bash/exercises/triangle/README.md +5 -4
- data/tracks/bash/exercises/two-fer/README.md +7 -9
- data/tracks/bash/exercises/word-count/README.md +6 -2
- data/tracks/bash/exercises/word-count/example.sh +22 -13
- data/tracks/bash/scripts/canonical_data_check.sh +112 -0
- data/tracks/c/exercises/acronym/src/{example.h → acronym.h} +0 -0
- data/tracks/c/exercises/gigasecond/.meta/hints.md +124 -0
- data/tracks/c/exercises/gigasecond/README.md +126 -0
- data/tracks/c/exercises/isogram/src/{example.h → isogram.h} +0 -0
- data/tracks/c/exercises/meetup/.meta/hints.md +124 -0
- data/tracks/c/exercises/meetup/README.md +142 -12
- data/tracks/c/exercises/pangram/src/{example.h → pangram.h} +0 -0
- data/tracks/c/exercises/space-age/.meta/hints.md +124 -0
- data/tracks/c/exercises/space-age/README.md +127 -2
- data/tracks/elisp/bin/test-examples +11 -14
- data/tracks/elisp/config.json +9 -1
- data/tracks/elisp/exercises/acronym/README.md +13 -0
- data/tracks/elisp/exercises/acronym/acronym-test.el +28 -0
- data/tracks/elisp/exercises/acronym/acronym.el +11 -0
- data/tracks/elisp/exercises/acronym/example.el +14 -0
- data/tracks/elisp/exercises/bob/example.el +1 -3
- data/tracks/elisp/exercises/hamming/README.md +2 -0
- data/tracks/elisp/exercises/hamming/hamming-test.el +35 -12
- data/tracks/elisp/exercises/hamming/hamming.el +0 -3
- data/tracks/fsharp/exercises/custom-set/CustomSetTest.fs +206 -132
- data/tracks/fsharp/exercises/custom-set/Example.fs +2 -0
- data/tracks/fsharp/generators/Generators.fs +61 -0
- data/tracks/go/config.json +25 -2
- data/tracks/go/exercises/acronym/acronym_test.go +8 -0
- data/tracks/go/exercises/alphametics/.meta/gen.go +72 -0
- data/tracks/go/exercises/alphametics/.meta/hints.md +38 -0
- data/tracks/go/exercises/alphametics/README.md +93 -0
- data/tracks/go/exercises/alphametics/alphametics_test.go +33 -0
- data/tracks/go/exercises/alphametics/cases_test.go +59 -0
- data/tracks/go/exercises/alphametics/example.go +212 -0
- data/tracks/go/exercises/atbash-cipher/.meta/gen.go +6 -4
- data/tracks/go/exercises/atbash-cipher/cases_test.go +2 -2
- data/tracks/go/exercises/change/.meta/gen.go +7 -5
- data/tracks/go/exercises/change/cases_test.go +2 -2
- data/tracks/go/exercises/collatz-conjecture/.meta/gen.go +5 -3
- data/tracks/go/exercises/collatz-conjecture/cases_test.go +2 -2
- data/tracks/go/exercises/connect/.meta/gen.go +5 -3
- data/tracks/go/exercises/connect/cases_test.go +2 -2
- data/tracks/go/exercises/flatten-array/.meta/gen.go +5 -3
- data/tracks/go/exercises/flatten-array/cases_test.go +2 -2
- data/tracks/go/exercises/meetup/.meta/gen.go +19 -8
- data/tracks/go/exercises/meetup/cases_test.go +2 -2
- data/tracks/go/exercises/simple-linked-list/README.md +47 -0
- data/tracks/go/exercises/simple-linked-list/example.go +74 -0
- data/tracks/go/exercises/simple-linked-list/linked_list_test.go +210 -0
- data/tracks/idris/config.json +2 -2
- data/tracks/java/exercises/all-your-base/.meta/src/reference/java/BaseConverter.java +1 -5
- data/tracks/java/exercises/all-your-base/.meta/version +1 -1
- data/tracks/java/exercises/all-your-base/src/test/java/BaseConverterTest.java +34 -10
- data/tracks/java/exercises/bob/README.md +2 -0
- data/tracks/java/exercises/kindergarten-garden/.meta/version +1 -0
- data/tracks/java/exercises/kindergarten-garden/src/test/java/KindergartenGardenTest.java +0 -55
- data/tracks/java/exercises/meetup/.meta/version +1 -0
- data/tracks/java/exercises/meetup/src/test/java/MeetupTest.java +32 -0
- data/tracks/java/exercises/parallel-letter-frequency/README.md +1 -0
- data/tracks/java/exercises/proverb/README.md +16 -10
- data/tracks/java/exercises/rail-fence-cipher/README.md +5 -6
- data/tracks/java/exercises/two-fer/README.md +1 -1
- data/tracks/java/exercises/word-search/.meta/version +1 -1
- data/tracks/java/exercises/word-search/src/test/java/WordSearcherTest.java +240 -2
- data/tracks/javascript/.eslintignore +0 -1
- data/tracks/javascript/exercises/palindrome-products/example.js +3 -3
- data/tracks/kotlin/docs/INSTALLATION.md +77 -68
- data/tracks/kotlin/docs/TESTS.md +41 -39
- data/tracks/perl6/exercises/acronym/acronym.t +20 -8
- data/tracks/perl6/exercises/acronym/example.yaml +1 -1
- data/tracks/perl6/exercises/all-your-base/all-your-base.t +108 -66
- data/tracks/perl6/exercises/all-your-base/example.yaml +2 -2
- data/tracks/perl6/exercises/allergies/allergies.t +39 -15
- data/tracks/perl6/exercises/allergies/example.yaml +2 -2
- data/tracks/perl6/exercises/anagram/anagram.t +73 -40
- data/tracks/perl6/exercises/anagram/example.yaml +1 -1
- data/tracks/perl6/exercises/atbash-cipher/atbash-cipher.t +38 -15
- data/tracks/perl6/exercises/atbash-cipher/example.yaml +1 -1
- data/tracks/perl6/exercises/bob/bob.t +77 -27
- data/tracks/perl6/exercises/bob/example.yaml +1 -1
- data/tracks/perl6/exercises/flatten-array/example.yaml +1 -1
- data/tracks/perl6/exercises/flatten-array/flatten-array.t +20 -8
- data/tracks/perl6/exercises/luhn/example.yaml +1 -1
- data/tracks/perl6/exercises/luhn/luhn.t +42 -16
- data/tracks/perl6/exercises/roman-numerals/README.md +68 -0
- data/tracks/php/exercises/gigasecond/gigasecond_test.php +1 -1
- data/tracks/python/docs/ABOUT.md +2 -2
- metadata +27 -10
- data/tracks/bash/docs/EXERCISE_README_INSERT.md +0 -3
- data/tracks/bash/exercises/word-count/example.awk +0 -12
- data/tracks/java/exercises/alphametics/src/main/java/.keep +0 -0
|
@@ -32,8 +32,10 @@ type js struct {
|
|
|
32
32
|
Cases []struct {
|
|
33
33
|
Description string
|
|
34
34
|
Property string
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
Input struct {
|
|
36
|
+
Phrase string
|
|
37
|
+
}
|
|
38
|
+
Expected string
|
|
37
39
|
}
|
|
38
40
|
}
|
|
39
41
|
}
|
|
@@ -50,9 +52,9 @@ type atbashTest struct {
|
|
|
50
52
|
|
|
51
53
|
var tests = []atbashTest {
|
|
52
54
|
{{range .J.Cases}} {{range .Cases}}{
|
|
53
|
-
{{if isEncode .Property}} s: {{printf "%q" .Phrase }},
|
|
55
|
+
{{if isEncode .Property}} s: {{printf "%q" .Input.Phrase }},
|
|
54
56
|
expected: {{printf "%q" .Expected }}, {{else}} s: {{printf "%q" .Expected }},
|
|
55
|
-
expected: {{printf "%q" .Phrase }}, {{- end}}
|
|
57
|
+
expected: {{printf "%q" .Input.Phrase }}, {{- end}}
|
|
56
58
|
},
|
|
57
59
|
{{end}}{{end}}
|
|
58
60
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
package atbash
|
|
2
2
|
|
|
3
3
|
// Source: exercism/problem-specifications
|
|
4
|
-
// Commit:
|
|
5
|
-
// Problem Specifications Version: 1.
|
|
4
|
+
// Commit: dda678b atbash-cipher: Apply new "input" policy
|
|
5
|
+
// Problem Specifications Version: 1.1.0
|
|
6
6
|
|
|
7
7
|
type atbashTest struct {
|
|
8
8
|
s string
|
|
@@ -31,9 +31,11 @@ type js struct {
|
|
|
31
31
|
type OneCase struct {
|
|
32
32
|
Description string
|
|
33
33
|
Property string
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
Input struct {
|
|
35
|
+
Coins []int
|
|
36
|
+
Target int
|
|
37
|
+
}
|
|
38
|
+
Expected interface{}
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
func (c OneCase) Valid() bool {
|
|
@@ -83,8 +85,8 @@ var testCases = []struct {
|
|
|
83
85
|
}{
|
|
84
86
|
{{range .J.Cases}}{
|
|
85
87
|
{{printf "%q" .Description}},
|
|
86
|
-
{{printf "%#v" .Coins}},
|
|
87
|
-
{{printf "%d" .Target}},
|
|
88
|
+
{{printf "%#v" .Input.Coins}},
|
|
89
|
+
{{printf "%d" .Input.Target}},
|
|
88
90
|
{{printf "%v" .Valid}},
|
|
89
91
|
{{printf "%#v" .IntSlice}},
|
|
90
92
|
},
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
package change
|
|
2
2
|
|
|
3
3
|
// Source: exercism/problem-specifications
|
|
4
|
-
// Commit:
|
|
5
|
-
// Problem Specifications Version: 1.
|
|
4
|
+
// Commit: 044d09a change: Apply new "input" policy
|
|
5
|
+
// Problem Specifications Version: 1.2.0
|
|
6
6
|
|
|
7
7
|
var testCases = []struct {
|
|
8
8
|
description string
|
|
@@ -20,8 +20,10 @@ func main() {
|
|
|
20
20
|
|
|
21
21
|
type OneCase struct {
|
|
22
22
|
Description string
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
Input struct {
|
|
24
|
+
Number int
|
|
25
|
+
}
|
|
26
|
+
Expected interface{}
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
// The JSON structure we expect to be able to unmarshal into
|
|
@@ -63,7 +65,7 @@ var testCases = []struct {
|
|
|
63
65
|
}{
|
|
64
66
|
{{range .J.Cases}}{
|
|
65
67
|
description: "{{.Description}}",
|
|
66
|
-
input: {{.Number}},
|
|
68
|
+
input: {{.Input.Number}},
|
|
67
69
|
{{if .Valid}} expected: {{.Answer}},
|
|
68
70
|
{{- else}} expectError: true,
|
|
69
71
|
{{- end}}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
package collatzconjecture
|
|
2
2
|
|
|
3
3
|
// Source: exercism/problem-specifications
|
|
4
|
-
// Commit:
|
|
5
|
-
// Problem Specifications Version: 1.
|
|
4
|
+
// Commit: 7bb0a64 collatz-conjecture: Apply new "input" policy
|
|
5
|
+
// Problem Specifications Version: 1.2.0
|
|
6
6
|
|
|
7
7
|
var testCases = []struct {
|
|
8
8
|
description string
|
|
@@ -22,8 +22,10 @@ func main() {
|
|
|
22
22
|
type js struct {
|
|
23
23
|
Cases []struct {
|
|
24
24
|
Description string
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
Input struct {
|
|
26
|
+
Board []string
|
|
27
|
+
}
|
|
28
|
+
Expected string
|
|
27
29
|
}
|
|
28
30
|
}
|
|
29
31
|
|
|
@@ -39,7 +41,7 @@ var testCases = []struct {
|
|
|
39
41
|
}{
|
|
40
42
|
{{range .J.Cases}}{
|
|
41
43
|
description: {{printf "%q" .Description}},
|
|
42
|
-
board: []string{ {{range $line := .Board}}{{printf "\n %q," $line}}{{end}}},
|
|
44
|
+
board: []string{ {{range $line := .Input.Board}}{{printf "\n %q," $line}}{{end}}},
|
|
43
45
|
expected: {{printf "%q" .Expected}},
|
|
44
46
|
},
|
|
45
47
|
{{end}}}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
package connect
|
|
2
2
|
|
|
3
3
|
// Source: exercism/problem-specifications
|
|
4
|
-
// Commit:
|
|
5
|
-
// Problem Specifications Version: 1.
|
|
4
|
+
// Commit: a02d64d connect: Apply new "input" policy
|
|
5
|
+
// Problem Specifications Version: 1.1.0
|
|
6
6
|
|
|
7
7
|
var testCases = []struct {
|
|
8
8
|
description string
|
|
@@ -29,8 +29,10 @@ type js struct {
|
|
|
29
29
|
type oneCase struct {
|
|
30
30
|
Description string
|
|
31
31
|
Property string
|
|
32
|
-
Input
|
|
33
|
-
|
|
32
|
+
Input struct {
|
|
33
|
+
Array interface{}
|
|
34
|
+
}
|
|
35
|
+
Expected []interface{}
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
// Template to generate test cases.
|
|
@@ -45,7 +47,7 @@ var testCases = []struct {
|
|
|
45
47
|
}{ {{range .J.Cases}}
|
|
46
48
|
{
|
|
47
49
|
description: {{printf "%q" .Description}},
|
|
48
|
-
input: {{printf "%#v" .Input}},
|
|
50
|
+
input: {{printf "%#v" .Input.Array}},
|
|
49
51
|
expected: {{printf "%#v" .Expected}},
|
|
50
52
|
},{{end}}
|
|
51
53
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
package flatten
|
|
2
2
|
|
|
3
3
|
// Source: exercism/problem-specifications
|
|
4
|
-
// Commit:
|
|
5
|
-
// Problem Specifications Version: 1.
|
|
4
|
+
// Commit: 0290376 flatten-array: Apply new "input" policy
|
|
5
|
+
// Problem Specifications Version: 1.2.0
|
|
6
6
|
|
|
7
7
|
var testCases = []struct {
|
|
8
8
|
description string
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
package main
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
|
+
"fmt"
|
|
4
5
|
"log"
|
|
5
6
|
"strings"
|
|
6
7
|
"text/template"
|
|
@@ -22,14 +23,24 @@ func main() {
|
|
|
22
23
|
|
|
23
24
|
// The JSON structure we expect to be able to unmarshal into
|
|
24
25
|
type js struct {
|
|
25
|
-
Cases []
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
Cases []OneCase
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
type OneCase struct {
|
|
30
|
+
Description string
|
|
31
|
+
Input struct {
|
|
32
|
+
Year int
|
|
33
|
+
Month int
|
|
34
|
+
Week string
|
|
35
|
+
Dayofweek string
|
|
32
36
|
}
|
|
37
|
+
DateString string `json:"expected"`
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
func (c OneCase) ExpectedDay() int {
|
|
41
|
+
var y, m, d int
|
|
42
|
+
fmt.Sscanf(c.DateString, "%4d-%2d-%2d", &y, &m, &d)
|
|
43
|
+
return d
|
|
33
44
|
}
|
|
34
45
|
|
|
35
46
|
// template applied to above data structure generates the Go test cases
|
|
@@ -46,6 +57,6 @@ var testCases = []struct {
|
|
|
46
57
|
weekday time.Weekday
|
|
47
58
|
expDay int
|
|
48
59
|
}{
|
|
49
|
-
{{range .J.Cases}}{ {{.Year}}, {{.Month}}, {{week .Week}}, time.{{.Dayofweek}}, {{.
|
|
60
|
+
{{range .J.Cases}}{ {{.Input.Year}}, {{.Input.Month}}, {{week .Input.Week}}, time.{{.Input.Dayofweek}}, {{.ExpectedDay}}}, // {{.Description}}
|
|
50
61
|
{{end}}}
|
|
51
62
|
`
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
package meetup
|
|
2
2
|
|
|
3
3
|
// Source: exercism/problem-specifications
|
|
4
|
-
// Commit:
|
|
5
|
-
// Problem Specifications Version: 1.
|
|
4
|
+
// Commit: 56cdfa5 meetup: Update json for new input policy
|
|
5
|
+
// Problem Specifications Version: 1.1.0
|
|
6
6
|
|
|
7
7
|
import "time"
|
|
8
8
|
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Simple Linked List
|
|
2
|
+
|
|
3
|
+
Write a simple linked list implementation that uses Elements and a List.
|
|
4
|
+
|
|
5
|
+
The linked list is a fundamental data structure in computer science,
|
|
6
|
+
often used in the implementation of other data structures. They're
|
|
7
|
+
pervasive in functional programming languages, such as Clojure, Erlang,
|
|
8
|
+
or Haskell, but far less common in imperative languages such as Ruby or
|
|
9
|
+
Python.
|
|
10
|
+
|
|
11
|
+
The simplest kind of linked list is a singly linked list. Each element in the
|
|
12
|
+
list contains data and a "next" field pointing to the next element in the list
|
|
13
|
+
of elements.
|
|
14
|
+
|
|
15
|
+
This variant of linked lists is often used to represent sequences or
|
|
16
|
+
push-down stacks (also called a LIFO stack; Last In, First Out).
|
|
17
|
+
|
|
18
|
+
As a first take, lets create a singly linked list to contain the range (1..10),
|
|
19
|
+
and provide functions to reverse a linked list and convert to and from arrays.
|
|
20
|
+
|
|
21
|
+
When implementing this in a language with built-in linked lists,
|
|
22
|
+
implement your own abstract data type.
|
|
23
|
+
|
|
24
|
+
## Running the tests
|
|
25
|
+
|
|
26
|
+
To run the tests run the command `go test` from within the exercise directory.
|
|
27
|
+
|
|
28
|
+
If the test suite contains benchmarks, you can run these with the `-bench`
|
|
29
|
+
flag:
|
|
30
|
+
|
|
31
|
+
go test -bench .
|
|
32
|
+
|
|
33
|
+
Keep in mind that each reviewer will run benchmarks on a different machine, with
|
|
34
|
+
different specs, so the results from these benchmark tests may vary.
|
|
35
|
+
|
|
36
|
+
## Further information
|
|
37
|
+
|
|
38
|
+
For more detailed information about the Go track, including how to get help if
|
|
39
|
+
you're having trouble, please visit the exercism.io [Go language page](http://exercism.io/languages/go/about).
|
|
40
|
+
|
|
41
|
+
## Source
|
|
42
|
+
|
|
43
|
+
Inspired by 'Data Structures and Algorithms with Object-Oriented Design Patterns in Ruby', singly linked-lists.
|
|
44
|
+
[http://www.brpreiss.com/books/opus8/html/page96.html#SECTION004300000000000000000](http://www.brpreiss.com/books/opus8/html/page96.html#SECTION004300000000000000000)
|
|
45
|
+
|
|
46
|
+
## Submitting Incomplete Solutions
|
|
47
|
+
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
package linkedlist
|
|
2
|
+
|
|
3
|
+
import "errors"
|
|
4
|
+
|
|
5
|
+
type element struct {
|
|
6
|
+
data int
|
|
7
|
+
next *element
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
type List struct {
|
|
11
|
+
head *element
|
|
12
|
+
size int
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
func New(array []int) *List {
|
|
16
|
+
var res List
|
|
17
|
+
for _, elem := range array {
|
|
18
|
+
res.Push(elem)
|
|
19
|
+
}
|
|
20
|
+
return &res
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
func (list *List) Size() int {
|
|
24
|
+
return list.size
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
func (list *List) Push(elem int) {
|
|
28
|
+
newNode := element{elem, nil}
|
|
29
|
+
if list.head == nil {
|
|
30
|
+
list.head = &newNode
|
|
31
|
+
} else {
|
|
32
|
+
node := list.head
|
|
33
|
+
for node.next != nil {
|
|
34
|
+
node = node.next
|
|
35
|
+
}
|
|
36
|
+
node.next = &newNode
|
|
37
|
+
}
|
|
38
|
+
list.size++
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
func (list *List) Pop() (int, error) {
|
|
42
|
+
var elem int
|
|
43
|
+
if list.size == 0 {
|
|
44
|
+
return 0, errors.New("Cannot call pop on empty list")
|
|
45
|
+
} else if list.size == 1 {
|
|
46
|
+
elem = list.head.data
|
|
47
|
+
list.head = nil
|
|
48
|
+
} else {
|
|
49
|
+
node := list.head
|
|
50
|
+
for node.next.next != nil {
|
|
51
|
+
node = node.next
|
|
52
|
+
}
|
|
53
|
+
elem = node.next.data
|
|
54
|
+
node.next = nil
|
|
55
|
+
}
|
|
56
|
+
list.size--
|
|
57
|
+
return elem, nil
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
func (list *List) Array() []int {
|
|
61
|
+
res := []int{}
|
|
62
|
+
for node := list.head; node != nil; node = node.next {
|
|
63
|
+
res = append(res, node.data)
|
|
64
|
+
}
|
|
65
|
+
return res
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
func (list *List) Reverse() *List {
|
|
69
|
+
array, size := list.Array(), list.size
|
|
70
|
+
for i := 0; i < size/2; i++ {
|
|
71
|
+
array[i], array[size-1-i] = array[size-1-i], array[i]
|
|
72
|
+
}
|
|
73
|
+
return New(array)
|
|
74
|
+
}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
// API:
|
|
2
|
+
//
|
|
3
|
+
// type Element struct {
|
|
4
|
+
// data int
|
|
5
|
+
// next *Element
|
|
6
|
+
// }
|
|
7
|
+
//
|
|
8
|
+
// type List struct {
|
|
9
|
+
// head *Element
|
|
10
|
+
// size int
|
|
11
|
+
// }
|
|
12
|
+
//
|
|
13
|
+
// func New([]int) *List
|
|
14
|
+
// func (*List) Size() int
|
|
15
|
+
// func (*List) Push(int)
|
|
16
|
+
// func (*List) Pop() (int, error)
|
|
17
|
+
// func (*List) Array() []int
|
|
18
|
+
// func (*List) Reverse() *List
|
|
19
|
+
|
|
20
|
+
package linkedlist
|
|
21
|
+
|
|
22
|
+
import (
|
|
23
|
+
"reflect"
|
|
24
|
+
"testing"
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
var array1To10 = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
|
|
28
|
+
|
|
29
|
+
func TestEmptyListHasSizeZero(t *testing.T) {
|
|
30
|
+
list := New([]int{})
|
|
31
|
+
if size := list.Size(); size != 0 {
|
|
32
|
+
t.Fatalf("Size of empty list: %d, expected: %d", size, 0)
|
|
33
|
+
}
|
|
34
|
+
list = New(nil)
|
|
35
|
+
if size := list.Size(); size != 0 {
|
|
36
|
+
t.Fatalf("Size of empty list: %d, expected: %d", size, 0)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
func TestSingletonListHasSizeOne(t *testing.T) {
|
|
41
|
+
list := New([]int{1})
|
|
42
|
+
if size := list.Size(); size != 1 {
|
|
43
|
+
t.Fatalf("Size of singleton list: %d, expected: %d", size, 1)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
func TestNonEmptyListHasCorrectSize(t *testing.T) {
|
|
48
|
+
list := New([]int{1, 2, 3})
|
|
49
|
+
if size := list.Size(); size != 3 {
|
|
50
|
+
t.Fatalf("Size of list from [1, 2, 3]: %d, expected: %d", size, 3)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
func TestEmptyListToEmptyArray(t *testing.T) {
|
|
55
|
+
list := New([]int{})
|
|
56
|
+
if array := list.Array(); len(array) != 0 {
|
|
57
|
+
t.Fatalf("Test empty list to array: %v, want empty array", array)
|
|
58
|
+
}
|
|
59
|
+
list = New(nil)
|
|
60
|
+
if array := list.Array(); len(array) != 0 {
|
|
61
|
+
t.Fatalf("Test empty list to array: %v, want empty array", array)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
func TestNonEmptyListToArray(t *testing.T) {
|
|
66
|
+
expected := []int{1, 2, 3}
|
|
67
|
+
list := New(expected)
|
|
68
|
+
array := list.Array()
|
|
69
|
+
if !reflect.DeepEqual(array, expected) {
|
|
70
|
+
t.Fatalf("Test non empty list to array: %v, want %v", array, expected)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
func TestPopFromEmptyList(t *testing.T) {
|
|
75
|
+
list := New([]int{})
|
|
76
|
+
if _, err := list.Pop(); err == nil {
|
|
77
|
+
t.Fatalf("Pop from empty list: expected error but there was not")
|
|
78
|
+
}
|
|
79
|
+
list = New(nil)
|
|
80
|
+
if _, err := list.Pop(); err == nil {
|
|
81
|
+
t.Fatalf("Pop from empty list: expected error but there was not")
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
func TestPopFromNonEmptyList(t *testing.T) {
|
|
86
|
+
list := New([]int{1, 2, 3})
|
|
87
|
+
elem, err := list.Pop()
|
|
88
|
+
if err != nil {
|
|
89
|
+
t.Fatalf("Pop from non empty list: unexpected error %v", err)
|
|
90
|
+
}
|
|
91
|
+
if elem != 3 {
|
|
92
|
+
t.Fatalf("Pop from non empty list: %d, want %d", elem, 3)
|
|
93
|
+
}
|
|
94
|
+
actual := list.Array()
|
|
95
|
+
expected := []int{1, 2}
|
|
96
|
+
if !reflect.DeepEqual(actual, expected) {
|
|
97
|
+
t.Fatalf("Pop from non empty list: %v, want %v", actual, expected)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
func TestPushToEmptyList(t *testing.T) {
|
|
102
|
+
list := New([]int{})
|
|
103
|
+
list.Push(1)
|
|
104
|
+
actual := list.Array()
|
|
105
|
+
expected := []int{1}
|
|
106
|
+
if !reflect.DeepEqual(actual, expected) {
|
|
107
|
+
t.Fatalf("Push to empty list: %v, want %v", actual, expected)
|
|
108
|
+
}
|
|
109
|
+
list = New(nil)
|
|
110
|
+
list.Push(1)
|
|
111
|
+
actual = list.Array()
|
|
112
|
+
if !reflect.DeepEqual(actual, expected) {
|
|
113
|
+
t.Fatalf("Push to empty list: %v, want %v", actual, expected)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
func TestPushToNonEmptyList(t *testing.T) {
|
|
118
|
+
list := New([]int{1, 2, 3})
|
|
119
|
+
list.Push(4)
|
|
120
|
+
actual := list.Array()
|
|
121
|
+
expected := []int{1, 2, 3, 4}
|
|
122
|
+
if !reflect.DeepEqual(actual, expected) {
|
|
123
|
+
t.Fatalf("Push to non empty list: %v, want %v", actual, expected)
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
func TestPushAndPop(t *testing.T) {
|
|
128
|
+
list := New([]int{1, 2, 3})
|
|
129
|
+
list.Pop()
|
|
130
|
+
list.Push(4)
|
|
131
|
+
list.Push(5)
|
|
132
|
+
list.Pop()
|
|
133
|
+
list.Push(6)
|
|
134
|
+
actual := list.Array()
|
|
135
|
+
expected := []int{1, 2, 4, 6}
|
|
136
|
+
if !reflect.DeepEqual(actual, expected) {
|
|
137
|
+
t.Fatalf("Test push and pop: %v, want %v", actual, expected)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
func TestReverseEmptyList(t *testing.T) {
|
|
142
|
+
list := New([]int{})
|
|
143
|
+
if reversed := list.Reverse().Array(); len(reversed) != 0 {
|
|
144
|
+
t.Fatalf("Reverse empty list: %v, want empty list", reversed)
|
|
145
|
+
}
|
|
146
|
+
list = New(nil)
|
|
147
|
+
if reversed := list.Reverse().Array(); len(reversed) != 0 {
|
|
148
|
+
t.Fatalf("Reverse empty list: %v, want empty list", reversed)
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
func TestReverseNonEmptyList(t *testing.T) {
|
|
153
|
+
list := New([]int{1, 2, 3})
|
|
154
|
+
actual := list.Reverse().Array()
|
|
155
|
+
expected := []int{3, 2, 1}
|
|
156
|
+
if !reflect.DeepEqual(actual, expected) {
|
|
157
|
+
t.Fatalf("Reverse non empty list: %v, want %v", actual, expected)
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
func BenchmarkNewList(b *testing.B) {
|
|
162
|
+
for i := 0; i < b.N; i++ {
|
|
163
|
+
_ = New(array1To10)
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
func BenchmarkListSize(b *testing.B) {
|
|
168
|
+
for i := 0; i < b.N; i++ {
|
|
169
|
+
b.StopTimer()
|
|
170
|
+
list := New(array1To10)
|
|
171
|
+
b.StartTimer()
|
|
172
|
+
_ = list.Size()
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
func BenchmarkListPush(b *testing.B) {
|
|
177
|
+
for i := 0; i < b.N; i++ {
|
|
178
|
+
b.StopTimer()
|
|
179
|
+
list := New(array1To10)
|
|
180
|
+
b.StartTimer()
|
|
181
|
+
list.Push(11)
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
func BenchmarkListPop(b *testing.B) {
|
|
186
|
+
for i := 0; i < b.N; i++ {
|
|
187
|
+
b.StopTimer()
|
|
188
|
+
list := New(array1To10)
|
|
189
|
+
b.StartTimer()
|
|
190
|
+
_, _ = list.Pop()
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
func BenchmarkListToArray(b *testing.B) {
|
|
195
|
+
for i := 0; i < b.N; i++ {
|
|
196
|
+
b.StopTimer()
|
|
197
|
+
list := New(array1To10)
|
|
198
|
+
b.StartTimer()
|
|
199
|
+
_ = list.Array()
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
func BenchmarkListReverse(b *testing.B) {
|
|
204
|
+
for i := 0; i < b.N; i++ {
|
|
205
|
+
b.StopTimer()
|
|
206
|
+
list := New(array1To10)
|
|
207
|
+
b.StartTimer()
|
|
208
|
+
_ = list.Reverse()
|
|
209
|
+
}
|
|
210
|
+
}
|