trackler 2.0.6.43 → 2.0.6.44

Sign up to get free protection for your applications and to get access to all the features.
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