trackler 2.2.1.71 → 2.2.1.72
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/problem-specifications/exercises/book-store/canonical-data.json +9 -2
- data/problem-specifications/exercises/word-count/canonical-data.json +9 -0
- data/tracks/bash/CONTRIBUTING.md +199 -0
- data/tracks/bash/config.json +24 -11
- data/tracks/bash/exercises/triangle/README.md +38 -0
- data/tracks/bash/exercises/triangle/example.sh +56 -0
- data/tracks/bash/exercises/triangle/triangle_test.sh +126 -0
- data/tracks/bash/img/canonical-data-example.png +0 -0
- data/tracks/bash/img/create-pr.png +0 -0
- data/tracks/bash/img/fork-repository.png +0 -0
- data/tracks/c/exercises/acronym/makefile +1 -1
- data/tracks/c/exercises/all-your-base/makefile +1 -1
- data/tracks/c/exercises/allergies/makefile +1 -1
- data/tracks/c/exercises/anagram/makefile +1 -1
- data/tracks/c/exercises/atbash-cipher/makefile +1 -1
- data/tracks/c/exercises/beer-song/makefile +1 -1
- data/tracks/c/exercises/binary-search/makefile +1 -1
- data/tracks/c/exercises/binary/makefile +1 -1
- data/tracks/c/exercises/bob/makefile +1 -1
- data/tracks/c/exercises/clock/makefile +1 -1
- data/tracks/c/exercises/collatz-conjecture/makefile +1 -1
- data/tracks/c/exercises/difference-of-squares/makefile +1 -1
- data/tracks/c/exercises/gigasecond/makefile +1 -1
- data/tracks/c/exercises/grains/makefile +1 -1
- data/tracks/c/exercises/hamming/makefile +1 -1
- data/tracks/c/exercises/hamming/test/test_hamming.c +2 -2
- data/tracks/c/exercises/hello-world/makefile +1 -1
- data/tracks/c/exercises/isogram/makefile +1 -1
- data/tracks/c/exercises/largest-series-product/makefile +1 -1
- data/tracks/c/exercises/leap/makefile +1 -1
- data/tracks/c/exercises/meetup/makefile +1 -1
- data/tracks/c/exercises/nth-prime/makefile +1 -1
- data/tracks/c/exercises/nucleotide-count/makefile +1 -1
- data/tracks/c/exercises/palindrome-products/makefile +1 -1
- data/tracks/c/exercises/pangram/makefile +1 -1
- data/tracks/c/exercises/pascals-triangle/makefile +1 -1
- data/tracks/c/exercises/perfect-numbers/makefile +1 -1
- data/tracks/c/exercises/phone-number/makefile +1 -1
- data/tracks/c/exercises/queen-attack/makefile +1 -1
- data/tracks/c/exercises/raindrops/makefile +1 -1
- data/tracks/c/exercises/react/makefile +1 -1
- data/tracks/c/exercises/rna-transcription/makefile +1 -1
- data/tracks/c/exercises/robot-simulator/makefile +1 -1
- data/tracks/c/exercises/roman-numerals/makefile +1 -1
- data/tracks/c/exercises/scrabble-score/makefile +1 -1
- data/tracks/c/exercises/series/makefile +1 -1
- data/tracks/c/exercises/sieve/makefile +1 -1
- data/tracks/c/exercises/space-age/makefile +1 -1
- data/tracks/c/exercises/sublist/makefile +1 -1
- data/tracks/c/exercises/sum-of-multiples/makefile +1 -1
- data/tracks/c/exercises/triangle/makefile +1 -1
- data/tracks/c/exercises/word-count/makefile +1 -1
- data/tracks/delphi/exercises/allergies/README.md +1 -1
- data/tracks/delphi/exercises/bank-account/README.md +1 -1
- data/tracks/delphi/exercises/beer-song/README.md +1 -1
- data/tracks/delphi/exercises/binary-search/README.md +1 -1
- data/tracks/delphi/exercises/bob/README.md +1 -1
- data/tracks/delphi/exercises/book-store/README.md +1 -1
- data/tracks/delphi/exercises/book-store/uBookStoreExample.pas +34 -14
- data/tracks/delphi/exercises/book-store/uBookStoreTests.pas +36 -1
- data/tracks/delphi/exercises/bowling/README.md +1 -1
- data/tracks/delphi/exercises/circular-buffer/README.md +1 -1
- data/tracks/delphi/exercises/clock/README.md +1 -1
- data/tracks/delphi/exercises/collatz-conjecture/README.md +1 -1
- data/tracks/delphi/exercises/etl/README.md +1 -1
- data/tracks/delphi/exercises/grains/README.md +1 -1
- data/tracks/delphi/exercises/hamming/README.md +1 -1
- data/tracks/delphi/exercises/hello-world/README.md +1 -1
- data/tracks/delphi/exercises/leap/README.md +1 -1
- data/tracks/delphi/exercises/minesweeper/README.md +1 -1
- data/tracks/delphi/exercises/nucleotide-count/README.md +1 -1
- data/tracks/delphi/exercises/perfect-numbers/README.md +1 -1
- data/tracks/delphi/exercises/phone-number/README.md +1 -1
- data/tracks/delphi/exercises/pig-latin/README.md +1 -1
- data/tracks/delphi/exercises/poker/README.md +1 -1
- data/tracks/delphi/exercises/raindrops/README.md +1 -1
- data/tracks/delphi/exercises/reverse-string/README.md +1 -1
- data/tracks/delphi/exercises/rna-transcription/README.md +1 -1
- data/tracks/delphi/exercises/roman-numerals/README.md +1 -1
- data/tracks/delphi/exercises/saddle-points/README.md +1 -1
- data/tracks/delphi/exercises/triangle/README.md +1 -1
- data/tracks/delphi/exercises/two-fer/README.md +1 -1
- data/tracks/delphi/exercises/wordy/README.md +1 -1
- data/tracks/ecmascript/.travis.yml +1 -1
- data/tracks/ecmascript/Makefile +4 -5
- data/tracks/ecmascript/README.md +2 -1
- data/tracks/ecmascript/config.json +12 -0
- data/tracks/ecmascript/exercises/change/package.json +5 -3
- data/tracks/ecmascript/exercises/protein-translation/package.json +2 -2
- data/tracks/ecmascript/exercises/react/README.md +41 -0
- data/tracks/ecmascript/exercises/react/example.js +101 -0
- data/tracks/ecmascript/exercises/react/package.json +71 -0
- data/tracks/ecmascript/exercises/react/react.spec.js +211 -0
- data/tracks/ecmascript/exercises/rectangles/package.json +1 -2
- data/tracks/ecmascript/exercises/rotational-cipher/package.json +1 -2
- data/tracks/ecmascript/exercises/spiral-matrix/package.json +1 -2
- data/tracks/ecmascript/exercises/transpose/package.json +2 -2
- data/tracks/erlang/docs/ABOUT.md +1 -1
- data/tracks/go/exercises/binary-search/.meta/gen.go +55 -0
- data/tracks/go/exercises/binary-search/binary_search_test.go +26 -167
- data/tracks/go/exercises/binary-search/cases_test.go +73 -0
- data/tracks/go/exercises/binary-search/example.go +8 -30
- data/tracks/go/exercises/nth-prime/.meta/gen.go +76 -0
- data/tracks/go/exercises/nth-prime/cases_test.go +43 -0
- data/tracks/go/exercises/nth-prime/nth_prime_test.go +4 -18
- data/tracks/go/exercises/prime-factors/.meta/gen.go +54 -0
- data/tracks/go/exercises/prime-factors/cases_test.go +48 -0
- data/tracks/go/exercises/prime-factors/prime_factors_test.go +4 -19
- data/tracks/groovy/config.json +13 -1
- data/tracks/groovy/exercises/linked-list/DoubleLinkedList.groovy +19 -0
- data/tracks/groovy/exercises/linked-list/DoubleLinkedListSpec.groovy +79 -0
- data/tracks/groovy/exercises/linked-list/Example.groovy +57 -0
- data/tracks/groovy/exercises/linked-list/README.md +49 -0
- data/tracks/java/bin/run-journey-test-from-ci.sh +1 -1
- data/tracks/java/config.json +10 -0
- data/tracks/java/config/maintainers.json +8 -1
- data/tracks/java/docs/MAINTAINING.md +3 -3
- data/tracks/java/exercises/accumulate/.meta/src/reference/java/Accumulate.java +2 -2
- data/tracks/java/exercises/binary/.meta/src/reference/java/Binary.java +3 -3
- data/tracks/java/exercises/circular-buffer/.meta/src/reference/java/BufferIOException.java +1 -1
- data/tracks/java/exercises/circular-buffer/.meta/src/reference/java/CircularBuffer.java +6 -6
- data/tracks/java/exercises/circular-buffer/src/main/java/BufferIOException.java +1 -1
- data/tracks/java/exercises/clock/.meta/src/reference/java/Clock.java +3 -3
- data/tracks/java/exercises/crypto-square/.meta/src/reference/java/Crypto.java +7 -7
- data/tracks/java/exercises/etl/.meta/src/reference/java/Etl.java +2 -2
- data/tracks/java/exercises/etl/src/main/java/Etl.java +2 -2
- data/tracks/java/exercises/kindergarten-garden/.meta/src/reference/java/KindergartenGarden.java +4 -4
- data/tracks/java/exercises/kindergarten-garden/.meta/src/reference/java/Plant.java +2 -2
- data/tracks/java/exercises/kindergarten-garden/src/main/java/Plant.java +2 -2
- data/tracks/java/exercises/nth-prime/.meta/src/reference/java/PrimeCalculator.java +2 -2
- data/tracks/java/exercises/reverse-string/.meta/src/reference/java/ReverseString.java +7 -0
- data/tracks/java/exercises/reverse-string/.meta/version +1 -0
- data/tracks/java/exercises/reverse-string/README.md +25 -0
- data/tracks/java/exercises/reverse-string/build.gradle +17 -0
- data/tracks/java/exercises/reverse-string/src/main/java/ReverseString.java +7 -0
- data/tracks/java/exercises/reverse-string/src/test/java/ReverseStringTest.java +37 -0
- data/tracks/java/exercises/run-length-encoding/.meta/src/reference/java/RunLengthEncoding.java +4 -4
- data/tracks/java/exercises/settings.gradle +1 -0
- data/tracks/kotlin/docs/RESOURCES.md +1 -1
- data/tracks/kotlin/exercises/accumulate/build.gradle +1 -1
- data/tracks/kotlin/exercises/acronym/build.gradle +1 -1
- data/tracks/kotlin/exercises/all-your-base/build.gradle +1 -1
- data/tracks/kotlin/exercises/allergies/build.gradle +1 -1
- data/tracks/kotlin/exercises/anagram/build.gradle +1 -1
- data/tracks/kotlin/exercises/atbash-cipher/build.gradle +1 -1
- data/tracks/kotlin/exercises/bank-account/build.gradle +1 -1
- data/tracks/kotlin/exercises/beer-song/build.gradle +1 -1
- data/tracks/kotlin/exercises/binary-search/build.gradle +1 -1
- data/tracks/kotlin/exercises/binary/build.gradle +1 -1
- data/tracks/kotlin/exercises/bob/build.gradle +1 -1
- data/tracks/kotlin/exercises/bracket-push/build.gradle +1 -1
- data/tracks/kotlin/exercises/change/build.gradle +1 -1
- data/tracks/kotlin/exercises/clock/build.gradle +1 -1
- data/tracks/kotlin/exercises/collatz-conjecture/build.gradle +1 -1
- data/tracks/kotlin/exercises/complex-numbers/build.gradle +1 -1
- data/tracks/kotlin/exercises/diamond/build.gradle +1 -1
- data/tracks/kotlin/exercises/difference-of-squares/build.gradle +1 -1
- data/tracks/kotlin/exercises/etl/build.gradle +1 -1
- data/tracks/kotlin/exercises/flatten-array/build.gradle +1 -1
- data/tracks/kotlin/exercises/forth/build.gradle +1 -1
- data/tracks/kotlin/exercises/gigasecond/build.gradle +1 -1
- data/tracks/kotlin/exercises/grade-school/build.gradle +1 -1
- data/tracks/kotlin/exercises/grains/build.gradle +1 -1
- data/tracks/kotlin/exercises/hamming/build.gradle +1 -1
- data/tracks/kotlin/exercises/hello-world/build.gradle +1 -1
- data/tracks/kotlin/exercises/hexadecimal/build.gradle +1 -1
- data/tracks/kotlin/exercises/isogram/build.gradle +1 -1
- data/tracks/kotlin/exercises/largest-series-product/build.gradle +1 -1
- data/tracks/kotlin/exercises/leap/build.gradle +1 -1
- data/tracks/kotlin/exercises/linked-list/build.gradle +1 -1
- data/tracks/kotlin/exercises/list-ops/build.gradle +1 -1
- data/tracks/kotlin/exercises/luhn/build.gradle +1 -1
- data/tracks/kotlin/exercises/meetup/build.gradle +1 -1
- data/tracks/kotlin/exercises/minesweeper/build.gradle +1 -1
- data/tracks/kotlin/exercises/nth-prime/build.gradle +1 -1
- data/tracks/kotlin/exercises/nucleotide-count/build.gradle +1 -1
- data/tracks/kotlin/exercises/pangram/build.gradle +1 -1
- data/tracks/kotlin/exercises/pascals-triangle/build.gradle +1 -1
- data/tracks/kotlin/exercises/perfect-numbers/build.gradle +1 -1
- data/tracks/kotlin/exercises/phone-number/build.gradle +1 -1
- data/tracks/kotlin/exercises/pig-latin/build.gradle +1 -1
- data/tracks/kotlin/exercises/prime-factors/build.gradle +1 -1
- data/tracks/kotlin/exercises/raindrops/build.gradle +1 -1
- data/tracks/kotlin/exercises/react/build.gradle +1 -1
- data/tracks/kotlin/exercises/rna-transcription/build.gradle +1 -1
- data/tracks/kotlin/exercises/robot-name/build.gradle +1 -1
- data/tracks/kotlin/exercises/robot-simulator/build.gradle +1 -1
- data/tracks/kotlin/exercises/roman-numerals/build.gradle +1 -1
- data/tracks/kotlin/exercises/rotational-cipher/build.gradle +1 -1
- data/tracks/kotlin/exercises/saddle-points/build.gradle +1 -1
- data/tracks/kotlin/exercises/say/build.gradle +1 -1
- data/tracks/kotlin/exercises/scrabble-score/build.gradle +1 -1
- data/tracks/kotlin/exercises/secret-handshake/build.gradle +1 -1
- data/tracks/kotlin/exercises/series/build.gradle +1 -1
- data/tracks/kotlin/exercises/sieve/build.gradle +1 -1
- data/tracks/kotlin/exercises/simple-cipher/README.md +4 -6
- data/tracks/kotlin/exercises/simple-cipher/build.gradle +1 -1
- data/tracks/kotlin/exercises/space-age/build.gradle +1 -1
- data/tracks/kotlin/exercises/spiral-matrix/build.gradle +1 -1
- data/tracks/kotlin/exercises/strain/build.gradle +1 -1
- data/tracks/kotlin/exercises/sublist/build.gradle +1 -1
- data/tracks/kotlin/exercises/sum-of-multiples/build.gradle +1 -1
- data/tracks/kotlin/exercises/triangle/build.gradle +1 -1
- data/tracks/kotlin/exercises/two-fer/build.gradle +1 -1
- data/tracks/kotlin/exercises/word-count/build.gradle +1 -1
- data/tracks/lua/.gitignore +1 -0
- data/tracks/lua/config.json +12 -0
- data/tracks/lua/exercises/isbn-verifier/README.md +52 -0
- data/tracks/lua/exercises/isbn-verifier/example.lua +16 -0
- data/tracks/lua/exercises/isbn-verifier/isbn-verifier_spec.lua +55 -0
- data/tracks/ocaml/.travis-ci.sh +1 -1
- data/tracks/ocaml/.travis.yml +1 -1
- data/tracks/ocaml/README.md +1 -1
- data/tracks/perl6/config.json +10 -0
- data/tracks/perl6/exercises/acronym/Acronym.pm6 +4 -0
- data/tracks/perl6/exercises/acronym/Example.pm6 +5 -0
- data/tracks/perl6/exercises/acronym/README.md +33 -0
- data/tracks/perl6/exercises/acronym/acronym.t +96 -0
- data/tracks/perl6/exercises/acronym/example.yaml +19 -0
- data/tracks/perl6/exercises/word-count/Example.pm6 +1 -1
- data/tracks/perl6/exercises/word-count/WordCount.pm6 +1 -1
- data/tracks/perl6/exercises/word-count/example.yaml +2 -2
- data/tracks/perl6/exercises/word-count/word-count.t +11 -2
- data/tracks/pony/docs/RESOURCES.md +1 -1
- data/tracks/purescript/docs/INSTALLATION.md +1 -3
- data/tracks/python/config.json +1 -1
- data/tracks/r/exercises/word-count/test_word-count.R +5 -0
- data/tracks/ruby/README.md +73 -10
- data/tracks/rust/config.json +34 -0
- data/tracks/rust/exercises/book-store/Cargo.toml +1 -1
- data/tracks/rust/exercises/book-store/tests/book-store.rs +7 -0
- data/tracks/rust/exercises/diffie-hellman/.gitignore +9 -0
- data/tracks/rust/exercises/diffie-hellman/Cargo-example.toml +6 -0
- data/tracks/rust/exercises/diffie-hellman/Cargo.toml +5 -0
- data/tracks/rust/exercises/diffie-hellman/README.md +77 -0
- data/tracks/rust/exercises/diffie-hellman/example.rs +15 -0
- data/tracks/rust/exercises/diffie-hellman/src/lib.rs +11 -0
- data/tracks/rust/exercises/diffie-hellman/tests/diffie-hellman.rs +60 -0
- data/tracks/rust/exercises/macros/.gitignore +3 -0
- data/tracks/rust/exercises/macros/.meta/description.md +29 -0
- data/tracks/rust/exercises/macros/.meta/metadata.yml +3 -0
- data/tracks/rust/exercises/macros/Cargo.toml +6 -0
- data/tracks/rust/exercises/macros/README.md +70 -0
- data/tracks/rust/exercises/macros/example.rs +16 -0
- data/tracks/rust/exercises/macros/src/lib.rs +6 -0
- data/tracks/rust/exercises/macros/tests/macros.rs +62 -0
- data/tracks/rust/exercises/simple-linked-list/.gitignore +7 -0
- data/tracks/rust/exercises/simple-linked-list/.meta/hints.md +34 -0
- data/tracks/rust/exercises/simple-linked-list/Cargo.toml +5 -0
- data/tracks/rust/exercises/simple-linked-list/README.md +96 -0
- data/tracks/rust/exercises/simple-linked-list/example.rs +87 -0
- data/tracks/rust/exercises/simple-linked-list/src/lib.rs +46 -0
- data/tracks/rust/exercises/simple-linked-list/tests/simple-linked-list.rs +91 -0
- data/tracks/swift/.travis.yml +1 -1
- data/tracks/swift/config.json +24 -0
- data/tracks/swift/exercises/isbn-verifier/Package.swift +5 -0
- data/tracks/swift/exercises/isbn-verifier/README.md +39 -0
- data/tracks/swift/exercises/isbn-verifier/Sources/IsbnVerifier.swift +1 -0
- data/tracks/swift/exercises/isbn-verifier/Sources/IsbnVerifierExample.swift +35 -0
- data/tracks/swift/exercises/isbn-verifier/Tests/IsbnVerifierTests/IsbnVerifierTests.swift +75 -0
- data/tracks/swift/exercises/isbn-verifier/Tests/LinuxMain.swift +6 -0
- data/tracks/swift/exercises/two-fer/Package.swift +5 -0
- data/tracks/swift/exercises/two-fer/README.md +54 -0
- data/tracks/swift/exercises/two-fer/Sources/TwoFer.swift +1 -0
- data/tracks/swift/exercises/two-fer/Sources/TwoFerExample.swift +6 -0
- data/tracks/swift/exercises/two-fer/Tests/LinuxMain.swift +6 -0
- data/tracks/swift/exercises/two-fer/Tests/TwoFerTests/TwoFerTests.swift +25 -0
- metadata +71 -2
@@ -9,7 +9,7 @@
|
|
9
9
|
"url": "https://github.com/exercism/xecmascript"
|
10
10
|
},
|
11
11
|
"devDependencies": {
|
12
|
-
"babel-jest": "^
|
12
|
+
"babel-jest": "^21.2.0",
|
13
13
|
"babel-plugin-transform-builtin-extend": "^1.1.2",
|
14
14
|
"babel-preset-env": "^1.4.0",
|
15
15
|
"eslint": "^3.19.0",
|
@@ -17,7 +17,7 @@
|
|
17
17
|
"eslint-plugin-import": "^2.2.0",
|
18
18
|
"eslint-plugin-jsx-a11y": "^5.0.1",
|
19
19
|
"eslint-plugin-react": "^7.0.1",
|
20
|
-
"jest": "^
|
20
|
+
"jest": "^21.2.1"
|
21
21
|
},
|
22
22
|
"jest": {
|
23
23
|
"modulePathIgnorePatterns": [
|
data/tracks/erlang/docs/ABOUT.md
CHANGED
@@ -2,4 +2,4 @@ Erlang is a programming language used to build massively scalable soft real-time
|
|
2
2
|
Some of its uses are in telecoms, banking, e-commerce, computer telephony and instant messaging.
|
3
3
|
Erlang's runtime system has built-in support for concurrency, distribution and fault tolerance.
|
4
4
|
|
5
|
-
The above description is a quote taken directly from the 'Getting Started' section of [the Erlang homepage](www.erlang.org).
|
5
|
+
The above description is a quote taken directly from the 'Getting Started' section of [the Erlang homepage](https://www.erlang.org).
|
@@ -0,0 +1,55 @@
|
|
1
|
+
package main
|
2
|
+
|
3
|
+
import (
|
4
|
+
"log"
|
5
|
+
"text/template"
|
6
|
+
|
7
|
+
"../../../gen"
|
8
|
+
)
|
9
|
+
|
10
|
+
func main() {
|
11
|
+
t, err := template.New("").Parse(tmpl)
|
12
|
+
if err != nil {
|
13
|
+
log.Fatal(err)
|
14
|
+
}
|
15
|
+
var j js
|
16
|
+
if err := gen.Gen("binary-search", &j, t); err != nil {
|
17
|
+
log.Fatal(err)
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
// The JSON structure we expect to be able to unmarshal into
|
22
|
+
type js struct {
|
23
|
+
Exercise string
|
24
|
+
Version string
|
25
|
+
Cases []oneCase
|
26
|
+
}
|
27
|
+
|
28
|
+
// Test cases
|
29
|
+
type oneCase struct {
|
30
|
+
Description string
|
31
|
+
Property string
|
32
|
+
Array []int
|
33
|
+
Value int
|
34
|
+
Expected int
|
35
|
+
}
|
36
|
+
|
37
|
+
// Template to generate test cases.
|
38
|
+
var tmpl = `package binarysearch
|
39
|
+
|
40
|
+
{{.Header}}
|
41
|
+
|
42
|
+
var testCases = []struct {
|
43
|
+
description string
|
44
|
+
slice []int
|
45
|
+
key int
|
46
|
+
x int
|
47
|
+
}{ {{range .J.Cases}}
|
48
|
+
{
|
49
|
+
description: {{printf "%q" .Description}},
|
50
|
+
slice: {{printf "%#v" .Array}},
|
51
|
+
key: {{printf "%d" .Value}},
|
52
|
+
x: {{printf "%d" .Expected}},
|
53
|
+
},{{end}}
|
54
|
+
}
|
55
|
+
`
|
@@ -1,193 +1,52 @@
|
|
1
|
-
// Go has binary search in the standard library. Let's reimplement
|
2
|
-
// sort.SearchInts with the same API as documented in the standard library
|
3
|
-
// at http://golang.org/pkg/sort/#Search. Note that there are some differences
|
4
|
-
// with the exercise README.
|
5
|
-
//
|
6
|
-
// * If there are duplicate values of the key you are searching for, you can't
|
7
|
-
// just stop at the first one you find; you must find the first occurrence in
|
8
|
-
// the slice.
|
9
|
-
//
|
10
|
-
// * There is no special "not found" indication. If the search key is not
|
11
|
-
// present, SearchInts returns the index of the first value greater than the
|
12
|
-
// search key. If the key is greater than all values in the slice, SearchInts
|
13
|
-
// returns the length of the slice.
|
14
|
-
//
|
15
|
-
// * You can assume the slice is sorted in increasing order. There is no need
|
16
|
-
// to check that it is sorted. (That would wreck the performance.)
|
17
|
-
//
|
18
|
-
// Try it on your own without peeking at the standard library code.
|
19
|
-
|
20
1
|
package binarysearch
|
21
2
|
|
22
3
|
import (
|
4
|
+
"fmt"
|
23
5
|
"math/rand"
|
24
|
-
"sort"
|
25
6
|
"testing"
|
26
7
|
)
|
27
8
|
|
28
|
-
var testData = []struct {
|
29
|
-
ref string
|
30
|
-
slice []int
|
31
|
-
key int
|
32
|
-
x int // expected result
|
33
|
-
}{
|
34
|
-
{"6 found at index 3",
|
35
|
-
[]int{1, 3, 4, 6, 8, 9, 11},
|
36
|
-
6, 3},
|
37
|
-
{"9 found at index 5",
|
38
|
-
[]int{1, 3, 4, 6, 8, 9, 11},
|
39
|
-
9, 5},
|
40
|
-
{"3 found at index 1",
|
41
|
-
[]int{1, 3, 5, 8, 13, 21, 34, 55, 89, 144},
|
42
|
-
3, 1},
|
43
|
-
{"55 found at index 7",
|
44
|
-
[]int{1, 3, 5, 8, 13, 21, 34, 55, 89, 144},
|
45
|
-
55, 7},
|
46
|
-
{"21 found at index 5",
|
47
|
-
[]int{1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377},
|
48
|
-
21, 5},
|
49
|
-
{"34 found at index 6",
|
50
|
-
[]int{1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377},
|
51
|
-
34, 6},
|
52
|
-
|
53
|
-
{"1 found at beginning of slice",
|
54
|
-
[]int{1, 3, 6},
|
55
|
-
1, 0},
|
56
|
-
{"6 found at end of slice",
|
57
|
-
[]int{1, 3, 6},
|
58
|
-
6, 2},
|
59
|
-
{"2 > 1 at index 0, < 3 at index 1",
|
60
|
-
[]int{1, 3, 6},
|
61
|
-
2, 1},
|
62
|
-
{"2 < all values",
|
63
|
-
[]int{11, 13, 16},
|
64
|
-
2, 0},
|
65
|
-
{"21 > all 3 values",
|
66
|
-
[]int{11, 13, 16},
|
67
|
-
21, 3},
|
68
|
-
{"1 found at beginning of slice",
|
69
|
-
[]int{1, 1, 1, 1, 1, 3, 6}, // duplicates
|
70
|
-
1, 0},
|
71
|
-
{"3 found at index 1",
|
72
|
-
[]int{1, 3, 3, 3, 3, 3, 6},
|
73
|
-
3, 1},
|
74
|
-
{"6 found at index 4",
|
75
|
-
[]int{1, 3, 3, 3, 6, 6, 6},
|
76
|
-
6, 4},
|
77
|
-
{"-2 > -3 at index 1, < -1 at index 2",
|
78
|
-
[]int{-6, -3, -1}, // negatives
|
79
|
-
-2, 2},
|
80
|
-
{"0 > -7 at index 4, < 1 at index 5",
|
81
|
-
[]int{-19, -17, -15, -12, -7, 1, 14, 35, 69, 124},
|
82
|
-
0, 5},
|
83
|
-
{"slice has no values",
|
84
|
-
nil, 0, 0},
|
85
|
-
}
|
86
|
-
|
87
9
|
func TestSearchInts(t *testing.T) {
|
88
|
-
for _, test := range
|
89
|
-
if !sort.IntsAreSorted(test.slice) {
|
90
|
-
t.Skip("Invalid test data")
|
91
|
-
}
|
10
|
+
for _, test := range testCases {
|
92
11
|
if x := SearchInts(test.slice, test.key); x != test.x {
|
93
|
-
t.Fatalf("
|
94
|
-
test.slice, test.key, x, test.x)
|
95
|
-
}
|
96
|
-
}
|
97
|
-
}
|
98
|
-
|
99
|
-
// Did you get it? Did you cut and paste from the standard library?
|
100
|
-
// Whatever. Now show you can work it.
|
101
|
-
//
|
102
|
-
// The test program will supply slices and keys and you will write a function
|
103
|
-
// that searches and returns one of the following messages:
|
104
|
-
//
|
105
|
-
// k found at beginning of slice.
|
106
|
-
// k found at end of slice.
|
107
|
-
// k found at index fx.
|
108
|
-
// k < all values.
|
109
|
-
// k > all n values.
|
110
|
-
// k > lv at lx, < gv at gx.
|
111
|
-
// slice has no values.
|
112
|
-
//
|
113
|
-
// In your messages, substitute appropritate values for k, lv, and gv;
|
114
|
-
// substitute indexes for fx, lx, and gx; substitute a number for n.
|
115
|
-
//
|
116
|
-
// In the function Message you will demonstrate a number of different ways
|
117
|
-
// to test the result of SearchInts. Note that you would probably never need
|
118
|
-
// all of these different tests in a real program. The point of the exercise
|
119
|
-
// is just to show that it is possible to identify a number of different
|
120
|
-
// conditions from the return value.
|
121
|
-
func TestMessage(t *testing.T) {
|
122
|
-
for _, test := range testData {
|
123
|
-
if !sort.IntsAreSorted(test.slice) {
|
124
|
-
t.Skip("Invalid test data")
|
125
|
-
}
|
126
|
-
if res := Message(test.slice, test.key); res != test.ref {
|
127
|
-
t.Fatalf("Message(%v, %d) =\n%q\nwant:\n%q",
|
128
|
-
test.slice, test.key, res, test.ref)
|
12
|
+
t.Fatalf("FAIL: %s\nSearchInts(%#v, %d) = %d, want %d",
|
13
|
+
test.description, test.slice, test.key, x, test.x)
|
129
14
|
}
|
15
|
+
t.Logf("SUCCESS: %s", test.description)
|
130
16
|
}
|
131
17
|
}
|
132
18
|
|
133
19
|
// Benchmarks also test searching larger random slices
|
134
20
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
s[i] = rand.Intn(len(s))
|
139
|
-
}
|
140
|
-
sort.Ints(s)
|
141
|
-
k := rand.Intn(len(s))
|
142
|
-
ref := sort.SearchInts(s, k)
|
143
|
-
res := SearchInts(s, k)
|
144
|
-
if ref != res {
|
145
|
-
b.Fatalf(
|
146
|
-
"Search of %d values gave different answer than sort.SearchInts",
|
147
|
-
len(s))
|
148
|
-
}
|
149
|
-
b.ResetTimer()
|
150
|
-
for i := 0; i < b.N; i++ {
|
151
|
-
SearchInts(s, k)
|
152
|
-
}
|
21
|
+
type query struct {
|
22
|
+
slice []int
|
23
|
+
x int
|
153
24
|
}
|
154
25
|
|
155
|
-
func
|
156
|
-
|
157
|
-
for i :=
|
158
|
-
|
26
|
+
func newQuery(n int) (query, error) {
|
27
|
+
q := query{slice: make([]int, n)}
|
28
|
+
for i := 0; i < n; i++ {
|
29
|
+
q.slice[i] = i
|
159
30
|
}
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
res := SearchInts(s, k)
|
164
|
-
if ref != res {
|
165
|
-
b.Fatalf(
|
166
|
-
"Search of %d values gave different answer than sort.SearchInts",
|
167
|
-
len(s))
|
168
|
-
}
|
169
|
-
b.ResetTimer()
|
170
|
-
for i := 0; i < b.N; i++ {
|
171
|
-
SearchInts(s, k)
|
31
|
+
q.x = rand.Intn(n)
|
32
|
+
if res := SearchInts(q.slice, q.x); res != q.x {
|
33
|
+
return q, fmt.Errorf("Search of %d values gave different answer", n)
|
172
34
|
}
|
35
|
+
return q, nil
|
173
36
|
}
|
174
37
|
|
175
|
-
func
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
}
|
180
|
-
sort.Ints(s)
|
181
|
-
k := rand.Intn(len(s))
|
182
|
-
ref := sort.SearchInts(s, k)
|
183
|
-
res := SearchInts(s, k)
|
184
|
-
if ref != res {
|
185
|
-
b.Fatalf(
|
186
|
-
"Search of %d values gave different answer than sort.SearchInts",
|
187
|
-
len(s))
|
38
|
+
func runBenchmark(n int, b *testing.B) {
|
39
|
+
q, err := newQuery(n)
|
40
|
+
if err != nil {
|
41
|
+
b.Fatal(err)
|
188
42
|
}
|
189
43
|
b.ResetTimer()
|
190
44
|
for i := 0; i < b.N; i++ {
|
191
|
-
SearchInts(
|
45
|
+
SearchInts(q.slice, q.x)
|
192
46
|
}
|
193
47
|
}
|
48
|
+
|
49
|
+
func Benchmark1e2(b *testing.B) { runBenchmark(1e2, b) }
|
50
|
+
func Benchmark1e4(b *testing.B) { runBenchmark(1e4, b) }
|
51
|
+
func Benchmark1e6(b *testing.B) { runBenchmark(1e6, b) }
|
52
|
+
func Benchmark1e8(b *testing.B) { runBenchmark(1e8, b) }
|
@@ -0,0 +1,73 @@
|
|
1
|
+
package binarysearch
|
2
|
+
|
3
|
+
// Source: exercism/problem-specifications
|
4
|
+
// Commit: 8acd78c Replace x-common with problem-specifications
|
5
|
+
// Problem Specifications Version: 1.0.0
|
6
|
+
|
7
|
+
var testCases = []struct {
|
8
|
+
description string
|
9
|
+
slice []int
|
10
|
+
key int
|
11
|
+
x int
|
12
|
+
}{
|
13
|
+
{
|
14
|
+
description: "finds a value in an array with one element",
|
15
|
+
slice: []int{6},
|
16
|
+
key: 6,
|
17
|
+
x: 0,
|
18
|
+
},
|
19
|
+
{
|
20
|
+
description: "finds a value in the middle of an array",
|
21
|
+
slice: []int{1, 3, 4, 6, 8, 9, 11},
|
22
|
+
key: 6,
|
23
|
+
x: 3,
|
24
|
+
},
|
25
|
+
{
|
26
|
+
description: "finds a value at the beginning of an array",
|
27
|
+
slice: []int{1, 3, 4, 6, 8, 9, 11},
|
28
|
+
key: 1,
|
29
|
+
x: 0,
|
30
|
+
},
|
31
|
+
{
|
32
|
+
description: "finds a value at the end of an array",
|
33
|
+
slice: []int{1, 3, 4, 6, 8, 9, 11},
|
34
|
+
key: 11,
|
35
|
+
x: 6,
|
36
|
+
},
|
37
|
+
{
|
38
|
+
description: "finds a value in an array of odd length",
|
39
|
+
slice: []int{1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 634},
|
40
|
+
key: 144,
|
41
|
+
x: 9,
|
42
|
+
},
|
43
|
+
{
|
44
|
+
description: "finds a value in an array of even length",
|
45
|
+
slice: []int{1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377},
|
46
|
+
key: 21,
|
47
|
+
x: 5,
|
48
|
+
},
|
49
|
+
{
|
50
|
+
description: "identifies that a value is not included in the array",
|
51
|
+
slice: []int{1, 3, 4, 6, 8, 9, 11},
|
52
|
+
key: 7,
|
53
|
+
x: -1,
|
54
|
+
},
|
55
|
+
{
|
56
|
+
description: "a value smaller than the array's smallest value is not included",
|
57
|
+
slice: []int{1, 3, 4, 6, 8, 9, 11},
|
58
|
+
key: 0,
|
59
|
+
x: -1,
|
60
|
+
},
|
61
|
+
{
|
62
|
+
description: "a value larger than the array's largest value is not included",
|
63
|
+
slice: []int{1, 3, 4, 6, 8, 9, 11},
|
64
|
+
key: 13,
|
65
|
+
x: -1,
|
66
|
+
},
|
67
|
+
{
|
68
|
+
description: "nothing is included in an empty array",
|
69
|
+
slice: []int{},
|
70
|
+
key: 1,
|
71
|
+
x: -1,
|
72
|
+
},
|
73
|
+
}
|
@@ -1,38 +1,16 @@
|
|
1
1
|
package binarysearch
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
func SearchInts(s []int, k int)
|
6
|
-
for j := len(s); i
|
3
|
+
// SearchInts search given key in the given slice
|
4
|
+
// upon finding returns its index, otherwise -1
|
5
|
+
func SearchInts(s []int, k int) int {
|
6
|
+
for i, j := 0, len(s)-1; i <= j; {
|
7
7
|
if h := (i + j) / 2; s[h] < k {
|
8
8
|
i = h + 1
|
9
|
+
} else if s[h] > k {
|
10
|
+
j = h - 1
|
9
11
|
} else {
|
10
|
-
|
12
|
+
return h
|
11
13
|
}
|
12
14
|
}
|
13
|
-
return
|
14
|
-
}
|
15
|
-
|
16
|
-
func Message(s []int, k int) string {
|
17
|
-
x := SearchInts(s, k)
|
18
|
-
switch {
|
19
|
-
case x == len(s):
|
20
|
-
if x == 0 {
|
21
|
-
return "slice has no values"
|
22
|
-
}
|
23
|
-
return fmt.Sprintf("%d > all %d values", k, x)
|
24
|
-
case s[x] != k:
|
25
|
-
if x == 0 {
|
26
|
-
return fmt.Sprintf("%d < all values", k)
|
27
|
-
}
|
28
|
-
return fmt.Sprintf("%d > %d at index %d, < %d at index %d",
|
29
|
-
k, s[x-1], x-1, s[x], x)
|
30
|
-
}
|
31
|
-
switch x {
|
32
|
-
case 0:
|
33
|
-
return fmt.Sprintf("%d found at beginning of slice", k)
|
34
|
-
case len(s) - 1:
|
35
|
-
return fmt.Sprintf("%d found at end of slice", k)
|
36
|
-
}
|
37
|
-
return fmt.Sprintf("%d found at index %d", k, x)
|
15
|
+
return -1
|
38
16
|
}
|