trackler 2.0.6.14 → 2.0.6.15
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/tracks/ceylon/.travis.yml +1 -0
- data/tracks/ceylon/bin/compile-all-stubs +16 -0
- data/tracks/ceylon/config.json +11 -0
- data/tracks/ceylon/exercises/react/example/Reactor.ceylon +96 -0
- data/tracks/ceylon/exercises/react/example/module.ceylon +4 -0
- data/tracks/ceylon/exercises/react/source/react/Reactor.ceylon +29 -0
- data/tracks/ceylon/exercises/react/source/react/ReactorTest.ceylon +195 -0
- data/tracks/ceylon/exercises/react/source/react/module.ceylon +3 -0
- data/tracks/csharp/config.json +9 -0
- data/tracks/csharp/exercises/pov/Example.cs +17 -17
- data/tracks/csharp/exercises/zipper/Example.cs +137 -0
- data/tracks/csharp/exercises/zipper/ZipperTest.cs +83 -0
- data/tracks/go/config.json +9 -0
- data/tracks/go/exercises/transpose/cases_test.go +247 -0
- data/tracks/go/exercises/transpose/example.go +25 -0
- data/tracks/go/exercises/transpose/example_gen.go +54 -0
- data/tracks/go/exercises/transpose/transpose_test.go +39 -0
- data/tracks/go/exercises/triangle/triangle.go +1 -1
- data/tracks/haskell/.travis.yml +2 -2
- data/tracks/haskell/common/stack.yaml +1 -1
- data/tracks/haskell/exercises/accumulate/stack.yaml +1 -1
- data/tracks/haskell/exercises/all-your-base/stack.yaml +1 -1
- data/tracks/haskell/exercises/allergies/stack.yaml +1 -1
- data/tracks/haskell/exercises/alphametics/stack.yaml +1 -1
- data/tracks/haskell/exercises/anagram/stack.yaml +1 -1
- data/tracks/haskell/exercises/atbash-cipher/stack.yaml +1 -1
- data/tracks/haskell/exercises/bank-account/stack.yaml +1 -1
- data/tracks/haskell/exercises/beer-song/stack.yaml +1 -1
- data/tracks/haskell/exercises/binary-search-tree/stack.yaml +1 -1
- data/tracks/haskell/exercises/binary/stack.yaml +1 -1
- data/tracks/haskell/exercises/bob/stack.yaml +1 -1
- data/tracks/haskell/exercises/bowling/stack.yaml +1 -1
- data/tracks/haskell/exercises/change/stack.yaml +1 -1
- data/tracks/haskell/exercises/clock/stack.yaml +1 -1
- data/tracks/haskell/exercises/connect/stack.yaml +1 -1
- data/tracks/haskell/exercises/crypto-square/stack.yaml +1 -1
- data/tracks/haskell/exercises/custom-set/stack.yaml +1 -1
- data/tracks/haskell/exercises/difference-of-squares/stack.yaml +1 -1
- data/tracks/haskell/exercises/dominoes/stack.yaml +1 -1
- data/tracks/haskell/exercises/etl/stack.yaml +1 -1
- data/tracks/haskell/exercises/food-chain/stack.yaml +1 -1
- data/tracks/haskell/exercises/forth/stack.yaml +1 -1
- data/tracks/haskell/exercises/gigasecond/stack.yaml +1 -1
- data/tracks/haskell/exercises/go-counting/stack.yaml +1 -1
- data/tracks/haskell/exercises/grade-school/stack.yaml +1 -1
- data/tracks/haskell/exercises/grains/stack.yaml +1 -1
- data/tracks/haskell/exercises/hamming/stack.yaml +1 -1
- data/tracks/haskell/exercises/hexadecimal/stack.yaml +1 -1
- data/tracks/haskell/exercises/house/stack.yaml +1 -1
- data/tracks/haskell/exercises/kindergarten-garden/stack.yaml +1 -1
- data/tracks/haskell/exercises/largest-series-product/stack.yaml +1 -1
- data/tracks/haskell/exercises/leap/stack.yaml +1 -1
- data/tracks/haskell/exercises/lens-person/stack.yaml +1 -1
- data/tracks/haskell/exercises/linked-list/stack.yaml +1 -1
- data/tracks/haskell/exercises/list-ops/stack.yaml +1 -1
- data/tracks/haskell/exercises/luhn/stack.yaml +1 -1
- data/tracks/haskell/exercises/matrix/stack.yaml +1 -1
- data/tracks/haskell/exercises/meetup/stack.yaml +1 -1
- data/tracks/haskell/exercises/minesweeper/stack.yaml +1 -1
- data/tracks/haskell/exercises/nth-prime/stack.yaml +1 -1
- data/tracks/haskell/exercises/nucleotide-count/stack.yaml +1 -1
- data/tracks/haskell/exercises/ocr-numbers/stack.yaml +1 -1
- data/tracks/haskell/exercises/octal/stack.yaml +1 -1
- data/tracks/haskell/exercises/palindrome-products/stack.yaml +1 -1
- data/tracks/haskell/exercises/parallel-letter-frequency/stack.yaml +1 -1
- data/tracks/haskell/exercises/pascals-triangle/stack.yaml +1 -1
- data/tracks/haskell/exercises/phone-number/stack.yaml +1 -1
- data/tracks/haskell/exercises/pig-latin/stack.yaml +1 -1
- data/tracks/haskell/exercises/pov/stack.yaml +1 -1
- data/tracks/haskell/exercises/prime-factors/stack.yaml +1 -1
- data/tracks/haskell/exercises/pythagorean-triplet/stack.yaml +1 -1
- data/tracks/haskell/exercises/queen-attack/stack.yaml +1 -1
- data/tracks/haskell/exercises/raindrops/stack.yaml +1 -1
- data/tracks/haskell/exercises/rna-transcription/stack.yaml +1 -1
- data/tracks/haskell/exercises/robot-name/stack.yaml +1 -1
- data/tracks/haskell/exercises/robot-simulator/stack.yaml +1 -1
- data/tracks/haskell/exercises/roman-numerals/stack.yaml +1 -1
- data/tracks/haskell/exercises/run-length-encoding/stack.yaml +1 -1
- data/tracks/haskell/exercises/saddle-points/stack.yaml +1 -1
- data/tracks/haskell/exercises/say/stack.yaml +1 -1
- data/tracks/haskell/exercises/scrabble-score/stack.yaml +1 -1
- data/tracks/haskell/exercises/secret-handshake/stack.yaml +1 -1
- data/tracks/haskell/exercises/series/stack.yaml +1 -1
- data/tracks/haskell/exercises/sgf-parsing/stack.yaml +1 -1
- data/tracks/haskell/exercises/sieve/stack.yaml +1 -1
- data/tracks/haskell/exercises/simple-cipher/stack.yaml +1 -1
- data/tracks/haskell/exercises/simple-linked-list/stack.yaml +1 -1
- data/tracks/haskell/exercises/space-age/stack.yaml +1 -1
- data/tracks/haskell/exercises/strain/stack.yaml +1 -1
- data/tracks/haskell/exercises/sublist/stack.yaml +1 -1
- data/tracks/haskell/exercises/sum-of-multiples/stack.yaml +1 -1
- data/tracks/haskell/exercises/triangle/stack.yaml +1 -1
- data/tracks/haskell/exercises/trinary/stack.yaml +1 -1
- data/tracks/haskell/exercises/word-count/stack.yaml +1 -1
- data/tracks/haskell/exercises/wordy/stack.yaml +1 -1
- data/tracks/haskell/exercises/zebra-puzzle/stack.yaml +1 -1
- data/tracks/haskell/exercises/zipper/stack.yaml +1 -1
- data/tracks/lua/exercises/list-ops/list-ops_spec.lua +1 -1
- data/tracks/objective-c/config.json +9 -0
- data/tracks/objective-c/exercises/beer-song/BeerSongExample.h +7 -0
- data/tracks/objective-c/exercises/beer-song/BeerSongExample.m +56 -0
- data/tracks/objective-c/exercises/beer-song/BeerSongTest.m +51 -0
- data/tracks/objective-c/xcodeProject/ObjectiveC.xcodeproj/project.pbxproj +23 -1
- data/tracks/objective-c/xcodeProject/ObjectiveC.xcodeproj/xcshareddata/xcschemes/OCLint.xcscheme +1 -1
- data/tracks/objective-c/xcodeProject/ObjectiveC.xcodeproj/xcshareddata/xcschemes/xobjectivecTest.xcscheme +1 -1
- data/tracks/perl6/config.json +5 -0
- data/tracks/perl6/exercises/grade-school/Example.pm +17 -0
- data/tracks/perl6/exercises/grade-school/grade-school.t +32 -0
- data/tracks/scala/config.json +6 -0
- data/tracks/scala/exercises/rna-transcription/build.sbt +2 -2
- data/tracks/scala/exercises/sublist/build.sbt +2 -2
- data/tracks/scala/exercises/sublist/src/test/scala/SublistTest.scala +1 -1
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d2be37cbc31136941811e051179467879b92babc
|
4
|
+
data.tar.gz: 14dfc0634c8eacfb96344447eb05bc63dfaafe3d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f9e6fcb733742f7201eca5aff89b7e19de23e040ff3809a77aff1459483226f59b2bab528e70b862149656512677e018025f367be6233c23dfb2e8769b6f9ed5
|
7
|
+
data.tar.gz: b39e788481896ab1b612425a7922dd249defb2c7b6c30091c15b9deeca895ecfc421372d2023c11bfde097ec4297166b9e5917949774a83697ddba7c8d0ea40c
|
data/lib/trackler/version.rb
CHANGED
data/tracks/ceylon/.travis.yml
CHANGED
data/tracks/ceylon/config.json
CHANGED
@@ -0,0 +1,96 @@
|
|
1
|
+
import ceylon.collection { HashMap, MutableMap }
|
2
|
+
|
3
|
+
class Reactor<Element>() given Element satisfies Object {
|
4
|
+
shared abstract class Cell() {
|
5
|
+
shared formal Element currentValue;
|
6
|
+
variable ComputeCell.Inner[] dependents = [];
|
7
|
+
shared default void addDependent(ComputeCell.Inner c) {
|
8
|
+
dependents = dependents.withTrailing(c);
|
9
|
+
}
|
10
|
+
shared void eachDependent(Anything(ComputeCell.Inner) f) {
|
11
|
+
for (dep in dependents) {
|
12
|
+
f(dep);
|
13
|
+
}
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
shared class InputCell(Element initialValue) extends Cell() {
|
18
|
+
variable Element currentValue_ = initialValue;
|
19
|
+
shared actual Element currentValue => currentValue_;
|
20
|
+
assign currentValue {
|
21
|
+
currentValue_ = currentValue;
|
22
|
+
eachDependent((d) => d.propagate());
|
23
|
+
eachDependent((d) => d.fireCallbacks());
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
shared class ComputeCell extends Cell {
|
28
|
+
shared alias Callback => Anything(Element);
|
29
|
+
|
30
|
+
shared interface Subscription {
|
31
|
+
shared formal void cancel();
|
32
|
+
}
|
33
|
+
|
34
|
+
shared class Inner(Element() newValue) extends Cell() {
|
35
|
+
variable Element currentValue_ = newValue();
|
36
|
+
shared actual Element currentValue => currentValue_;
|
37
|
+
variable Element lastCallbackValue = currentValue_;
|
38
|
+
|
39
|
+
variable Integer callbacksIssued = 0;
|
40
|
+
variable MutableMap<Integer, Callback> activeCallbacks = HashMap<Integer, Callback>();
|
41
|
+
|
42
|
+
shared Subscription addCallback(Callback f) {
|
43
|
+
value id = callbacksIssued;
|
44
|
+
callbacksIssued++;
|
45
|
+
activeCallbacks.put(id, f);
|
46
|
+
return object satisfies Subscription {
|
47
|
+
cancel() => activeCallbacks.remove(id);
|
48
|
+
};
|
49
|
+
}
|
50
|
+
|
51
|
+
shared void propagate() {
|
52
|
+
Element nv = newValue();
|
53
|
+
if (nv != currentValue) {
|
54
|
+
currentValue_ = nv;
|
55
|
+
eachDependent((d) => d.propagate());
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
shared void fireCallbacks() {
|
60
|
+
if (lastCallbackValue == currentValue) {
|
61
|
+
return;
|
62
|
+
}
|
63
|
+
lastCallbackValue = currentValue;
|
64
|
+
for (cb in activeCallbacks.items) {
|
65
|
+
cb(currentValue);
|
66
|
+
}
|
67
|
+
eachDependent((d) => d.fireCallbacks());
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
Inner inner;
|
72
|
+
|
73
|
+
shared new single(Cell c, Element(Element) f) extends Cell() {
|
74
|
+
// Since `c.addDependent(this)` is illegal, we have to create an inner cell.
|
75
|
+
inner = Inner(() => f(c.currentValue));
|
76
|
+
c.addDependent(inner);
|
77
|
+
}
|
78
|
+
|
79
|
+
shared new double(Cell c1, Cell c2, Element(Element, Element) f) extends Cell() {
|
80
|
+
// Since `c.addDependent(this)` is illegal, we have to create an inner cell.
|
81
|
+
inner = Inner(() => f(c1.currentValue, c2.currentValue));
|
82
|
+
c1.addDependent(inner);
|
83
|
+
c2.addDependent(inner);
|
84
|
+
}
|
85
|
+
|
86
|
+
shared actual Element currentValue => inner.currentValue;
|
87
|
+
|
88
|
+
shared Subscription addCallback(Callback f) {
|
89
|
+
return inner.addCallback(f);
|
90
|
+
}
|
91
|
+
|
92
|
+
shared actual void addDependent(ComputeCell.Inner c) {
|
93
|
+
inner.addDependent(c);
|
94
|
+
}
|
95
|
+
}
|
96
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class Reactor<Element>() given Element satisfies Object {
|
2
|
+
shared abstract class Cell() {
|
3
|
+
shared formal Element currentValue;
|
4
|
+
}
|
5
|
+
|
6
|
+
shared class InputCell(Element initialValue) extends Cell() {
|
7
|
+
shared actual variable Element currentValue = nothing;
|
8
|
+
}
|
9
|
+
|
10
|
+
shared class ComputeCell extends Cell {
|
11
|
+
shared new single(Cell c, Element(Element) f) extends Cell() {
|
12
|
+
}
|
13
|
+
|
14
|
+
shared new double(Cell c1, Cell c2, Element(Element, Element) f) extends Cell() {
|
15
|
+
}
|
16
|
+
|
17
|
+
shared alias Callback => Anything(Element);
|
18
|
+
|
19
|
+
shared actual Element currentValue = nothing;
|
20
|
+
|
21
|
+
shared interface Subscription {
|
22
|
+
shared formal void cancel();
|
23
|
+
}
|
24
|
+
|
25
|
+
shared Subscription addCallback(Callback f) {
|
26
|
+
return nothing;
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
@@ -0,0 +1,195 @@
|
|
1
|
+
import ceylon.test { ... }
|
2
|
+
|
3
|
+
test
|
4
|
+
void inputCellsHaveValue() {
|
5
|
+
value r = Reactor<Integer>();
|
6
|
+
value input = r.InputCell(10);
|
7
|
+
assertEquals(input.currentValue, 10);
|
8
|
+
}
|
9
|
+
|
10
|
+
test
|
11
|
+
void inputCellsCanHaveValuesSet() {
|
12
|
+
value r = Reactor<Integer>();
|
13
|
+
value input = r.InputCell(4);
|
14
|
+
input.currentValue = 20;
|
15
|
+
assertEquals(input.currentValue, 20);
|
16
|
+
}
|
17
|
+
|
18
|
+
test
|
19
|
+
void computeCellsCalculateInitialValue() {
|
20
|
+
value r = Reactor<Integer>();
|
21
|
+
value input = r.InputCell(1);
|
22
|
+
value output = r.ComputeCell.single(input, (Integer x) => x + 1);
|
23
|
+
assertEquals(output.currentValue, 2);
|
24
|
+
}
|
25
|
+
|
26
|
+
test
|
27
|
+
void computeCellsTakeInputInRightOrder() {
|
28
|
+
value r = Reactor<Integer>();
|
29
|
+
value one = r.InputCell(1);
|
30
|
+
value two = r.InputCell(2);
|
31
|
+
value output = r.ComputeCell.double(one, two, (Integer x, Integer y) => x + y * 10);
|
32
|
+
assertEquals(output.currentValue, 21);
|
33
|
+
}
|
34
|
+
|
35
|
+
test
|
36
|
+
void computeCellsUpdateValueWhenDependenciesChange() {
|
37
|
+
value r = Reactor<Integer>();
|
38
|
+
value input = r.InputCell(1);
|
39
|
+
value output = r.ComputeCell.single(input, (Integer x) => x + 1);
|
40
|
+
input.currentValue = 3;
|
41
|
+
assertEquals(output.currentValue, 4);
|
42
|
+
}
|
43
|
+
|
44
|
+
test
|
45
|
+
void computeCellsCanDependOnOtherComputeCells() {
|
46
|
+
value r = Reactor<Integer>();
|
47
|
+
value input = r.InputCell(1);
|
48
|
+
value timesTwo = r.ComputeCell.single(input, (Integer x) => x * 2);
|
49
|
+
value timesThirty = r.ComputeCell.single(input, (Integer x) => x * 30);
|
50
|
+
value output = r.ComputeCell.double(timesTwo, timesThirty, (Integer x, Integer y) => x + y);
|
51
|
+
|
52
|
+
assertEquals(output.currentValue, 32);
|
53
|
+
input.currentValue = 3;
|
54
|
+
assertEquals(output.currentValue, 96);
|
55
|
+
}
|
56
|
+
|
57
|
+
test
|
58
|
+
void computeCellsFireCallbacks() {
|
59
|
+
value r = Reactor<Integer>();
|
60
|
+
value input = r.InputCell(1);
|
61
|
+
value output = r.ComputeCell.single(input, (Integer x) => x + 1);
|
62
|
+
|
63
|
+
variable Integer[] vals = [];
|
64
|
+
output.addCallback((x) => vals = vals.withTrailing(x));
|
65
|
+
|
66
|
+
input.currentValue = 3;
|
67
|
+
assertEquals(vals, [4]);
|
68
|
+
}
|
69
|
+
|
70
|
+
test
|
71
|
+
void callbacksOnlyFireOnChange() {
|
72
|
+
value r = Reactor<Integer>();
|
73
|
+
value input = r.InputCell(1);
|
74
|
+
value output = r.ComputeCell.single(input, (Integer x) => if (x < 3) then 111 else 222);
|
75
|
+
|
76
|
+
variable Integer[] vals = [];
|
77
|
+
output.addCallback((x) => vals = vals.withTrailing(x));
|
78
|
+
|
79
|
+
input.currentValue = 2;
|
80
|
+
assertEquals(vals, []);
|
81
|
+
|
82
|
+
input.currentValue = 4;
|
83
|
+
assertEquals(vals, [222]);
|
84
|
+
}
|
85
|
+
|
86
|
+
test
|
87
|
+
void callbacksCanBeAddedAndRemoved() {
|
88
|
+
value r = Reactor<Integer>();
|
89
|
+
value input = r.InputCell(11);
|
90
|
+
value output = r.ComputeCell.single(input, (Integer x) => x + 1);
|
91
|
+
|
92
|
+
variable Integer[] vals1 = [];
|
93
|
+
value sub1 = output.addCallback((x) => vals1 = vals1.withTrailing(x));
|
94
|
+
variable Integer[] vals2 = [];
|
95
|
+
output.addCallback((x) => vals2 = vals2.withTrailing(x));
|
96
|
+
|
97
|
+
input.currentValue = 31;
|
98
|
+
|
99
|
+
sub1.cancel();
|
100
|
+
variable Integer[] vals3 = [];
|
101
|
+
output.addCallback((x) => vals3 = vals3.withTrailing(x));
|
102
|
+
|
103
|
+
input.currentValue = 41;
|
104
|
+
|
105
|
+
assertEquals(vals1, [32]);
|
106
|
+
assertEquals(vals2, [32, 42]);
|
107
|
+
assertEquals(vals3, [42]);
|
108
|
+
}
|
109
|
+
|
110
|
+
test
|
111
|
+
void removingCallbackMultipleTimesDoesntInterfereWithOtherCallbacks() {
|
112
|
+
value r = Reactor<Integer>();
|
113
|
+
value input = r.InputCell(1);
|
114
|
+
value output = r.ComputeCell.single(input, (Integer x) => x + 1);
|
115
|
+
|
116
|
+
variable Integer[] vals1 = [];
|
117
|
+
value sub1 = output.addCallback((x) => vals1 = vals1.withTrailing(x));
|
118
|
+
variable Integer[] vals2 = [];
|
119
|
+
output.addCallback((x) => vals2 = vals2.withTrailing(x));
|
120
|
+
|
121
|
+
for (i in 1..10) {
|
122
|
+
sub1.cancel();
|
123
|
+
}
|
124
|
+
|
125
|
+
input.currentValue = 2;
|
126
|
+
assertEquals(vals1, []);
|
127
|
+
assertEquals(vals2, [3]);
|
128
|
+
}
|
129
|
+
|
130
|
+
test
|
131
|
+
void callbacksAreOnlyCalledOnceEvenIfMultipleDependenciesChange() {
|
132
|
+
value r = Reactor<Integer>();
|
133
|
+
value input = r.InputCell(1);
|
134
|
+
value plusOne = r.ComputeCell.single(input, (Integer x) => x + 1);
|
135
|
+
value minusOne1 = r.ComputeCell.single(input, (Integer x) => x - 1);
|
136
|
+
value minusOne2 = r.ComputeCell.single(minusOne1, (Integer x) => x - 1);
|
137
|
+
value output = r.ComputeCell.double(plusOne, minusOne2, (Integer x, Integer y) => x * y);
|
138
|
+
|
139
|
+
variable Integer[] vals = [];
|
140
|
+
output.addCallback((x) => vals = vals.withTrailing(x));
|
141
|
+
|
142
|
+
input.currentValue = 4;
|
143
|
+
assertEquals(vals, [10]);
|
144
|
+
}
|
145
|
+
|
146
|
+
test
|
147
|
+
void callbacksAreNotCalledIfDependenciesChangeButOutputValueDoesntChange() {
|
148
|
+
value r = Reactor<Integer>();
|
149
|
+
value input = r.InputCell(1);
|
150
|
+
value plusOne = r.ComputeCell.single(input, (Integer x) => x + 1);
|
151
|
+
value minusOne = r.ComputeCell.single(input, (Integer x) => x - 1);
|
152
|
+
value alwaysTwo = r.ComputeCell.double(plusOne, minusOne, (Integer x, Integer y) => x - y);
|
153
|
+
|
154
|
+
variable Integer[] vals = [];
|
155
|
+
alwaysTwo.addCallback((x) => vals = vals.withTrailing(x));
|
156
|
+
|
157
|
+
for (i in 1..10) {
|
158
|
+
input.currentValue = i;
|
159
|
+
}
|
160
|
+
assertEquals(vals, []);
|
161
|
+
}
|
162
|
+
|
163
|
+
{[Boolean, Boolean, Boolean, Boolean, Boolean]*} adderCases => {
|
164
|
+
[false, false, false, false, false],
|
165
|
+
[false, false, true, false, true],
|
166
|
+
[false, true, false, false, true],
|
167
|
+
[false, true, true, true, false],
|
168
|
+
[true, false, false, false, true],
|
169
|
+
[true, false, true, true, false],
|
170
|
+
[true, true, false, true, false],
|
171
|
+
[true, true, true, true, true]
|
172
|
+
};
|
173
|
+
|
174
|
+
test
|
175
|
+
parameters(`value adderCases`)
|
176
|
+
// This is a digital logic circuit called an adder:
|
177
|
+
// https://en.wikipedia.org/wiki/Adder_(electronics)
|
178
|
+
void testAdder(Boolean aval, Boolean bval, Boolean cinval, Boolean expectCout, Boolean expectSum) {
|
179
|
+
value r = Reactor<Boolean>();
|
180
|
+
value a = r.InputCell(aval);
|
181
|
+
value b = r.InputCell(bval);
|
182
|
+
value carryIn = r.InputCell(cinval);
|
183
|
+
|
184
|
+
value aXorB = r.ComputeCell.double(a, b, (Boolean a, Boolean b) => a != b);
|
185
|
+
value sum = r.ComputeCell.double(aXorB, carryIn, (Boolean axorb, Boolean cin) => axorb != cin);
|
186
|
+
|
187
|
+
value aXorBAndCin = r.ComputeCell.double(aXorB, carryIn, (Boolean axorb, Boolean cin) => axorb && cin);
|
188
|
+
value aAndB = r.ComputeCell.double(a, b, (Boolean a, Boolean b) => a && b);
|
189
|
+
value carryOut = r.ComputeCell.double(aXorBAndCin, aAndB, (Boolean a, Boolean b) => a || b);
|
190
|
+
|
191
|
+
// Test them both at once so if they fail we get to see both values.
|
192
|
+
[Boolean, Boolean] expected = [expectSum, expectCout];
|
193
|
+
[Boolean, Boolean] observed = [sum.currentValue, carryOut.currentValue];
|
194
|
+
assertEquals(expected, observed);
|
195
|
+
}
|
data/tracks/csharp/config.json
CHANGED
@@ -17,9 +17,9 @@ public class Graph<T> : IEquatable<Graph<T>>
|
|
17
17
|
Value.Equals(other.Value) && Children.SequenceEqual(other.Children);
|
18
18
|
}
|
19
19
|
|
20
|
-
public class
|
20
|
+
public class GraphCrumb<T>
|
21
21
|
{
|
22
|
-
public
|
22
|
+
public GraphCrumb(T value, IEnumerable<Graph<T>> left, IEnumerable<Graph<T>> right)
|
23
23
|
{
|
24
24
|
Value = value;
|
25
25
|
Left = left;
|
@@ -31,16 +31,16 @@ public class Crumb<T>
|
|
31
31
|
public IEnumerable<Graph<T>> Right { get; }
|
32
32
|
}
|
33
33
|
|
34
|
-
public class
|
34
|
+
public class GraphZipper<T>
|
35
35
|
{
|
36
|
-
public
|
36
|
+
public GraphZipper(Graph<T> focus, IEnumerable<GraphCrumb<T>> crumbs)
|
37
37
|
{
|
38
38
|
Focus = focus;
|
39
39
|
Crumbs = crumbs;
|
40
40
|
}
|
41
41
|
|
42
42
|
public Graph<T> Focus { get; }
|
43
|
-
public IEnumerable<
|
43
|
+
public IEnumerable<GraphCrumb<T>> Crumbs { get; }
|
44
44
|
}
|
45
45
|
|
46
46
|
public static class Pov
|
@@ -54,15 +54,15 @@ public static class Pov
|
|
54
54
|
public static IEnumerable<T> TracePathBetween<T>(T value1, T value2, Graph<T> graph) where T : IComparable
|
55
55
|
=> ZipperToPath(FindNode(value2, GraphToZipper(FromPOV(value1, graph))));
|
56
56
|
|
57
|
-
private static
|
57
|
+
private static GraphZipper<T> GraphToZipper<T>(Graph<T> graph)
|
58
58
|
{
|
59
59
|
if (graph == null)
|
60
60
|
return null;
|
61
61
|
|
62
|
-
return new
|
62
|
+
return new GraphZipper<T>(graph, Enumerable.Empty<GraphCrumb<T>>());
|
63
63
|
}
|
64
64
|
|
65
|
-
private static IEnumerable<T> ZipperToPath<T>(
|
65
|
+
private static IEnumerable<T> ZipperToPath<T>(GraphZipper<T> zipper)
|
66
66
|
{
|
67
67
|
if (zipper == null)
|
68
68
|
return null;
|
@@ -70,7 +70,7 @@ public static class Pov
|
|
70
70
|
return zipper.Crumbs.Select(c => c.Value).Reverse().Concat(new[] { zipper.Focus.Value });
|
71
71
|
}
|
72
72
|
|
73
|
-
private static
|
73
|
+
private static GraphZipper<T> GoDown<T>(GraphZipper<T> zipper)
|
74
74
|
{
|
75
75
|
if (zipper == null || !zipper.Focus.Children.Any())
|
76
76
|
return null;
|
@@ -78,12 +78,12 @@ public static class Pov
|
|
78
78
|
var focus = zipper.Focus;
|
79
79
|
var children = focus.Children;
|
80
80
|
|
81
|
-
var newCrumb = new
|
81
|
+
var newCrumb = new GraphCrumb<T>(focus.Value, Enumerable.Empty<Graph<T>>(), children.Skip(1));
|
82
82
|
|
83
|
-
return new
|
83
|
+
return new GraphZipper<T>(children.First(), new[] { newCrumb }.Concat(zipper.Crumbs));
|
84
84
|
}
|
85
85
|
|
86
|
-
private static
|
86
|
+
private static GraphZipper<T> GoRight<T>(GraphZipper<T> zipper)
|
87
87
|
{
|
88
88
|
if (zipper == null || !zipper.Crumbs.Any() || !zipper.Crumbs.First().Right.Any())
|
89
89
|
return null;
|
@@ -91,12 +91,12 @@ public static class Pov
|
|
91
91
|
var crumbs = zipper.Crumbs;
|
92
92
|
var firstCrumb = crumbs.First();
|
93
93
|
|
94
|
-
var newCrumb = new
|
94
|
+
var newCrumb = new GraphCrumb<T>(firstCrumb.Value, firstCrumb.Left.Concat(new[] { zipper.Focus }), firstCrumb.Right.Skip(1));
|
95
95
|
|
96
|
-
return new
|
96
|
+
return new GraphZipper<T>(firstCrumb.Right.First(), new[] { newCrumb }.Concat(crumbs.Skip(1)));
|
97
97
|
}
|
98
98
|
|
99
|
-
private static
|
99
|
+
private static GraphZipper<T> FindNode<T>(T value, GraphZipper<T> zipper)
|
100
100
|
where T : IComparable
|
101
101
|
{
|
102
102
|
if (zipper == null || zipper.Focus.Value.CompareTo(value) == 0)
|
@@ -105,7 +105,7 @@ public static class Pov
|
|
105
105
|
return FindNode(value, GoDown(zipper)) ?? FindNode(value, GoRight(zipper));
|
106
106
|
}
|
107
107
|
|
108
|
-
private static Graph<T> ChangeParent<T>(
|
108
|
+
private static Graph<T> ChangeParent<T>(GraphZipper<T> zipper)
|
109
109
|
{
|
110
110
|
if (zipper == null)
|
111
111
|
return null;
|
@@ -116,7 +116,7 @@ public static class Pov
|
|
116
116
|
var firstCrumb = zipper.Crumbs.First();
|
117
117
|
var focus = zipper.Focus;
|
118
118
|
|
119
|
-
var newZipper = new
|
119
|
+
var newZipper = new GraphZipper<T>(CreateGraph(firstCrumb.Value, firstCrumb.Left.Concat(firstCrumb.Right)), zipper.Crumbs.Skip(1));
|
120
120
|
var parentGraph = ChangeParent(newZipper);
|
121
121
|
|
122
122
|
var ys = focus.Children.Concat(new[] { parentGraph });
|