trackler 2.2.1.135 → 2.2.1.136

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/problem-specifications/exercises/pov/canonical-data.json +33 -1
  4. data/tracks/c/exercises/acronym/test/test_acronym.c +25 -17
  5. data/tracks/csharp/exercises/binary-search-tree/BinarySearchTreeTest.cs +37 -28
  6. data/tracks/csharp/generators/Exercises/BinarySearchTree.cs +69 -0
  7. data/tracks/haskell/config.json +1 -0
  8. data/tracks/haskell/exercises/accumulate/package.yaml +1 -1
  9. data/tracks/haskell/exercises/acronym/package.yaml +1 -1
  10. data/tracks/haskell/exercises/all-your-base/package.yaml +1 -1
  11. data/tracks/haskell/exercises/allergies/package.yaml +1 -1
  12. data/tracks/haskell/exercises/alphametics/package.yaml +1 -1
  13. data/tracks/haskell/exercises/anagram/package.yaml +1 -1
  14. data/tracks/haskell/exercises/atbash-cipher/package.yaml +1 -1
  15. data/tracks/haskell/exercises/bank-account/package.yaml +1 -1
  16. data/tracks/haskell/exercises/beer-song/package.yaml +1 -1
  17. data/tracks/haskell/exercises/binary-search-tree/package.yaml +1 -1
  18. data/tracks/haskell/exercises/binary/package.yaml +1 -1
  19. data/tracks/haskell/exercises/bob/package.yaml +1 -1
  20. data/tracks/haskell/exercises/bowling/package.yaml +1 -1
  21. data/tracks/haskell/exercises/bracket-push/package.yaml +1 -1
  22. data/tracks/haskell/exercises/change/package.yaml +1 -1
  23. data/tracks/haskell/exercises/clock/package.yaml +1 -1
  24. data/tracks/haskell/exercises/collatz-conjecture/package.yaml +1 -1
  25. data/tracks/haskell/exercises/complex-numbers/package.yaml +1 -1
  26. data/tracks/haskell/exercises/connect/package.yaml +1 -1
  27. data/tracks/haskell/exercises/crypto-square/package.yaml +1 -1
  28. data/tracks/haskell/exercises/custom-set/package.yaml +1 -1
  29. data/tracks/haskell/exercises/diamond/package.yaml +1 -1
  30. data/tracks/haskell/exercises/difference-of-squares/package.yaml +1 -1
  31. data/tracks/haskell/exercises/dominoes/package.yaml +1 -1
  32. data/tracks/haskell/exercises/etl/package.yaml +1 -1
  33. data/tracks/haskell/exercises/food-chain/package.yaml +1 -1
  34. data/tracks/haskell/exercises/forth/package.yaml +1 -1
  35. data/tracks/haskell/exercises/gigasecond/package.yaml +1 -1
  36. data/tracks/haskell/exercises/go-counting/package.yaml +1 -1
  37. data/tracks/haskell/exercises/grade-school/package.yaml +1 -1
  38. data/tracks/haskell/exercises/grains/package.yaml +1 -1
  39. data/tracks/haskell/exercises/hamming/package.yaml +1 -1
  40. data/tracks/haskell/exercises/hello-world/package.yaml +1 -1
  41. data/tracks/haskell/exercises/hexadecimal/package.yaml +1 -1
  42. data/tracks/haskell/exercises/house/package.yaml +1 -1
  43. data/tracks/haskell/exercises/isbn-verifier/package.yaml +1 -1
  44. data/tracks/haskell/exercises/isogram/package.yaml +1 -1
  45. data/tracks/haskell/exercises/kindergarten-garden/examples/success-standard/src/Garden.hs +1 -10
  46. data/tracks/haskell/exercises/kindergarten-garden/package.yaml +2 -3
  47. data/tracks/haskell/exercises/kindergarten-garden/src/Garden.hs +3 -7
  48. data/tracks/haskell/exercises/kindergarten-garden/test/Tests.hs +10 -16
  49. data/tracks/haskell/exercises/largest-series-product/package.yaml +1 -1
  50. data/tracks/haskell/exercises/leap/package.yaml +1 -1
  51. data/tracks/haskell/exercises/lens-person/examples/success-standard/package.yaml +0 -1
  52. data/tracks/haskell/exercises/lens-person/package.yaml +1 -1
  53. data/tracks/haskell/exercises/linked-list/package.yaml +1 -1
  54. data/tracks/haskell/exercises/list-ops/package.yaml +1 -1
  55. data/tracks/haskell/exercises/luhn/package.yaml +1 -1
  56. data/tracks/haskell/exercises/matrix/package.yaml +1 -1
  57. data/tracks/haskell/exercises/meetup/package.yaml +1 -1
  58. data/tracks/haskell/exercises/minesweeper/package.yaml +1 -1
  59. data/tracks/haskell/exercises/nth-prime/package.yaml +1 -1
  60. data/tracks/haskell/exercises/nucleotide-count/package.yaml +1 -1
  61. data/tracks/haskell/exercises/ocr-numbers/package.yaml +1 -1
  62. data/tracks/haskell/exercises/octal/package.yaml +1 -1
  63. data/tracks/haskell/exercises/palindrome-products/package.yaml +1 -1
  64. data/tracks/haskell/exercises/pangram/package.yaml +1 -1
  65. data/tracks/haskell/exercises/parallel-letter-frequency/package.yaml +1 -1
  66. data/tracks/haskell/exercises/pascals-triangle/package.yaml +1 -1
  67. data/tracks/haskell/exercises/perfect-numbers/package.yaml +1 -1
  68. data/tracks/haskell/exercises/phone-number/package.yaml +1 -1
  69. data/tracks/haskell/exercises/pig-latin/package.yaml +1 -1
  70. data/tracks/haskell/exercises/poker/package.yaml +1 -1
  71. data/tracks/haskell/exercises/pov/package.yaml +2 -2
  72. data/tracks/haskell/exercises/pov/test/Tests.hs +15 -0
  73. data/tracks/haskell/exercises/prime-factors/package.yaml +1 -1
  74. data/tracks/haskell/exercises/protein-translation/package.yaml +1 -1
  75. data/tracks/haskell/exercises/pythagorean-triplet/package.yaml +1 -1
  76. data/tracks/haskell/exercises/queen-attack/package.yaml +1 -1
  77. data/tracks/haskell/exercises/rail-fence-cipher/package.yaml +1 -1
  78. data/tracks/haskell/exercises/raindrops/package.yaml +1 -1
  79. data/tracks/haskell/exercises/rna-transcription/package.yaml +1 -1
  80. data/tracks/haskell/exercises/robot-name/package.yaml +1 -1
  81. data/tracks/haskell/exercises/robot-simulator/package.yaml +1 -1
  82. data/tracks/haskell/exercises/roman-numerals/package.yaml +1 -1
  83. data/tracks/haskell/exercises/rotational-cipher/package.yaml +1 -1
  84. data/tracks/haskell/exercises/run-length-encoding/package.yaml +1 -1
  85. data/tracks/haskell/exercises/saddle-points/package.yaml +1 -1
  86. data/tracks/haskell/exercises/say/package.yaml +1 -1
  87. data/tracks/haskell/exercises/scrabble-score/package.yaml +1 -1
  88. data/tracks/haskell/exercises/secret-handshake/package.yaml +1 -1
  89. data/tracks/haskell/exercises/series/package.yaml +1 -1
  90. data/tracks/haskell/exercises/sgf-parsing/package.yaml +1 -1
  91. data/tracks/haskell/exercises/sieve/package.yaml +1 -1
  92. data/tracks/haskell/exercises/simple-cipher/package.yaml +1 -1
  93. data/tracks/haskell/exercises/simple-linked-list/package.yaml +1 -1
  94. data/tracks/haskell/exercises/space-age/package.yaml +1 -1
  95. data/tracks/haskell/exercises/spiral-matrix/package.yaml +1 -1
  96. data/tracks/haskell/exercises/strain/package.yaml +1 -1
  97. data/tracks/haskell/exercises/sublist/package.yaml +1 -1
  98. data/tracks/haskell/exercises/sum-of-multiples/package.yaml +1 -1
  99. data/tracks/haskell/exercises/transpose/package.yaml +1 -1
  100. data/tracks/haskell/exercises/triangle/package.yaml +1 -1
  101. data/tracks/haskell/exercises/trinary/package.yaml +1 -1
  102. data/tracks/haskell/exercises/twelve-days/package.yaml +1 -1
  103. data/tracks/haskell/exercises/word-count/package.yaml +1 -1
  104. data/tracks/haskell/exercises/wordy/package.yaml +1 -1
  105. data/tracks/haskell/exercises/zebra-puzzle/package.yaml +1 -1
  106. data/tracks/haskell/exercises/zipper/package.yaml +1 -1
  107. data/tracks/java/CONTRIBUTING.md +39 -3
  108. data/tracks/java/POLICIES.md +68 -3
  109. data/tracks/java/exercises/crypto-square/README.md +4 -5
  110. data/tracks/java/exercises/error-handling/README.md +38 -0
  111. data/tracks/java/exercises/series/README.md +6 -6
  112. data/tracks/java/exercises/sieve/README.md +5 -3
  113. data/tracks/java/scripts/canonical_data_check.sh +1 -1
  114. data/tracks/python/exercises/react/example.py +54 -63
  115. data/tracks/python/exercises/react/react.py +10 -10
  116. data/tracks/python/exercises/react/react_test.py +197 -131
  117. data/tracks/python/exercises/sieve/README.md +5 -3
  118. data/tracks/rust/exercises/react/example.rs +103 -64
  119. data/tracks/rust/exercises/react/src/lib.rs +31 -17
  120. data/tracks/rust/exercises/react/tests/react.rs +52 -61
  121. data/tracks/swift/config.json +11 -0
  122. data/tracks/swift/exercises/circular-buffer/Sources/CircularBufferExample.swift +12 -12
  123. data/tracks/swift/exercises/circular-buffer/Tests/CircularBufferTests/CircularBufferTests.swift +1 -1
  124. data/tracks/swift/exercises/proverb/Package.swift +5 -0
  125. data/tracks/swift/exercises/proverb/README.md +25 -0
  126. data/tracks/swift/exercises/proverb/Sources/Proverb.swift +1 -0
  127. data/tracks/swift/exercises/proverb/Sources/ProverbExample.swift +28 -0
  128. data/tracks/swift/exercises/proverb/Tests/LinuxMain.swift +6 -0
  129. data/tracks/swift/exercises/proverb/Tests/ProverbTests/ProverbTests.swift +61 -0
  130. data/tracks/typescript/config.json +14 -0
  131. data/tracks/typescript/exercises/palindrome-products/README.md +65 -0
  132. data/tracks/typescript/exercises/palindrome-products/package.json +36 -0
  133. data/tracks/typescript/exercises/palindrome-products/palindrome-products.example.ts +38 -0
  134. data/tracks/typescript/exercises/palindrome-products/palindrome-products.test.ts +69 -0
  135. data/tracks/typescript/exercises/palindrome-products/palindrome-products.ts +0 -0
  136. data/tracks/typescript/exercises/palindrome-products/tsconfig.json +22 -0
  137. data/tracks/typescript/exercises/palindrome-products/tslint.json +127 -0
  138. data/tracks/typescript/exercises/palindrome-products/yarn.lock +2624 -0
  139. metadata +17 -2
@@ -1,12 +1,29 @@
1
- // Because these are passed without & to some functions,
2
- // it will probably be necessary for these two types to be Copy.
3
- pub type CellID = ();
4
- pub type CallbackID = ();
1
+ /// `InputCellID` is a unique identifier for an input cell.
2
+ #[derive(Clone, Copy, Debug, PartialEq)]
3
+ pub struct InputCellID();
4
+ /// `ComputeCellID` is a unique identifier for a compute cell.
5
+ /// Values of type `InputCellID` and `ComputeCellID` should not be mutually assignable,
6
+ /// demonstrated by the following tests:
7
+ ///
8
+ /// ```compile_fail
9
+ /// let mut r = react::Reactor::new();
10
+ /// let input: react::ComputeCellID = r.create_input(111);
11
+ /// ```
12
+ ///
13
+ /// ```compile_fail
14
+ /// let mut r = react::Reactor::new();
15
+ /// let input = r.create_input(111);
16
+ /// let compute: react::InputCellID = r.create_compute(&[react::CellID::Input(input)], |_| 222).unwrap();
17
+ /// ```
18
+ #[derive(Clone, Copy, Debug, PartialEq)]
19
+ pub struct ComputeCellID();
20
+ #[derive(Clone, Copy, Debug, PartialEq)]
21
+ pub struct CallbackID();
5
22
 
6
- #[derive(Debug, PartialEq)]
7
- pub enum SetValueError {
8
- NonexistentCell,
9
- ComputeCell,
23
+ #[derive(Clone, Copy, Debug, PartialEq)]
24
+ pub enum CellID {
25
+ Input(InputCellID),
26
+ Compute(ComputeCellID),
10
27
  }
11
28
 
12
29
  #[derive(Debug, PartialEq)]
@@ -28,7 +45,7 @@ impl <T: Copy + PartialEq> Reactor<T> {
28
45
  }
29
46
 
30
47
  // Creates an input cell with the specified initial value, returning its ID.
31
- pub fn create_input(&mut self, _initial: T) -> CellID {
48
+ pub fn create_input(&mut self, _initial: T) -> InputCellID {
32
49
  unimplemented!()
33
50
  }
34
51
 
@@ -45,7 +62,7 @@ impl <T: Copy + PartialEq> Reactor<T> {
45
62
  // Notice that there is no way to *remove* a cell.
46
63
  // This means that you may assume, without checking, that if the dependencies exist at creation
47
64
  // time they will continue to exist as long as the Reactor exists.
48
- pub fn create_compute<F: Fn(&[T]) -> T>(&mut self, _dependencies: &[CellID], _compute_func: F) -> Result<CellID, CellID> {
65
+ pub fn create_compute<F: Fn(&[T]) -> T>(&mut self, _dependencies: &[CellID], _compute_func: F) -> Result<ComputeCellID, CellID> {
49
66
  unimplemented!()
50
67
  }
51
68
 
@@ -62,16 +79,13 @@ impl <T: Copy + PartialEq> Reactor<T> {
62
79
 
63
80
  // Sets the value of the specified input cell.
64
81
  //
65
- // Returns an Err if either:
66
- // * the cell does not exist
67
- // * the specified cell is a compute cell, since compute cells cannot have their values
68
- // directly set.
82
+ // Returns false if the cell does not exist.
69
83
  //
70
84
  // Similarly, you may wonder about `get_mut(&mut self, id: CellID) -> Option<&mut Cell>`, with
71
85
  // a `set_value(&mut self, new_value: T)` method on `Cell`.
72
86
  //
73
87
  // As before, that turned out to add too much extra complexity.
74
- pub fn set_value(&mut self, _id: CellID, _new_value: T) -> Result<(), SetValueError> {
88
+ pub fn set_value(&mut self, _id: InputCellID, _new_value: T) -> bool {
75
89
  unimplemented!()
76
90
  }
77
91
 
@@ -87,7 +101,7 @@ impl <T: Copy + PartialEq> Reactor<T> {
87
101
  // * Exactly once if the compute cell's value changed as a result of the set_value call.
88
102
  // The value passed to the callback should be the final value of the compute cell after the
89
103
  // set_value call.
90
- pub fn add_callback<F: FnMut(T) -> ()>(&mut self, _id: CellID, _callback: F) -> Option<CallbackID> {
104
+ pub fn add_callback<F: FnMut(T) -> ()>(&mut self, _id: ComputeCellID, _callback: F) -> Option<CallbackID> {
91
105
  unimplemented!()
92
106
  }
93
107
 
@@ -96,7 +110,7 @@ impl <T: Copy + PartialEq> Reactor<T> {
96
110
  // Returns an Err if either the cell or callback does not exist.
97
111
  //
98
112
  // A removed callback should no longer be called.
99
- pub fn remove_callback(&mut self, cell: CellID, callback: CallbackID) -> Result<(), RemoveCallbackError> {
113
+ pub fn remove_callback(&mut self, cell: ComputeCellID, callback: CallbackID) -> Result<(), RemoveCallbackError> {
100
114
  unimplemented!(
101
115
  "Remove the callback identified by the CallbackID {:?} from the cell {:?}",
102
116
  callback,
@@ -6,7 +6,7 @@ use react::*;
6
6
  fn input_cells_have_a_value() {
7
7
  let mut reactor = Reactor::new();
8
8
  let input = reactor.create_input(10);
9
- assert_eq!(reactor.value(input), Some(10));
9
+ assert_eq!(reactor.value(CellID::Input(input)), Some(10));
10
10
  }
11
11
 
12
12
  #[test]
@@ -14,8 +14,8 @@ fn input_cells_have_a_value() {
14
14
  fn an_input_cells_value_can_be_set() {
15
15
  let mut reactor = Reactor::new();
16
16
  let input = reactor.create_input(4);
17
- assert!(reactor.set_value(input, 20).is_ok());
18
- assert_eq!(reactor.value(input), Some(20));
17
+ assert!(reactor.set_value(input, 20));
18
+ assert_eq!(reactor.value(CellID::Input(input)), Some(20));
19
19
  }
20
20
 
21
21
  #[test]
@@ -23,7 +23,7 @@ fn an_input_cells_value_can_be_set() {
23
23
  fn error_setting_a_nonexistent_input_cell() {
24
24
  let mut dummy_reactor = Reactor::new();
25
25
  let input = dummy_reactor.create_input(1);
26
- assert_eq!(Reactor::new().set_value(input, 0), Err(SetValueError::NonexistentCell));
26
+ assert!(!Reactor::new().set_value(input, 0));
27
27
  }
28
28
 
29
29
  #[test]
@@ -31,8 +31,8 @@ fn error_setting_a_nonexistent_input_cell() {
31
31
  fn compute_cells_calculate_initial_value() {
32
32
  let mut reactor = Reactor::new();
33
33
  let input = reactor.create_input(1);
34
- let output = reactor.create_compute(&[input], |v| v[0] + 1).unwrap();
35
- assert_eq!(reactor.value(output), Some(2));
34
+ let output = reactor.create_compute(&[CellID::Input(input)], |v| v[0] + 1).unwrap();
35
+ assert_eq!(reactor.value(CellID::Compute(output)), Some(2));
36
36
  }
37
37
 
38
38
  #[test]
@@ -41,8 +41,8 @@ fn compute_cells_take_inputs_in_the_right_order() {
41
41
  let mut reactor = Reactor::new();
42
42
  let one = reactor.create_input(1);
43
43
  let two = reactor.create_input(2);
44
- let output = reactor.create_compute(&[one, two], |v| v[0] + v[1] * 10).unwrap();
45
- assert_eq!(reactor.value(output), Some(21));
44
+ let output = reactor.create_compute(&[CellID::Input(one), CellID::Input(two)], |v| v[0] + v[1] * 10).unwrap();
45
+ assert_eq!(reactor.value(CellID::Compute(output)), Some(21));
46
46
  }
47
47
 
48
48
  #[test]
@@ -50,7 +50,7 @@ fn compute_cells_take_inputs_in_the_right_order() {
50
50
  fn error_creating_compute_cell_if_input_doesnt_exist() {
51
51
  let mut dummy_reactor = Reactor::new();
52
52
  let input = dummy_reactor.create_input(1);
53
- assert_eq!(Reactor::new().create_compute(&[input], |_| 0), Err(input));
53
+ assert_eq!(Reactor::new().create_compute(&[CellID::Input(input)], |_| 0), Err(CellID::Input(input)));
54
54
  }
55
55
 
56
56
  #[test]
@@ -61,9 +61,9 @@ fn do_not_break_cell_if_creating_compute_cell_with_valid_and_invalid_input() {
61
61
  let dummy_cell = dummy_reactor.create_input(2);
62
62
  let mut reactor = Reactor::new();
63
63
  let input = reactor.create_input(1);
64
- assert_eq!(reactor.create_compute(&[input, dummy_cell], |_| 0), Err(dummy_cell));
65
- assert!(reactor.set_value(input, 5).is_ok());
66
- assert_eq!(reactor.value(input), Some(5));
64
+ assert_eq!(reactor.create_compute(&[CellID::Input(input), CellID::Input(dummy_cell)], |_| 0), Err(CellID::Input(dummy_cell)));
65
+ assert!(reactor.set_value(input, 5));
66
+ assert_eq!(reactor.value(CellID::Input(input)), Some(5));
67
67
  }
68
68
 
69
69
  #[test]
@@ -71,10 +71,10 @@ fn do_not_break_cell_if_creating_compute_cell_with_valid_and_invalid_input() {
71
71
  fn compute_cells_update_value_when_dependencies_are_changed() {
72
72
  let mut reactor = Reactor::new();
73
73
  let input = reactor.create_input(1);
74
- let output = reactor.create_compute(&[input], |v| v[0] + 1).unwrap();
75
- assert_eq!(reactor.value(output), Some(2));
76
- assert!(reactor.set_value(input, 3).is_ok());
77
- assert_eq!(reactor.value(output), Some(4));
74
+ let output = reactor.create_compute(&[CellID::Input(input)], |v| v[0] + 1).unwrap();
75
+ assert_eq!(reactor.value(CellID::Compute(output)), Some(2));
76
+ assert!(reactor.set_value(input, 3));
77
+ assert_eq!(reactor.value(CellID::Compute(output)), Some(4));
78
78
  }
79
79
 
80
80
  #[test]
@@ -82,21 +82,12 @@ fn compute_cells_update_value_when_dependencies_are_changed() {
82
82
  fn compute_cells_can_depend_on_other_compute_cells() {
83
83
  let mut reactor = Reactor::new();
84
84
  let input = reactor.create_input(1);
85
- let times_two = reactor.create_compute(&[input], |v| v[0] * 2).unwrap();
86
- let times_thirty = reactor.create_compute(&[input], |v| v[0] * 30).unwrap();
87
- let output = reactor.create_compute(&[times_two, times_thirty], |v| v[0] + v[1]).unwrap();
88
- assert_eq!(reactor.value(output), Some(32));
89
- assert!(reactor.set_value(input, 3).is_ok());
90
- assert_eq!(reactor.value(output), Some(96));
91
- }
92
-
93
- #[test]
94
- #[ignore]
95
- fn error_setting_a_compute_cell() {
96
- let mut reactor = Reactor::new();
97
- let input = reactor.create_input(1);
98
- let output = reactor.create_compute(&[input], |_| 0).unwrap();
99
- assert_eq!(reactor.set_value(output, 3), Err(SetValueError::ComputeCell));
85
+ let times_two = reactor.create_compute(&[CellID::Input(input)], |v| v[0] * 2).unwrap();
86
+ let times_thirty = reactor.create_compute(&[CellID::Input(input)], |v| v[0] * 30).unwrap();
87
+ let output = reactor.create_compute(&[CellID::Compute(times_two), CellID::Compute(times_thirty)], |v| v[0] + v[1]).unwrap();
88
+ assert_eq!(reactor.value(CellID::Compute(output)), Some(32));
89
+ assert!(reactor.set_value(input, 3));
90
+ assert_eq!(reactor.value(CellID::Compute(output)), Some(96));
100
91
  }
101
92
 
102
93
  /// A CallbackRecorder helps tests whether callbacks get called correctly.
@@ -138,9 +129,9 @@ fn compute_cells_fire_callbacks() {
138
129
  let cb = CallbackRecorder::new();
139
130
  let mut reactor = Reactor::new();
140
131
  let input = reactor.create_input(1);
141
- let output = reactor.create_compute(&[input], |v| v[0] + 1).unwrap();
132
+ let output = reactor.create_compute(&[CellID::Input(input)], |v| v[0] + 1).unwrap();
142
133
  assert!(reactor.add_callback(output, |v| cb.callback_called(v)).is_some());
143
- assert!(reactor.set_value(input, 3).is_ok());
134
+ assert!(reactor.set_value(input, 3));
144
135
  cb.expect_to_have_been_called_with(4);
145
136
  }
146
137
 
@@ -149,7 +140,7 @@ fn compute_cells_fire_callbacks() {
149
140
  fn error_adding_callback_to_nonexistent_cell() {
150
141
  let mut dummy_reactor = Reactor::new();
151
142
  let input = dummy_reactor.create_input(1);
152
- let output = dummy_reactor.create_compute(&[input], |_| 0).unwrap();
143
+ let output = dummy_reactor.create_compute(&[CellID::Input(input)], |_| 0).unwrap();
153
144
  assert_eq!(Reactor::new().add_callback(output, |_: usize| println!("hi")), None);
154
145
  }
155
146
 
@@ -159,12 +150,12 @@ fn callbacks_only_fire_on_change() {
159
150
  let cb = CallbackRecorder::new();
160
151
  let mut reactor = Reactor::new();
161
152
  let input = reactor.create_input(1);
162
- let output = reactor.create_compute(&[input], |v| if v[0] < 3 { 111 } else { 222 }).unwrap();
153
+ let output = reactor.create_compute(&[CellID::Input(input)], |v| if v[0] < 3 { 111 } else { 222 }).unwrap();
163
154
  assert!(reactor.add_callback(output, |v| cb.callback_called(v)).is_some());
164
155
 
165
- assert!(reactor.set_value(input, 2).is_ok());
156
+ assert!(reactor.set_value(input, 2));
166
157
  cb.expect_not_to_have_been_called();
167
- assert!(reactor.set_value(input, 4).is_ok());
158
+ assert!(reactor.set_value(input, 4));
168
159
  cb.expect_to_have_been_called_with(222);
169
160
  }
170
161
 
@@ -177,19 +168,19 @@ fn callbacks_can_be_added_and_removed() {
177
168
 
178
169
  let mut reactor = Reactor::new();
179
170
  let input = reactor.create_input(11);
180
- let output = reactor.create_compute(&[input], |v| v[0] + 1).unwrap();
171
+ let output = reactor.create_compute(&[CellID::Input(input)], |v| v[0] + 1).unwrap();
181
172
 
182
173
  let callback = reactor.add_callback(output, |v| cb1.callback_called(v)).unwrap();
183
174
  assert!(reactor.add_callback(output, |v| cb2.callback_called(v)).is_some());
184
175
 
185
- assert!(reactor.set_value(input, 31).is_ok());
176
+ assert!(reactor.set_value(input, 31));
186
177
  cb1.expect_to_have_been_called_with(32);
187
178
  cb2.expect_to_have_been_called_with(32);
188
179
 
189
180
  assert!(reactor.remove_callback(output, callback).is_ok());
190
181
  assert!(reactor.add_callback(output, |v| cb3.callback_called(v)).is_some());
191
182
 
192
- assert!(reactor.set_value(input, 41).is_ok());
183
+ assert!(reactor.set_value(input, 41));
193
184
  cb1.expect_not_to_have_been_called();
194
185
  cb2.expect_to_have_been_called_with(42);
195
186
  cb3.expect_to_have_been_called_with(42);
@@ -203,7 +194,7 @@ fn removing_a_callback_multiple_times_doesnt_interfere_with_other_callbacks() {
203
194
 
204
195
  let mut reactor = Reactor::new();
205
196
  let input = reactor.create_input(1);
206
- let output = reactor.create_compute(&[input], |v| v[0] + 1).unwrap();
197
+ let output = reactor.create_compute(&[CellID::Input(input)], |v| v[0] + 1).unwrap();
207
198
  let callback = reactor.add_callback(output, |v| cb1.callback_called(v)).unwrap();
208
199
  assert!(reactor.add_callback(output, |v| cb2.callback_called(v)).is_some());
209
200
  // We want the first remove to be Ok, but the others should be errors.
@@ -212,7 +203,7 @@ fn removing_a_callback_multiple_times_doesnt_interfere_with_other_callbacks() {
212
203
  assert_eq!(reactor.remove_callback(output, callback), Err(RemoveCallbackError::NonexistentCallback));
213
204
  }
214
205
 
215
- assert!(reactor.set_value(input, 2).is_ok());
206
+ assert!(reactor.set_value(input, 2));
216
207
  cb1.expect_not_to_have_been_called();
217
208
  cb2.expect_to_have_been_called_with(3);
218
209
  }
@@ -223,12 +214,12 @@ fn callbacks_should_only_be_called_once_even_if_multiple_dependencies_change() {
223
214
  let cb = CallbackRecorder::new();
224
215
  let mut reactor = Reactor::new();
225
216
  let input = reactor.create_input(1);
226
- let plus_one = reactor.create_compute(&[input], |v| v[0] + 1).unwrap();
227
- let minus_one1 = reactor.create_compute(&[input], |v| v[0] - 1).unwrap();
228
- let minus_one2 = reactor.create_compute(&[minus_one1], |v| v[0] - 1).unwrap();
229
- let output = reactor.create_compute(&[plus_one, minus_one2], |v| v[0] * v[1]).unwrap();
217
+ let plus_one = reactor.create_compute(&[CellID::Input(input)], |v| v[0] + 1).unwrap();
218
+ let minus_one1 = reactor.create_compute(&[CellID::Input(input)], |v| v[0] - 1).unwrap();
219
+ let minus_one2 = reactor.create_compute(&[CellID::Compute(minus_one1)], |v| v[0] - 1).unwrap();
220
+ let output = reactor.create_compute(&[CellID::Compute(plus_one), CellID::Compute(minus_one2)], |v| v[0] * v[1]).unwrap();
230
221
  assert!(reactor.add_callback(output, |v| cb.callback_called(v)).is_some());
231
- assert!(reactor.set_value(input, 4).is_ok());
222
+ assert!(reactor.set_value(input, 4));
232
223
  cb.expect_to_have_been_called_with(10);
233
224
  }
234
225
 
@@ -238,12 +229,12 @@ fn callbacks_should_not_be_called_if_dependencies_change_but_output_value_doesnt
238
229
  let cb = CallbackRecorder::new();
239
230
  let mut reactor = Reactor::new();
240
231
  let input = reactor.create_input(1);
241
- let plus_one = reactor.create_compute(&[input], |v| v[0] + 1).unwrap();
242
- let minus_one = reactor.create_compute(&[input], |v| v[0] - 1).unwrap();
243
- let always_two = reactor.create_compute(&[plus_one, minus_one], |v| v[0] - v[1]).unwrap();
232
+ let plus_one = reactor.create_compute(&[CellID::Input(input)], |v| v[0] + 1).unwrap();
233
+ let minus_one = reactor.create_compute(&[CellID::Input(input)], |v| v[0] - 1).unwrap();
234
+ let always_two = reactor.create_compute(&[CellID::Compute(plus_one), CellID::Compute(minus_one)], |v| v[0] - v[1]).unwrap();
244
235
  assert!(reactor.add_callback(always_two, |v| cb.callback_called(v)).is_some());
245
236
  for i in 2..5 {
246
- assert!(reactor.set_value(input, i).is_ok());
237
+ assert!(reactor.set_value(input, i));
247
238
  cb.expect_not_to_have_been_called();
248
239
  }
249
240
  }
@@ -258,12 +249,12 @@ fn test_adder_with_boolean_values() {
258
249
  let b = reactor.create_input(false);
259
250
  let carry_in = reactor.create_input(false);
260
251
 
261
- let a_xor_b = reactor.create_compute(&[a, b], |v| v[0] ^ v[1]).unwrap();
262
- let sum = reactor.create_compute(&[a_xor_b, carry_in], |v| v[0] ^ v[1]).unwrap();
252
+ let a_xor_b = reactor.create_compute(&[CellID::Input(a), CellID::Input(b)], |v| v[0] ^ v[1]).unwrap();
253
+ let sum = reactor.create_compute(&[CellID::Compute(a_xor_b), CellID::Input(carry_in)], |v| v[0] ^ v[1]).unwrap();
263
254
 
264
- let a_xor_b_and_cin = reactor.create_compute(&[a_xor_b, carry_in], |v| v[0] && v[1]).unwrap();
265
- let a_and_b = reactor.create_compute(&[a, b], |v| v[0] && v[1]).unwrap();
266
- let carry_out = reactor.create_compute(&[a_xor_b_and_cin, a_and_b], |v| v[0] || v[1]).unwrap();
255
+ let a_xor_b_and_cin = reactor.create_compute(&[CellID::Compute(a_xor_b), CellID::Input(carry_in)], |v| v[0] && v[1]).unwrap();
256
+ let a_and_b = reactor.create_compute(&[CellID::Input(a), CellID::Input(b)], |v| v[0] && v[1]).unwrap();
257
+ let carry_out = reactor.create_compute(&[CellID::Compute(a_xor_b_and_cin), CellID::Compute(a_and_b)], |v| v[0] || v[1]).unwrap();
267
258
 
268
259
  let tests = &[
269
260
  (false, false, false, false, false),
@@ -277,11 +268,11 @@ fn test_adder_with_boolean_values() {
277
268
  ];
278
269
 
279
270
  for &(aval, bval, cinval, expected_cout, expected_sum) in tests {
280
- assert!(reactor.set_value(a, aval).is_ok());
281
- assert!(reactor.set_value(b, bval).is_ok());
282
- assert!(reactor.set_value(carry_in, cinval).is_ok());
271
+ assert!(reactor.set_value(a, aval));
272
+ assert!(reactor.set_value(b, bval));
273
+ assert!(reactor.set_value(carry_in, cinval));
283
274
 
284
- assert_eq!(reactor.value(sum), Some(expected_sum));
285
- assert_eq!(reactor.value(carry_out), Some(expected_cout));
275
+ assert_eq!(reactor.value(CellID::Compute(sum)), Some(expected_sum));
276
+ assert_eq!(reactor.value(CellID::Compute(carry_out)), Some(expected_cout));
286
277
  }
287
278
  }
@@ -438,6 +438,17 @@
438
438
  "loops"
439
439
  ]
440
440
  },
441
+ {
442
+ "core": false,
443
+ "difficulty": 3,
444
+ "slug": "proverb",
445
+ "topics": [
446
+ "algorithms",
447
+ "strings"
448
+ ],
449
+ "unlocked_by": null,
450
+ "uuid": "9604f1ef-4925-4c28-9c59-b986c1a42c7e"
451
+ },
441
452
  {
442
453
  "core": false,
443
454
  "difficulty": 4,
@@ -10,29 +10,29 @@ struct CircularBuffer<T: Equatable> {
10
10
  let capacity: Int
11
11
  var writePoint = 0
12
12
  var readPoint = 0
13
-
13
+
14
14
  private var isFull: Bool {
15
15
  return buffer.flatMap { $0 }.count >= capacity
16
16
  }
17
-
17
+
18
18
  private var isEmpty: Bool {
19
19
  return buffer.flatMap { $0 }.isEmpty
20
20
  }
21
-
21
+
22
22
  init(capacity: Int) {
23
23
  self.capacity = capacity
24
24
  buffer = [T?](repeating: nil, count: capacity)
25
25
  }
26
-
26
+
27
27
  mutating func write(_ data: T) throws {
28
28
  guard !isFull else {
29
29
  throw CircularBufferError.bufferFull
30
30
  }
31
-
31
+
32
32
  buffer[writePoint] = data
33
33
  updateWritePoint()
34
34
  }
35
-
35
+
36
36
  mutating func overwrite(_ data: T) {
37
37
  buffer[writePoint] = data
38
38
  if isFull && writePoint == readPoint {
@@ -40,26 +40,26 @@ struct CircularBuffer<T: Equatable> {
40
40
  }
41
41
  updateWritePoint()
42
42
  }
43
-
43
+
44
44
  mutating func read() throws -> T {
45
45
  guard let data = buffer[readPoint] else {
46
46
  throw CircularBufferError.bufferEmpty
47
47
  }
48
-
48
+
49
49
  buffer[readPoint] = nil
50
50
  updateReadPoint()
51
-
51
+
52
52
  return data
53
53
  }
54
-
54
+
55
55
  mutating func clear() {
56
56
  buffer = [T?](repeating: nil, count: capacity)
57
57
  }
58
-
58
+
59
59
  private mutating func updateWritePoint() {
60
60
  writePoint = (writePoint + 1) % capacity
61
61
  }
62
-
62
+
63
63
  private mutating func updateReadPoint() {
64
64
  readPoint = (readPoint + 1) % capacity
65
65
  }
@@ -2,7 +2,7 @@ import XCTest
2
2
  @testable import CircularBuffer
3
3
 
4
4
  class CircularBufferTests: XCTestCase {
5
-
5
+
6
6
  func testReadEmptyBufferThrowsBufferEmptyException() {
7
7
  var buffer = CircularBuffer<Int>(capacity: 1)
8
8
 
@@ -0,0 +1,5 @@
1
+ import PackageDescription
2
+
3
+ let package = Package(
4
+ name: "Proverb"
5
+ )