trackler 2.0.6.43 → 2.0.6.44

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2c7f1d91990a4750f3d2068c141560f8a61c9ee9
4
- data.tar.gz: 9ba1ec515f9d583f4f953b9b8ed78e24a4a2e069
3
+ metadata.gz: e22e92816145327ce2071b3930d8ede4ffc175b8
4
+ data.tar.gz: 07bc3bf77b11fdb37e8b2cacf629ec3a96b29d03
5
5
  SHA512:
6
- metadata.gz: 176d6fe5e46c669cbefced9200fa8249b32c6b058b09429825f30921a9d4cc1e75f06736da9d9d51942b21043fed2d013e521d98e4a70b698cf01a864ea417c0
7
- data.tar.gz: 623edfdafd946b751858d3b0edb82763e0d3543ae40b26de43943f824d0f1ab0f3563a584a3103aab27394e4db1372a85b93efd94a5f7dcd2239a6b3f64c2aa0
6
+ metadata.gz: 4f85dea3808a59c08bb536fb023a0335b90f5c7d042371a927b6fc109192ca1fad66c322863bcaee0a77d50a7e9830ac07cb23d60a143c53a02132d990320805
7
+ data.tar.gz: 1e3f404b70a1dc3e7e3ed5efde77f99e0c9256b4bbc487843fffed137f426d05c9f5376d66c9a6a96de0e5b4b0e7a02554b445b5e430815e890a0a3ad96e7a25
@@ -1,3 +1,3 @@
1
1
  module Trackler
2
- VERSION = "2.0.6.43"
2
+ VERSION = "2.0.6.44"
3
3
  end
@@ -151,6 +151,12 @@ func clear(s string) Board {
151
151
  return bytes.Split(b, []byte{'\n'})[1:]
152
152
  }
153
153
 
154
+ func TestTestVersion(t *testing.T) {
155
+ if testVersion != targetTestVersion {
156
+ t.Fatalf("Found testVersion = %v, want %v.", testVersion, targetTestVersion)
157
+ }
158
+ }
159
+
154
160
  func TestValid(t *testing.T) {
155
161
  for _, ref := range validBoards {
156
162
  b := clear(ref)
@@ -175,12 +181,6 @@ func TestBad(t *testing.T) {
175
181
  }
176
182
  }
177
183
 
178
- func TestTestVersion(t *testing.T) {
179
- if testVersion != targetTestVersion {
180
- t.Errorf("Found testVersion = %v, want %v.", testVersion, targetTestVersion)
181
- }
182
- }
183
-
184
184
  func BenchmarkCount(b *testing.B) {
185
185
  m := clear(`
186
186
  +------+
@@ -1,6 +1,6 @@
1
1
  package react
2
2
 
3
- const testVersion = 4
3
+ const testVersion = 5
4
4
 
5
5
  type reactor struct {
6
6
  cells []*cell
@@ -17,6 +17,14 @@ type cell struct {
17
17
  observers map[int]func(int)
18
18
  }
19
19
 
20
+ type canceler struct {
21
+ cancel func()
22
+ }
23
+
24
+ func (c *canceler) Cancel() {
25
+ c.cancel()
26
+ }
27
+
20
28
  func (c *cell) Value() int { return c.value }
21
29
 
22
30
  func (c *cell) SetValue(v int) {
@@ -27,15 +35,15 @@ func (c *cell) SetValue(v int) {
27
35
  }
28
36
  }
29
37
 
30
- func (c *cell) AddCallback(cb func(int)) CallbackHandle {
38
+ func (c *cell) AddCallback(cb func(int)) Canceler {
31
39
  key := c.nextKey
32
40
  c.nextKey++
33
41
  c.observers[key] = cb
34
- return key
35
- }
36
-
37
- func (c *cell) RemoveCallback(key CallbackHandle) {
38
- delete(c.observers, key.(int))
42
+ return &canceler{
43
+ cancel: func() {
44
+ delete(c.observers, key)
45
+ },
46
+ }
39
47
  }
40
48
 
41
49
  func New() Reactor {
@@ -38,12 +38,12 @@ type ComputeCell interface {
38
38
  Cell
39
39
 
40
40
  // AddCallback adds a callback which will be called when the value changes.
41
- // It returns a callback handle which can be used to remove the callback.
42
- AddCallback(func(int)) CallbackHandle
43
-
44
- // RemoveCallback removes a previously added callback, if it exists.
45
- RemoveCallback(CallbackHandle)
41
+ // It returns a Canceler which can be used to remove the callback.
42
+ AddCallback(func(int)) Canceler
46
43
  }
47
44
 
48
- // A CallbackHandle is used to remove previously added callbacks, see ComputeCell.
49
- type CallbackHandle interface{}
45
+ // A Canceler is used to remove previously added callbacks, see ComputeCell.
46
+ type Canceler interface {
47
+ // Cancel removes the callback.
48
+ Cancel()
49
+ }
@@ -11,7 +11,7 @@ import (
11
11
  // Also define a testVersion with a value that matches
12
12
  // the targetTestVersion here.
13
13
 
14
- const targetTestVersion = 4
14
+ const targetTestVersion = 5
15
15
 
16
16
  // This is a compile time check to see if you've properly implemented New().
17
17
  var _ Reactor = New()
@@ -182,7 +182,7 @@ func TestCallbackAddRemove(t *testing.T) {
182
182
  if len(observed2) != 1 || observed2[0] != 3 {
183
183
  t.Fatalf("observed2 not properly called")
184
184
  }
185
- c.RemoveCallback(cb1)
185
+ cb1.Cancel()
186
186
  i.SetValue(3)
187
187
  if len(observed1) != 1 {
188
188
  t.Fatalf("observed1 called after removal")
@@ -200,11 +200,11 @@ func TestMultipleCallbackRemoval(t *testing.T) {
200
200
  numCallbacks := 5
201
201
 
202
202
  calls := make([]int, numCallbacks)
203
- handles := make([]CallbackHandle, numCallbacks)
203
+ cancelers := make([]Canceler, numCallbacks)
204
204
  for i := 0; i < numCallbacks; i++ {
205
205
  // Rebind i, otherwise all callbacks will use i = numCallbacks
206
206
  i := i
207
- handles[i] = c.AddCallback(func(v int) { calls[i]++ })
207
+ cancelers[i] = c.AddCallback(func(v int) { calls[i]++ })
208
208
  }
209
209
 
210
210
  inp.SetValue(2)
@@ -212,7 +212,7 @@ func TestMultipleCallbackRemoval(t *testing.T) {
212
212
  if calls[i] != 1 {
213
213
  t.Fatalf("callback %d/%d should be called 1 time, was called %d times", i+1, numCallbacks, calls[i])
214
214
  }
215
- c.RemoveCallback(handles[i])
215
+ cancelers[i].Cancel()
216
216
  }
217
217
 
218
218
  inp.SetValue(3)
@@ -231,7 +231,7 @@ func TestRemoveIdempotence(t *testing.T) {
231
231
  cb1 := output.AddCallback(func(int) {})
232
232
  output.AddCallback(func(int) { timesCalled++ })
233
233
  for i := 0; i < 10; i++ {
234
- output.RemoveCallback(cb1)
234
+ cb1.Cancel()
235
235
  }
236
236
  inp.SetValue(2)
237
237
  if timesCalled != 1 {
@@ -62,7 +62,8 @@
62
62
  "diamond",
63
63
  "secret-handshake",
64
64
  "flatten-array",
65
- "perfect-numbers"
65
+ "perfect-numbers",
66
+ "change"
66
67
  ],
67
68
  "exercises": [
68
69
  {
@@ -359,6 +360,11 @@
359
360
  "slug": "perfect-numbers",
360
361
  "difficulty": 1,
361
362
  "topics": []
363
+ },
364
+ {
365
+ "slug": "change",
366
+ "difficulty": 1,
367
+ "topics": []
362
368
  }
363
369
  ],
364
370
  "deprecated": [
@@ -0,0 +1,17 @@
1
+ apply plugin: "java"
2
+ apply plugin: "eclipse"
3
+ apply plugin: "idea"
4
+
5
+ repositories {
6
+ mavenCentral()
7
+ }
8
+
9
+ dependencies {
10
+ testCompile "junit:junit:4.12"
11
+ }
12
+ test {
13
+ testLogging {
14
+ exceptionFormat = 'full'
15
+ events = ["passed", "failed", "skipped"]
16
+ }
17
+ }
@@ -0,0 +1,63 @@
1
+ import java.util.*;
2
+ import java.util.stream.Collectors;
3
+
4
+ import static java.util.Comparator.comparingInt;
5
+
6
+ final class ChangeCalculator {
7
+
8
+ private final List<Integer> currencyCoins;
9
+
10
+ ChangeCalculator(final List<Integer> currencyCoins) {
11
+ this.currencyCoins = currencyCoins;
12
+ Collections.sort(currencyCoins);
13
+ }
14
+
15
+ List<Integer> computeMostEfficientChange(final int grandTotal) {
16
+ if (grandTotal < 0) {
17
+ throw new IllegalArgumentException("Negative totals are not allowed.");
18
+ }
19
+
20
+ final Map<Integer, List<Integer>> minimalCoinsMap = new HashMap<>();
21
+ minimalCoinsMap.put(0, new ArrayList<>());
22
+
23
+ for (int total = 1; total <= grandTotal; total++) {
24
+ final int localTotal = total;
25
+
26
+ final List<Integer> minimalCoins = getCoinsNoLargerThan(total)
27
+ .stream()
28
+ .map(coin -> {
29
+ final List<Integer> minimalRemainderCoins = minimalCoinsMap.get(localTotal - coin);
30
+ return minimalRemainderCoins != null ? prepend(coin, minimalRemainderCoins) : null;
31
+ })
32
+ .filter(Objects::nonNull)
33
+ .sorted(comparingInt(List::size))
34
+ .findFirst()
35
+ .orElse(null);
36
+
37
+ minimalCoinsMap.put(localTotal, minimalCoins);
38
+ }
39
+
40
+ final List<Integer> resultCandidate = minimalCoinsMap.get(grandTotal);
41
+
42
+ if (resultCandidate == null) {
43
+ throw new IllegalArgumentException(
44
+ "The total " + grandTotal + " cannot be represented in the given currency.");
45
+ }
46
+
47
+ return resultCandidate;
48
+ }
49
+
50
+ private List<Integer> getCoinsNoLargerThan(final int threshold) {
51
+ return currencyCoins.stream()
52
+ .filter(coin -> coin <= threshold)
53
+ .collect(Collectors.toList());
54
+ }
55
+
56
+ private List<Integer> prepend(final int integer, final List<Integer> integers) {
57
+ final List<Integer> result = new ArrayList<>();
58
+ result.add(integer);
59
+ result.addAll(integers);
60
+ return result;
61
+ }
62
+
63
+ }
@@ -0,0 +1,5 @@
1
+ final class ChangeCalculator {
2
+
3
+
4
+
5
+ }
@@ -0,0 +1,114 @@
1
+ import org.junit.Ignore;
2
+ import org.junit.Rule;
3
+ import org.junit.Test;
4
+ import org.junit.rules.ExpectedException;
5
+
6
+ import static java.util.Arrays.asList;
7
+ import static java.util.Collections.emptyList;
8
+ import static java.util.Collections.singletonList;
9
+ import static org.junit.Assert.assertEquals;
10
+
11
+ public final class ChangeCalculatorTest {
12
+
13
+ /*
14
+ * See https://github.com/junit-team/junit4/wiki/Rules for information on JUnit Rules in general and
15
+ * ExpectedExceptions in particular.
16
+ */
17
+ @Rule
18
+ public ExpectedException expectedException = ExpectedException.none();
19
+
20
+ @Test
21
+ public void testChangeThatCanBeGivenInASingleCoin() {
22
+ ChangeCalculator changeCalculator = new ChangeCalculator(asList(1, 5, 10, 25, 100));
23
+
24
+ assertEquals(
25
+ singletonList(25),
26
+ changeCalculator.computeMostEfficientChange(25));
27
+ }
28
+
29
+ @Ignore
30
+ @Test
31
+ public void testChangeThatMustBeGivenInMultipleCoins() {
32
+ ChangeCalculator changeCalculator = new ChangeCalculator(asList(1, 5, 10, 25, 100));
33
+
34
+ assertEquals(
35
+ asList(5, 10),
36
+ changeCalculator.computeMostEfficientChange(15));
37
+ }
38
+
39
+ @Ignore
40
+ @Test
41
+ // https://en.wikipedia.org/wiki/Change-making_problem#Greedy_method
42
+ public void testLilliputianCurrencyForWhichGreedyAlgorithmFails() {
43
+ ChangeCalculator changeCalculator = new ChangeCalculator(asList(1, 4, 15, 20, 50));
44
+
45
+ assertEquals(
46
+ asList(4, 4, 15),
47
+ changeCalculator.computeMostEfficientChange(23));
48
+ }
49
+
50
+ @Ignore
51
+ @Test
52
+ // https://en.wikipedia.org/wiki/Change-making_problem#Greedy_method
53
+ public void testLowerElbonianCurrencyForWhichGreedyAlgorithmFails() {
54
+ ChangeCalculator changeCalculator = new ChangeCalculator(asList(1, 5, 10, 21, 25));
55
+
56
+ assertEquals(
57
+ asList(21, 21, 21),
58
+ changeCalculator.computeMostEfficientChange(63));
59
+ }
60
+
61
+ @Ignore
62
+ @Test
63
+ public void testLargeAmountOfChange() {
64
+ ChangeCalculator changeCalculator = new ChangeCalculator(asList(1, 2, 5, 10, 20, 50, 100));
65
+
66
+ assertEquals(
67
+ asList(2, 2, 5, 20, 20, 50, 100, 100, 100, 100, 100, 100, 100, 100, 100),
68
+ changeCalculator.computeMostEfficientChange(999));
69
+ }
70
+
71
+ @Ignore
72
+ @Test
73
+ public void testZeroChange() {
74
+ ChangeCalculator changeCalculator = new ChangeCalculator(asList(1, 5, 10, 21, 25));
75
+
76
+ assertEquals(
77
+ emptyList(),
78
+ changeCalculator.computeMostEfficientChange(0));
79
+ }
80
+
81
+ @Ignore
82
+ @Test
83
+ public void testChangeLessThanSmallestCoinInCurrencyCannotBeRepresented() {
84
+ ChangeCalculator changeCalculator = new ChangeCalculator(asList(5, 10));
85
+
86
+ expectedException.expect(IllegalArgumentException.class);
87
+ expectedException.expectMessage("The total 3 cannot be represented in the given currency.");
88
+
89
+ changeCalculator.computeMostEfficientChange(3);
90
+ }
91
+
92
+ @Ignore
93
+ @Test
94
+ public void testChangeLargerThanAllCoinsInCurrencyThatCannotBeRepresented() {
95
+ ChangeCalculator changeCalculator = new ChangeCalculator(asList(5, 10));
96
+
97
+ expectedException.expect(IllegalArgumentException.class);
98
+ expectedException.expectMessage("The total 94 cannot be represented in the given currency.");
99
+
100
+ changeCalculator.computeMostEfficientChange(94);
101
+ }
102
+
103
+ @Ignore
104
+ @Test
105
+ public void testNegativeChangeIsRejected() {
106
+ ChangeCalculator changeCalculator = new ChangeCalculator(asList(1, 2, 5));
107
+
108
+ expectedException.expect(IllegalArgumentException.class);
109
+ expectedException.expectMessage("Negative totals are not allowed.");
110
+
111
+ changeCalculator.computeMostEfficientChange(-5);
112
+ }
113
+
114
+ }
@@ -10,6 +10,7 @@ include 'binary-search'
10
10
  include 'binary-search-tree'
11
11
  include 'bob'
12
12
  include 'bracket-push'
13
+ include 'change'
13
14
  include 'clock'
14
15
  include 'crypto-square'
15
16
  include 'custom-set'
@@ -80,5 +80,5 @@ The MIT License (MIT)
80
80
  Copyright (c) 2015 Katrina Owen, _@kytrinyx.com
81
81
 
82
82
  ## Racket icon
83
- The Racket logo was created by [Matthias.f at en.wikipedia](https://en.wikipedia.org/wiki/User:Matthias.f) and released under the Creative Commons Attribution-Share Alike 3.0 Unported license.
84
- We adapted the Racket logo, creating a black/white version of it to use on Exercism.
83
+ The Racket logo was created by [Matthew Butterick](https://en.wikipedia.org/wiki/Matthew_Butterick) and released under the Creative Commons Attribution-Share Alike 3.0 Unported license.
84
+ We have adapted it, changing the colour scheme, for use on Exercism.
Binary file
@@ -1 +1 @@
1
- 3
1
+ 4
@@ -1,5 +1,5 @@
1
1
  module BookKeeping
2
- VERSION = 3
2
+ VERSION = 4
3
3
  end
4
4
 
5
5
  class Pangram
@@ -4,66 +4,69 @@ gem 'minitest', '>= 5.0.0'
4
4
  require 'minitest/autorun'
5
5
  require_relative 'pangram'
6
6
 
7
- # Test data version: # 2adfe21
7
+ # Test data version: # f04fb3d
8
8
  class PangramTest < Minitest::Test
9
9
  def test_sentence_empty
10
10
  # skip
11
11
  phrase = ''
12
- refute Pangram.pangram?(phrase), "#{phrase.inspect} is NOT a pangram"
12
+ result = Pangram.pangram?(phrase)
13
+ refute result, "Expected false, got: #{result.inspect}. #{phrase.inspect} is NOT a pangram"
13
14
  end
14
15
 
15
16
  def test_pangram_with_only_lower_case
16
17
  skip
17
18
  phrase = 'the quick brown fox jumps over the lazy dog'
18
- assert Pangram.pangram?(phrase), "#{phrase.inspect} IS a pangram"
19
+ result = Pangram.pangram?(phrase)
20
+ assert result, "Expected true, got: #{result.inspect}. #{phrase.inspect} IS a pangram"
19
21
  end
20
22
 
21
23
  def test_missing_character_x
22
24
  skip
23
25
  phrase = 'a quick movement of the enemy will jeopardize five gunboats'
24
- refute Pangram.pangram?(phrase), "#{phrase.inspect} is NOT a pangram"
26
+ result = Pangram.pangram?(phrase)
27
+ refute result, "Expected false, got: #{result.inspect}. #{phrase.inspect} is NOT a pangram"
25
28
  end
26
29
 
27
30
  def test_another_missing_character_x
28
31
  skip
29
32
  phrase = 'the quick brown fish jumps over the lazy dog'
30
- refute Pangram.pangram?(phrase), "#{phrase.inspect} is NOT a pangram"
33
+ result = Pangram.pangram?(phrase)
34
+ refute result, "Expected false, got: #{result.inspect}. #{phrase.inspect} is NOT a pangram"
31
35
  end
32
36
 
33
37
  def test_pangram_with_underscores
34
38
  skip
35
39
  phrase = 'the_quick_brown_fox_jumps_over_the_lazy_dog'
36
- assert Pangram.pangram?(phrase), "#{phrase.inspect} IS a pangram"
40
+ result = Pangram.pangram?(phrase)
41
+ assert result, "Expected true, got: #{result.inspect}. #{phrase.inspect} IS a pangram"
37
42
  end
38
43
 
39
44
  def test_pangram_with_numbers
40
45
  skip
41
46
  phrase = 'the 1 quick brown fox jumps over the 2 lazy dogs'
42
- assert Pangram.pangram?(phrase), "#{phrase.inspect} IS a pangram"
47
+ result = Pangram.pangram?(phrase)
48
+ assert result, "Expected true, got: #{result.inspect}. #{phrase.inspect} IS a pangram"
43
49
  end
44
50
 
45
51
  def test_missing_letters_replaced_by_numbers
46
52
  skip
47
53
  phrase = '7h3 qu1ck brown fox jumps ov3r 7h3 lazy dog'
48
- refute Pangram.pangram?(phrase), "#{phrase.inspect} is NOT a pangram"
54
+ result = Pangram.pangram?(phrase)
55
+ refute result, "Expected false, got: #{result.inspect}. #{phrase.inspect} is NOT a pangram"
49
56
  end
50
57
 
51
58
  def test_pangram_with_mixed_case_and_punctuation
52
59
  skip
53
60
  phrase = '"Five quacking Zephyrs jolt my wax bed."'
54
- assert Pangram.pangram?(phrase), "#{phrase.inspect} IS a pangram"
61
+ result = Pangram.pangram?(phrase)
62
+ assert result, "Expected true, got: #{result.inspect}. #{phrase.inspect} IS a pangram"
55
63
  end
56
64
 
57
- def test_pangram_with_non_ascii_characters
65
+ def test_upper_and_lower_case_versions_of_the_same_character_should_not_be_counted_separately
58
66
  skip
59
- phrase = 'Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich.'
60
- assert Pangram.pangram?(phrase), "#{phrase.inspect} IS a pangram"
61
- end
62
-
63
- def test_panagram_in_alphabet_other_than_ascii
64
- skip
65
- phrase = 'Широкая электрификация южных губерний даст мощный толчок подъёму сельского хозяйства.'
66
- refute Pangram.pangram?(phrase), "#{phrase.inspect} is NOT a pangram"
67
+ phrase = 'the quick brown fox jumped over the lazy FOX'
68
+ result = Pangram.pangram?(phrase)
69
+ refute result, "Expected false, got: #{result.inspect}. #{phrase.inspect} is NOT a pangram"
67
70
  end
68
71
 
69
72
  # Problems in exercism evolve over time, as we find better ways to ask
@@ -84,6 +87,6 @@ class PangramTest < Minitest::Test
84
87
  # http://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/constants.html
85
88
  def test_bookkeeping
86
89
  skip
87
- assert_equal 3, BookKeeping::VERSION
90
+ assert_equal 4, BookKeeping::VERSION
88
91
  end
89
92
  end
@@ -7,13 +7,14 @@ class PangramCase < OpenStruct
7
7
 
8
8
  def workload
9
9
  [
10
- "phrase = '#{input}'\n",
11
- " #{assertion} Pangram.pangram?(phrase), \"#{message}\""
12
- ].join
10
+ "phrase = '#{input}'",
11
+ " result = Pangram.pangram?(phrase)",
12
+ " #{assertion} result, \"#{message}\""
13
+ ].join("\n")
13
14
  end
14
15
 
15
16
  def message
16
- "\#{phrase.inspect} #{is_or_isnt} a pangram"
17
+ "Expected #{expected}, got: \#{result.inspect}. \#{phrase.inspect} #{is_or_isnt} a pangram"
17
18
  end
18
19
 
19
20
  def is_or_isnt
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trackler
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.6.43
4
+ version: 2.0.6.44
5
5
  platform: ruby
6
6
  authors:
7
7
  - Katrina Owen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-18 00:00:00.000000000 Z
11
+ date: 2017-02-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubyzip
@@ -3892,6 +3892,10 @@ files:
3892
3892
  - tracks/java/exercises/bracket-push/src/main/java/BracketChecker.java
3893
3893
  - tracks/java/exercises/bracket-push/src/test/java/BracketCheckerTest.java
3894
3894
  - tracks/java/exercises/build.gradle
3895
+ - tracks/java/exercises/change/build.gradle
3896
+ - tracks/java/exercises/change/src/example/java/ChangeCalculator.java
3897
+ - tracks/java/exercises/change/src/main/java/ChangeCalculator.java
3898
+ - tracks/java/exercises/change/src/test/java/ChangeCalculatorTest.java
3895
3899
  - tracks/java/exercises/clock/build.gradle
3896
3900
  - tracks/java/exercises/clock/src/example/java/Clock.java
3897
3901
  - tracks/java/exercises/clock/src/main/java/.keep