trackler 2.2.1.88 → 2.2.1.89
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 +4 -4
- data/lib/trackler/version.rb +1 -1
- data/problem-specifications/exercises/bowling/canonical-data.json +95 -39
- data/problem-specifications/exercises/gigasecond/canonical-data.json +17 -7
- data/problem-specifications/exercises/pangram/canonical-data.json +32 -12
- data/problem-specifications/exercises/say/canonical-data.json +47 -17
- data/problem-specifications/exercises/sum-of-multiples/canonical-data.json +54 -28
- data/problem-specifications/exercises/triangle/canonical-data.json +52 -18
- data/problem-specifications/exercises/two-bucket/canonical-data.json +38 -26
- data/problem-specifications/exercises/two-fer/canonical-data.json +14 -8
- data/problem-specifications/exercises/word-count/canonical-data.json +35 -13
- data/problem-specifications/exercises/wordy/canonical-data.json +50 -18
- data/tracks/bash/exercises/leap/.meta/version +1 -0
- data/tracks/bash/exercises/leap/example.sh +9 -9
- data/tracks/bash/exercises/leap/leap_test.sh +17 -33
- data/tracks/ceylon/exercises/anagram/source/anagram/AnagramTest.ceylon +1 -1
- data/tracks/ceylon/exercises/bracket-push/source/bracketpush/BracketsTest.ceylon +1 -1
- data/tracks/ceylon/exercises/rna-transcription/source/rnatranscription/RNATest.ceylon +2 -1
- data/tracks/fsharp/build.cake +2 -7
- data/tracks/fsharp/exercises/acronym/AcronymTest.fs +1 -1
- data/tracks/fsharp/exercises/all-your-base/AllYourBase.fs +1 -1
- data/tracks/fsharp/exercises/all-your-base/AllYourBaseTest.fs +43 -43
- data/tracks/fsharp/exercises/all-your-base/Example.fs +5 -5
- data/tracks/fsharp/exercises/allergies/AllergiesTest.fs +1 -1
- data/tracks/fsharp/exercises/alphametics/AlphameticsTest.fs +19 -1
- data/tracks/fsharp/exercises/alphametics/Example.fs +53 -34
- data/tracks/fsharp/exercises/anagram/AnagramTest.fs +1 -1
- data/tracks/fsharp/exercises/atbash-cipher/AtbashCipherTest.fs +1 -1
- data/tracks/fsharp/exercises/beer-song/BeerSongTest.fs +1 -1
- data/tracks/fsharp/exercises/binary-search/BinarySearchTest.fs +1 -1
- data/tracks/fsharp/exercises/bob/BobTest.fs +1 -1
- data/tracks/fsharp/exercises/book-store/BookStoreTest.fs +1 -1
- data/tracks/fsharp/exercises/bracket-push/BracketPushTest.fs +1 -1
- data/tracks/fsharp/exercises/change/ChangeTest.fs +1 -1
- data/tracks/fsharp/exercises/collatz-conjecture/CollatzConjectureTest.fs +1 -1
- data/tracks/fsharp/exercises/connect/ConnectTest.fs +1 -1
- data/tracks/fsharp/exercises/crypto-square/CryptoSquareTest.fs +1 -1
- data/tracks/fsharp/exercises/difference-of-squares/DifferenceOfSquaresTest.fs +1 -1
- data/tracks/fsharp/exercises/dominoes/DominoesTest.fs +25 -25
- data/tracks/fsharp/exercises/etl/EtlTest.fs +8 -8
- data/tracks/fsharp/exercises/isbn-verifier/IsbnVerifierTest.fs +5 -1
- data/tracks/fsharp/exercises/luhn/LuhnTest.fs +1 -1
- data/tracks/fsharp/exercises/meetup/Example.fs +11 -11
- data/tracks/fsharp/exercises/meetup/Meetup.fs +2 -2
- data/tracks/fsharp/exercises/meetup/MeetupTest.fs +96 -96
- data/tracks/fsharp/exercises/robot-simulator/Example.fs +21 -21
- data/tracks/fsharp/exercises/robot-simulator/RobotSimulator.fs +5 -5
- data/tracks/fsharp/exercises/robot-simulator/RobotSimulatorTest.fs +78 -96
- data/tracks/fsharp/generators/CanonicalData.fs +50 -4
- data/tracks/fsharp/generators/Common.fs +4 -13
- data/tracks/fsharp/generators/Exercise.fs +31 -15
- data/tracks/fsharp/generators/Generators.fs +76 -111
- data/tracks/haskell/exercises/alphametics/package.yaml +1 -1
- data/tracks/haskell/exercises/alphametics/test/Tests.hs +5 -0
- data/tracks/haskell/exercises/bowling/package.yaml +1 -1
- data/tracks/haskell/exercises/pangram/package.yaml +1 -1
- data/tracks/haskell/exercises/say/package.yaml +1 -1
- data/tracks/haskell/exercises/sum-of-multiples/package.yaml +1 -1
- data/tracks/haskell/exercises/word-count/package.yaml +1 -1
- data/tracks/haskell/exercises/wordy/package.yaml +1 -1
- data/tracks/java/exercises/nucleotide-count/.meta/hints.md +58 -0
- data/tracks/java/exercises/nucleotide-count/README.md +62 -0
- metadata +4 -2
data/tracks/fsharp/build.cake
CHANGED
|
@@ -68,13 +68,8 @@ Task("ReplaceStubWithExample")
|
|
|
68
68
|
Task("AddPackagesUsedInExampleImplementations")
|
|
69
69
|
.IsDependentOn("ReplaceStubWithExample")
|
|
70
70
|
.Does(() => {
|
|
71
|
-
var
|
|
72
|
-
|
|
73
|
-
+ GetFiles(buildDir + "/*/SgfParsing.fsproj");
|
|
74
|
-
|
|
75
|
-
foreach (var fparsecProject in fparsecProjects) {
|
|
76
|
-
DotNetCoreTool(fparsecProject, "add", "package FParsec");
|
|
77
|
-
}
|
|
71
|
+
var projects = GetFiles(buildDir + "/*/SgfParsing.fsproj");
|
|
72
|
+
Parallel.ForEach(projects, parallelOptions, (project) => DotNetCoreTool(project.FullPath, "add", "package FParsec"));
|
|
78
73
|
});
|
|
79
74
|
|
|
80
75
|
Task("TestUsingExampleImplementation")
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// This file was auto-generated based on version 2.0
|
|
1
|
+
// This file was auto-generated based on version 2.1.0 of the canonical data.
|
|
2
2
|
|
|
3
3
|
module AllYourBaseTest
|
|
4
4
|
|
|
@@ -9,169 +9,169 @@ open AllYourBase
|
|
|
9
9
|
|
|
10
10
|
[<Fact>]
|
|
11
11
|
let ``Single bit one to decimal`` () =
|
|
12
|
+
let digits = [1]
|
|
12
13
|
let inputBase = 2
|
|
13
|
-
let inputDigits = [1]
|
|
14
14
|
let outputBase = 10
|
|
15
15
|
let expected = Some [1]
|
|
16
|
-
rebase inputBase
|
|
16
|
+
rebase digits inputBase outputBase |> should equal expected
|
|
17
17
|
|
|
18
18
|
[<Fact(Skip = "Remove to run test")>]
|
|
19
19
|
let ``Binary to single decimal`` () =
|
|
20
|
+
let digits = [1; 0; 1]
|
|
20
21
|
let inputBase = 2
|
|
21
|
-
let inputDigits = [1; 0; 1]
|
|
22
22
|
let outputBase = 10
|
|
23
23
|
let expected = Some [5]
|
|
24
|
-
rebase inputBase
|
|
24
|
+
rebase digits inputBase outputBase |> should equal expected
|
|
25
25
|
|
|
26
26
|
[<Fact(Skip = "Remove to run test")>]
|
|
27
27
|
let ``Single decimal to binary`` () =
|
|
28
|
+
let digits = [5]
|
|
28
29
|
let inputBase = 10
|
|
29
|
-
let inputDigits = [5]
|
|
30
30
|
let outputBase = 2
|
|
31
31
|
let expected = Some [1; 0; 1]
|
|
32
|
-
rebase inputBase
|
|
32
|
+
rebase digits inputBase outputBase |> should equal expected
|
|
33
33
|
|
|
34
34
|
[<Fact(Skip = "Remove to run test")>]
|
|
35
35
|
let ``Binary to multiple decimal`` () =
|
|
36
|
+
let digits = [1; 0; 1; 0; 1; 0]
|
|
36
37
|
let inputBase = 2
|
|
37
|
-
let inputDigits = [1; 0; 1; 0; 1; 0]
|
|
38
38
|
let outputBase = 10
|
|
39
39
|
let expected = Some [4; 2]
|
|
40
|
-
rebase inputBase
|
|
40
|
+
rebase digits inputBase outputBase |> should equal expected
|
|
41
41
|
|
|
42
42
|
[<Fact(Skip = "Remove to run test")>]
|
|
43
43
|
let ``Decimal to binary`` () =
|
|
44
|
+
let digits = [4; 2]
|
|
44
45
|
let inputBase = 10
|
|
45
|
-
let inputDigits = [4; 2]
|
|
46
46
|
let outputBase = 2
|
|
47
47
|
let expected = Some [1; 0; 1; 0; 1; 0]
|
|
48
|
-
rebase inputBase
|
|
48
|
+
rebase digits inputBase outputBase |> should equal expected
|
|
49
49
|
|
|
50
50
|
[<Fact(Skip = "Remove to run test")>]
|
|
51
51
|
let ``Trinary to hexadecimal`` () =
|
|
52
|
+
let digits = [1; 1; 2; 0]
|
|
52
53
|
let inputBase = 3
|
|
53
|
-
let inputDigits = [1; 1; 2; 0]
|
|
54
54
|
let outputBase = 16
|
|
55
55
|
let expected = Some [2; 10]
|
|
56
|
-
rebase inputBase
|
|
56
|
+
rebase digits inputBase outputBase |> should equal expected
|
|
57
57
|
|
|
58
58
|
[<Fact(Skip = "Remove to run test")>]
|
|
59
59
|
let ``Hexadecimal to trinary`` () =
|
|
60
|
+
let digits = [2; 10]
|
|
60
61
|
let inputBase = 16
|
|
61
|
-
let inputDigits = [2; 10]
|
|
62
62
|
let outputBase = 3
|
|
63
63
|
let expected = Some [1; 1; 2; 0]
|
|
64
|
-
rebase inputBase
|
|
64
|
+
rebase digits inputBase outputBase |> should equal expected
|
|
65
65
|
|
|
66
66
|
[<Fact(Skip = "Remove to run test")>]
|
|
67
67
|
let ``15-bit integer`` () =
|
|
68
|
+
let digits = [3; 46; 60]
|
|
68
69
|
let inputBase = 97
|
|
69
|
-
let inputDigits = [3; 46; 60]
|
|
70
70
|
let outputBase = 73
|
|
71
71
|
let expected = Some [6; 10; 45]
|
|
72
|
-
rebase inputBase
|
|
72
|
+
rebase digits inputBase outputBase |> should equal expected
|
|
73
73
|
|
|
74
74
|
[<Fact(Skip = "Remove to run test")>]
|
|
75
75
|
let ``Empty list`` () =
|
|
76
|
+
let digits = []
|
|
76
77
|
let inputBase = 2
|
|
77
|
-
let inputDigits = []
|
|
78
78
|
let outputBase = 10
|
|
79
79
|
let expected = Some [0]
|
|
80
|
-
rebase inputBase
|
|
80
|
+
rebase digits inputBase outputBase |> should equal expected
|
|
81
81
|
|
|
82
82
|
[<Fact(Skip = "Remove to run test")>]
|
|
83
83
|
let ``Single zero`` () =
|
|
84
|
+
let digits = [0]
|
|
84
85
|
let inputBase = 10
|
|
85
|
-
let inputDigits = [0]
|
|
86
86
|
let outputBase = 2
|
|
87
87
|
let expected = Some [0]
|
|
88
|
-
rebase inputBase
|
|
88
|
+
rebase digits inputBase outputBase |> should equal expected
|
|
89
89
|
|
|
90
90
|
[<Fact(Skip = "Remove to run test")>]
|
|
91
91
|
let ``Multiple zeros`` () =
|
|
92
|
+
let digits = [0; 0; 0]
|
|
92
93
|
let inputBase = 10
|
|
93
|
-
let inputDigits = [0; 0; 0]
|
|
94
94
|
let outputBase = 2
|
|
95
95
|
let expected = Some [0]
|
|
96
|
-
rebase inputBase
|
|
96
|
+
rebase digits inputBase outputBase |> should equal expected
|
|
97
97
|
|
|
98
98
|
[<Fact(Skip = "Remove to run test")>]
|
|
99
99
|
let ``Leading zeros`` () =
|
|
100
|
+
let digits = [0; 6; 0]
|
|
100
101
|
let inputBase = 7
|
|
101
|
-
let inputDigits = [0; 6; 0]
|
|
102
102
|
let outputBase = 10
|
|
103
103
|
let expected = Some [4; 2]
|
|
104
|
-
rebase inputBase
|
|
104
|
+
rebase digits inputBase outputBase |> should equal expected
|
|
105
105
|
|
|
106
106
|
[<Fact(Skip = "Remove to run test")>]
|
|
107
107
|
let ``Input base is one`` () =
|
|
108
|
+
let digits = []
|
|
108
109
|
let inputBase = 1
|
|
109
|
-
let inputDigits = []
|
|
110
110
|
let outputBase = 10
|
|
111
111
|
let expected = None
|
|
112
|
-
rebase inputBase
|
|
112
|
+
rebase digits inputBase outputBase |> should equal expected
|
|
113
113
|
|
|
114
114
|
[<Fact(Skip = "Remove to run test")>]
|
|
115
115
|
let ``Input base is zero`` () =
|
|
116
|
+
let digits = []
|
|
116
117
|
let inputBase = 0
|
|
117
|
-
let inputDigits = []
|
|
118
118
|
let outputBase = 10
|
|
119
119
|
let expected = None
|
|
120
|
-
rebase inputBase
|
|
120
|
+
rebase digits inputBase outputBase |> should equal expected
|
|
121
121
|
|
|
122
122
|
[<Fact(Skip = "Remove to run test")>]
|
|
123
123
|
let ``Input base is negative`` () =
|
|
124
|
+
let digits = [1]
|
|
124
125
|
let inputBase = -2
|
|
125
|
-
let inputDigits = [1]
|
|
126
126
|
let outputBase = 10
|
|
127
127
|
let expected = None
|
|
128
|
-
rebase inputBase
|
|
128
|
+
rebase digits inputBase outputBase |> should equal expected
|
|
129
129
|
|
|
130
130
|
[<Fact(Skip = "Remove to run test")>]
|
|
131
131
|
let ``Negative digit`` () =
|
|
132
|
+
let digits = [1; -1; 1; 0; 1; 0]
|
|
132
133
|
let inputBase = 2
|
|
133
|
-
let inputDigits = [1; -1; 1; 0; 1; 0]
|
|
134
134
|
let outputBase = 10
|
|
135
135
|
let expected = None
|
|
136
|
-
rebase inputBase
|
|
136
|
+
rebase digits inputBase outputBase |> should equal expected
|
|
137
137
|
|
|
138
138
|
[<Fact(Skip = "Remove to run test")>]
|
|
139
139
|
let ``Invalid positive digit`` () =
|
|
140
|
+
let digits = [1; 2; 1; 0; 1; 0]
|
|
140
141
|
let inputBase = 2
|
|
141
|
-
let inputDigits = [1; 2; 1; 0; 1; 0]
|
|
142
142
|
let outputBase = 10
|
|
143
143
|
let expected = None
|
|
144
|
-
rebase inputBase
|
|
144
|
+
rebase digits inputBase outputBase |> should equal expected
|
|
145
145
|
|
|
146
146
|
[<Fact(Skip = "Remove to run test")>]
|
|
147
147
|
let ``Output base is one`` () =
|
|
148
|
+
let digits = [1; 0; 1; 0; 1; 0]
|
|
148
149
|
let inputBase = 2
|
|
149
|
-
let inputDigits = [1; 0; 1; 0; 1; 0]
|
|
150
150
|
let outputBase = 1
|
|
151
151
|
let expected = None
|
|
152
|
-
rebase inputBase
|
|
152
|
+
rebase digits inputBase outputBase |> should equal expected
|
|
153
153
|
|
|
154
154
|
[<Fact(Skip = "Remove to run test")>]
|
|
155
155
|
let ``Output base is zero`` () =
|
|
156
|
+
let digits = [7]
|
|
156
157
|
let inputBase = 10
|
|
157
|
-
let inputDigits = [7]
|
|
158
158
|
let outputBase = 0
|
|
159
159
|
let expected = None
|
|
160
|
-
rebase inputBase
|
|
160
|
+
rebase digits inputBase outputBase |> should equal expected
|
|
161
161
|
|
|
162
162
|
[<Fact(Skip = "Remove to run test")>]
|
|
163
163
|
let ``Output base is negative`` () =
|
|
164
|
+
let digits = [1]
|
|
164
165
|
let inputBase = 2
|
|
165
|
-
let inputDigits = [1]
|
|
166
166
|
let outputBase = -7
|
|
167
167
|
let expected = None
|
|
168
|
-
rebase inputBase
|
|
168
|
+
rebase digits inputBase outputBase |> should equal expected
|
|
169
169
|
|
|
170
170
|
[<Fact(Skip = "Remove to run test")>]
|
|
171
171
|
let ``Both bases are negative`` () =
|
|
172
|
+
let digits = [1]
|
|
172
173
|
let inputBase = -2
|
|
173
|
-
let inputDigits = [1]
|
|
174
174
|
let outputBase = -7
|
|
175
175
|
let expected = None
|
|
176
|
-
rebase inputBase
|
|
176
|
+
rebase digits inputBase outputBase |> should equal expected
|
|
177
177
|
|
|
@@ -19,12 +19,12 @@ let fromBase b nums =
|
|
|
19
19
|
|
|
20
20
|
loop 0 nums
|
|
21
21
|
|
|
22
|
-
let rebase
|
|
23
|
-
match
|
|
22
|
+
let rebase digits inputBase outputBase =
|
|
23
|
+
match inputBase < 2 || outputBase < 2 with
|
|
24
24
|
| true ->
|
|
25
25
|
None
|
|
26
26
|
| false ->
|
|
27
|
-
|
|
27
|
+
digits
|
|
28
28
|
|> List.skipWhile ((=) 0)
|
|
29
|
-
|> fromBase
|
|
30
|
-
|> Option.bind (toBase
|
|
29
|
+
|> fromBase inputBase
|
|
30
|
+
|> Option.bind (toBase outputBase)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// This file was auto-generated based on version 1.
|
|
1
|
+
// This file was auto-generated based on version 1.2.0 of the canonical data.
|
|
2
2
|
|
|
3
3
|
module AlphameticsTest
|
|
4
4
|
|
|
@@ -105,3 +105,21 @@ let ``Puzzle with ten letters`` () =
|
|
|
105
105
|
|> Some
|
|
106
106
|
solve puzzle |> should equal expected
|
|
107
107
|
|
|
108
|
+
[<Fact(Skip = "Remove to run test")>]
|
|
109
|
+
let ``Puzzle with ten letters and 199 addends`` () =
|
|
110
|
+
let puzzle = "THIS + A + FIRE + THEREFORE + FOR + ALL + HISTORIES + I + TELL + A + TALE + THAT + FALSIFIES + ITS + TITLE + TIS + A + LIE + THE + TALE + OF + THE + LAST + FIRE + HORSES + LATE + AFTER + THE + FIRST + FATHERS + FORESEE + THE + HORRORS + THE + LAST + FREE + TROLL + TERRIFIES + THE + HORSES + OF + FIRE + THE + TROLL + RESTS + AT + THE + HOLE + OF + LOSSES + IT + IS + THERE + THAT + SHE + STORES + ROLES + OF + LEATHERS + AFTER + SHE + SATISFIES + HER + HATE + OFF + THOSE + FEARS + A + TASTE + RISES + AS + SHE + HEARS + THE + LEAST + FAR + HORSE + THOSE + FAST + HORSES + THAT + FIRST + HEAR + THE + TROLL + FLEE + OFF + TO + THE + FOREST + THE + HORSES + THAT + ALERTS + RAISE + THE + STARES + OF + THE + OTHERS + AS + THE + TROLL + ASSAILS + AT + THE + TOTAL + SHIFT + HER + TEETH + TEAR + HOOF + OFF + TORSO + AS + THE + LAST + HORSE + FORFEITS + ITS + LIFE + THE + FIRST + FATHERS + HEAR + OF + THE + HORRORS + THEIR + FEARS + THAT + THE + FIRES + FOR + THEIR + FEASTS + ARREST + AS + THE + FIRST + FATHERS + RESETTLE + THE + LAST + OF + THE + FIRE + HORSES + THE + LAST + TROLL + HARASSES + THE + FOREST + HEART + FREE + AT + LAST + OF + THE + LAST + TROLL + ALL + OFFER + THEIR + FIRE + HEAT + TO + THE + ASSISTERS + FAR + OFF + THE + TROLL + FASTS + ITS + LIFE + SHORTER + AS + STARS + RISE + THE + HORSES + REST + SAFE + AFTER + ALL + SHARE + HOT + FISH + AS + THEIR + AFFILIATES + TAILOR + A + ROOFS + FOR + THEIR + SAFE == FORTRESSES"
|
|
111
|
+
let expected =
|
|
112
|
+
[ ('A', 1);
|
|
113
|
+
('E', 0);
|
|
114
|
+
('F', 5);
|
|
115
|
+
('H', 8);
|
|
116
|
+
('I', 7);
|
|
117
|
+
('L', 2);
|
|
118
|
+
('O', 6);
|
|
119
|
+
('R', 3);
|
|
120
|
+
('S', 4);
|
|
121
|
+
('T', 9) ]
|
|
122
|
+
|> Map.ofList
|
|
123
|
+
|> Some
|
|
124
|
+
solve puzzle |> should equal expected
|
|
125
|
+
|
|
@@ -2,24 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
open System
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
let private foldMapBy mapping map1 map2 =
|
|
6
|
+
let helper acc key value =
|
|
7
|
+
match Map.tryFind key acc with
|
|
8
|
+
| Some x -> Map.add key (mapping x value) acc
|
|
9
|
+
| None -> Map.add key value acc
|
|
7
10
|
|
|
8
|
-
|
|
9
|
-
let private equal = pstring " == "
|
|
10
|
-
let private operand = many1Satisfy isAsciiUpper
|
|
11
|
-
let private expression = sepBy operand plus
|
|
12
|
-
let private equation = expression .>> equal .>>. expression
|
|
11
|
+
map1 |> Map.fold helper map2
|
|
13
12
|
|
|
14
|
-
let private
|
|
15
|
-
match run parser input with
|
|
16
|
-
| Success(result, _, _) -> Some result
|
|
17
|
-
| Failure(errorMsg, _, _) -> None
|
|
18
|
-
|
|
19
|
-
let private parseEquation = parseToOption equation
|
|
20
|
-
|
|
21
|
-
let private operandToInt (map: Map<char, int>) (operand: string) =
|
|
22
|
-
Seq.fold (fun acc x -> acc * 10 + Map.find x map) 0 operand
|
|
13
|
+
let private tenToPower power = Math.Pow(10., float power) |> int
|
|
23
14
|
|
|
24
15
|
let private generateCombinations length =
|
|
25
16
|
let rec helper remaining options =
|
|
@@ -28,25 +19,53 @@ let private generateCombinations length =
|
|
|
28
19
|
for xs in helper (remaining - 1) (Set.remove x options) do
|
|
29
20
|
yield x::xs }
|
|
30
21
|
|
|
31
|
-
helper length ([0..9] |> Set.ofList)
|
|
22
|
+
helper length ([0..9] |> Set.ofList)
|
|
23
|
+
|
|
24
|
+
let private solutions parts =
|
|
25
|
+
let letters = parts |> Seq.concat |> Seq.toList |> List.distinct
|
|
26
|
+
let nonZeroLetters = Array.map Seq.head parts |> Array.distinct
|
|
27
|
+
|
|
28
|
+
letters
|
|
29
|
+
|> List.length
|
|
30
|
+
|> generateCombinations
|
|
31
|
+
|> Seq.map (fun combination -> Seq.zip letters combination |> Map.ofSeq)
|
|
32
|
+
|> Seq.filter (fun solution -> Array.forall (fun letter -> Map.find letter solution <> 0) nonZeroLetters)
|
|
33
|
+
|
|
34
|
+
let private trySolve counts solution =
|
|
35
|
+
let folder sum letter count =
|
|
36
|
+
let multiplier = Map.find letter solution
|
|
37
|
+
sum + count * multiplier
|
|
38
|
+
|
|
39
|
+
match Map.fold folder 0 counts with
|
|
40
|
+
| 0 -> Some solution
|
|
41
|
+
| _ -> None
|
|
42
|
+
|
|
43
|
+
let private parseAddends (puzzle: string) =
|
|
44
|
+
puzzle
|
|
45
|
+
.Replace("==", "")
|
|
46
|
+
.Replace("+", "")
|
|
47
|
+
.Split([|" "|], StringSplitOptions.RemoveEmptyEntries)
|
|
32
48
|
|
|
33
|
-
let private
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|>
|
|
40
|
-
|> Seq.filter (fun m -> Set.forall (fun x -> Map.find x m <> 0) nonZeroChars)
|
|
49
|
+
let private addendToLetterCount multiplier word =
|
|
50
|
+
word
|
|
51
|
+
|> Seq.rev
|
|
52
|
+
|> Seq.mapi (fun i letter -> (letter, tenToPower i * multiplier))
|
|
53
|
+
|> Seq.groupBy fst
|
|
54
|
+
|> Seq.map (fun (letter, counts) -> (letter, counts |> Seq.sumBy snd))
|
|
55
|
+
|> Map.ofSeq
|
|
41
56
|
|
|
42
|
-
let private
|
|
57
|
+
let private addendsToLetterCount addends =
|
|
58
|
+
let mapAddend i addend =
|
|
59
|
+
let multiplier = if i = Array.length addends - 1 then -1 else 1
|
|
60
|
+
addendToLetterCount multiplier addend
|
|
43
61
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
left = right
|
|
62
|
+
addends
|
|
63
|
+
|> Array.mapi mapAddend
|
|
64
|
+
|> Array.reduce (foldMapBy (+))
|
|
48
65
|
|
|
49
|
-
let solve
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
66
|
+
let solve (puzzle: string) =
|
|
67
|
+
let addends = parseAddends puzzle
|
|
68
|
+
let letterCounts = addendsToLetterCount addends
|
|
69
|
+
|
|
70
|
+
solutions addends
|
|
71
|
+
|> Seq.tryPick (trySolve letterCounts)
|